Version 1.14.0-dev.0.0

Merge commit 'd9396d8a1600a0454decba7c4fe74348b46e41ab' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 52b004a..5f6d954 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,11 +1,40 @@
-## 1.13.0
+## 1.14.0
+
+### Core library changes
+* `dart:convert`
+  * `Base64Decoder.convert` now takes optional `start` and `end` parameters.
+
+* `dart:core`
+  * Added `Uri.data` getter for `data:` URIs, and `UriData` class for the
+    return type.
+  * Added `growable` parameter to `List.filled` constructor.
+
+* `dart:math`
+  * `Random` added a `secure` constructor returning a cryptographically secure
+    random generator which reads from the entropy source provided by the
+    embedder for every generated random value.
+
+* `dart:io`
+  * `Platform` added an `isiOS` getter and `Platform.operatingSystem` may now
+    return `ios`.
+
+## 1.13.0 - 2015-11-18
 
 ### Core library changes
 * `dart:async`
+  * `StreamController` added getters for `onListen`, `onPause`, and `onResume`
+    with the corresponding new `typedef void ControllerCallback()`.
+  * `StreamController` added a getter for `onCancel` with the corresponding
+    new `typedef ControllerCancelCallback()`;
   * `StreamTransformer` instances created with `fromHandlers` with no
     `handleError` callback now forward stack traces along with errors to the
     resulting streams.
 
+* `dart:convert`
+  * Added support for Base-64 encoding and decoding.
+    * Added new classes `Base64Codec`, `Base64Encoder`, and `Base64Decoder`.
+    * Added new top-level `const Base64Codec BASE64`.
+
 * `dart:core`
   * `Uri` added `removeFragment` method.
   * `String.allMatches` (implementing `Pattern.allMatches`) is now lazy,
@@ -15,7 +44,18 @@
 * `dart:developer`
   * Added `Timeline` class for interacting with Observatory's timeline feature.
   * Added `ServiceExtensionHandler`, `ServiceExtensionResponse`, and `registerExtension` which enable developers to provide their own VM service protocol extensions.
-  
+
+* `dart:html`, `dart:indexed_db`, `dart:svg`, `dart:web_audio`, `dart:web_gl`, `dart:web_sql`
+  * The return type of some APIs changed from `double` to `num`. Dartium is now
+    using
+    JS interop for most operations. JS does not distinguish between numeric
+    types, and will return a number as an int if it fits in an int. This will
+    mostly cause an error if you assign to something typed `double` in
+    checked mode. You may
+    need to insert a `toDouble()` call or accept `num`. Examples of APIs that
+    are affected include `Element.getBoundingClientRect` and
+    `TextMetrics.width`.
+
 * `dart:io`
   * **Breaking:** Secure networking has changed, replacing the NSS library
     with the BoringSSL library. `SecureSocket`, `SecureServerSocket`,
@@ -33,16 +73,23 @@
     allowed by the HTTP protocol.
     The `HttpServer` still gracefully receives fragments, but discards them
     before delivering the request.
-  * Removed server socket references. The use of server socket references
-    was deprecated back in 1.9. Use the `shared` flag when creating listening
-    sockets and `HttpServer` to distribute accepted sockets between isolates.
+  * To allow connections to be accepted on the same port across different
+    isolates, set the `shared` argument to `true` when creating server socket
+    and `HttpServer` instances.
+    * The deprecated `ServerSocketReference` and `RawServerSocketReference`
+      classes have been removed.
+    * The corresponding `reference` properties on `ServerSocket` and
+      `RawServerSocket` have been removed.
 
 * `dart:isolate`
   * `spawnUri` added an `environment` named argument.
 
 ### Tool changes
 
-* `docgen` and 'dartdocgen' no longer ship in the sdk. The `docgen` sources have
+* `dart2js` and Dartium now support improved Javascript Interoperability via the
+  [js package](https://pub.dartlang.org/packages/js).
+
+* `docgen` and `dartdocgen` no longer ship in the SDK. The `docgen` sources have
    been removed from the repository.
 
 * This is the last release to ship the VM's "legacy debug protocol".
@@ -52,6 +99,17 @@
   of a number of issues uncovered by the first few non-observatory
   clients.  This is a potentially breaking change for clients.
 
+* Dartium has been substantially changed. Rather than using C++ calls into
+  Chromium internals for DOM operations it now uses JS interop.
+  The DOM objects in `dart:html` and related libraries now wrap
+  a JavaScript object and delegate operations to it. This should be
+  mostly transparent to users. However, performance and memory characteristics
+  may be different from previous versions. There may be some changes in which
+  DOM objects are wrapped as Dart objects. For example, if you get a reference
+  to a Window object, even through JS interop, you will always see it as a
+  Dart Window, even when used cross-frame. We expect the change to using
+  JS interop will make it much simpler to update to new Chrome versions.
+
 ## 1.12.2 - 2015-10-21
 
 ### Core library changes
@@ -83,10 +141,14 @@
 ### Language changes
 
 * Null-aware operators
-    * `??`: if null operator. `expr1 ?? expr2` evaluates to `expr1` if not `null`, otherwise `expr2`.
-    * `??=`: null-aware assignment. `v ??= expr` causes `v` to be assigned `expr` only if `v` is `null`.
-    * `x?.p`: null-aware access. `x?.p` evaluates to `x.p` if `x` is not `null`, otherwise evaluates to `null`.
-    * `x?.m()`: null-aware method invocation. `x?.m()` invokes `m` only if `x` is not `null`.
+    * `??`: if null operator. `expr1 ?? expr2` evaluates to `expr1` if
+      not `null`, otherwise `expr2`.
+    * `??=`: null-aware assignment. `v ??= expr` causes `v` to be assigned
+      `expr` only if `v` is `null`.
+    * `x?.p`: null-aware access. `x?.p` evaluates to `x.p` if `x` is not
+      `null`, otherwise evaluates to `null`.
+    * `x?.m()`: null-aware method invocation. `x?.m()` invokes `m` only
+      if `x` is not `null`.
 
 ### Core library changes
 
diff --git a/DEPS b/DEPS
index 1b0567c..a98a3b5 100644
--- a/DEPS
+++ b/DEPS
@@ -32,13 +32,13 @@
       "https://chromium.googlesource.com/external/github.com/dart-lang/%s.git",
 
   "gyp_rev": "@6ee91ad8659871916f9aa840d42e1513befdf638",
-  "co19_rev": "@ead3698f33d2cd41e75b6ce5d4a1203767cedd50",
+  "co19_rev": "@3ed795ea02e022ef19c77cf1b6095b7c8f5584d0",
   "chromium_url": "http://src.chromium.org/svn",
   "chromium_git": "https://chromium.googlesource.com",
 
   # Revisions of /third_party/* dependencies.
   "7zip_rev" : "@19997",
-  "analyzer_cli_rev" : "@c7a22746baaa8ee6b3e6b0378f9ad9de6e486186",
+  "analyzer_cli_rev" : "@c93a3d2d1c7715a6c7a067ebdbc9ba716b865226",
   "args_tag": "@0.13.0",
   "async_tag": "@1.2.0",
   "barback_tag" : "@0.15.2+7",
@@ -50,7 +50,7 @@
   "collection_rev": "@1da9a07f32efa2ba0c391b289e2037391e31da0e",
   "crypto_rev" : "@2df57a1e26dd88e8d0614207d4b062c73209917d",
   "csslib_tag" : "@0.12.0",
-  "dart2js_info_rev" : "@c4ad464717e3a304fb0d44a6937c25ff2049b863",
+  "dart2js_info_rev" : "@0a221eaf16aec3879c45719de656680ccb80d8a1",
   "dartdoc_rev" : "@18f85ff0b389c417550e541055a84b04273f2b38",
   "dart_services_rev" : "@7aea2574e6f3924bf409a80afb8ad52aa2be4f97",
   "dart_style_tag": "@0.2.0",
@@ -68,7 +68,7 @@
   "intl_rev": "@32047558bd220a53c1f4d93a26d54b83533b1475",
   "jinja2_rev": "@2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_tag": "@1.1.1",
-  "linter_rev": "@99e2607faf0e9bc522f2f12a24ba50f2954dbbff",
+  "linter_rev": "@74e5478c3693a9dcf05cc99b0dc5d53f0f776375",
   "logging_rev": "@85d83e002670545e9039ad3985f0018ab640e597",
   "markdown_rev": "@4aaadf3d940bb172e1f6285af4d2b1710d309982",
   "matcher_tag": "@0.12.0",
diff --git a/create_sdk.gyp b/create_sdk.gyp
index 769f502..749cda5 100644
--- a/create_sdk.gyp
+++ b/create_sdk.gyp
@@ -20,14 +20,15 @@
         {
           'action_name': 'create_sdk_py',
           'inputs': [
-            # This is neccessary because we have all the pub test files inside
-            # the pub directory instead of in tests/pub. Xcode can only handle
-            # a certain amount of files in one list (also depending on the
-            # length of the path from where you run). This regexp excludes
-            # pub/test
+            # Xcode can only handle a certain amount of files in one list
+            # (also depending on the length of the path from where you run).
             '<!@(["python", "tools/list_files.py",'
-                '"^(?!.*pub/test).*dart$",'
+                '"dart$",'
                 '"sdk/lib"])',
+            'sdk/lib/dart2dart.platform',
+            'sdk/lib/dart_client.platform',
+            'sdk/lib/dart_server.platform',
+            'sdk/lib/dart_shared.platform',
             '<!@(["python", "tools/list_files.py", "", '
                 '"sdk/lib/_internal/js_runtime/lib/preambles"])',
             '<!@(["python", "tools/list_files.py", "", "sdk/bin"])',
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index 707246a..eb5f9a9 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -2264,6 +2264,7 @@
             </p>
           </dd></dl></dd></dl>
     
+    
       <h2 class="domain"><a name="types">Types</a></h2>
       <p>
         This section contains descriptions of the data types referenced
@@ -2327,6 +2328,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
@@ -3964,13 +3966,13 @@
         </p>
         
         
-      <h4>Feedback</h4><dl><dt class="field"><b><i>coveringExpressionOffsets ( List&lt;int&gt; )</i></b></dt><dd>
+      <h4>Feedback</h4><dl><dt class="field"><b><i>coveringExpressionOffsets ( <span style="color:#999999">optional</span> List&lt;int&gt; )</i></b></dt><dd>
             
             <p>
               The offsets of the expressions that cover the specified
               selection, from the down most to the up most.
             </p>
-          </dd><dt class="field"><b><i>coveringExpressionLengths ( List&lt;int&gt; )</i></b></dt><dd>
+          </dd><dt class="field"><b><i>coveringExpressionLengths ( <span style="color:#999999">optional</span> List&lt;int&gt; )</i></b></dt><dd>
             
             <p>
               The lengths of the expressions that cover the specified
diff --git a/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart b/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart
index db3e626..26a0080 100644
--- a/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart
+++ b/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart
@@ -7421,6 +7421,109 @@
     return JenkinsSmiHash.finish(hash);
   }
 }
+/**
+ * diagnostic.getDiagnostics params
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class DiagnosticGetDiagnosticsParams {
+  Request toRequest(String id) {
+    return new Request(id, "diagnostic.getDiagnostics", null);
+  }
+
+  @override
+  bool operator==(other) {
+    if (other is DiagnosticGetDiagnosticsParams) {
+      return true;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    return 587526202;
+  }
+}
+
+/**
+ * diagnostic.getDiagnostics result
+ *
+ * {
+ *   "contexts": List<ContextData>
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class DiagnosticGetDiagnosticsResult implements HasToJson {
+  List<ContextData> _contexts;
+
+  /**
+   * The list of analysis contexts.
+   */
+  List<ContextData> get contexts => _contexts;
+
+  /**
+   * The list of analysis contexts.
+   */
+  void set contexts(List<ContextData> value) {
+    assert(value != null);
+    this._contexts = value;
+  }
+
+  DiagnosticGetDiagnosticsResult(List<ContextData> contexts) {
+    this.contexts = contexts;
+  }
+
+  factory DiagnosticGetDiagnosticsResult.fromJson(JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      List<ContextData> contexts;
+      if (json.containsKey("contexts")) {
+        contexts = jsonDecoder.decodeList(jsonPath + ".contexts", json["contexts"], (String jsonPath, Object json) => new ContextData.fromJson(jsonDecoder, jsonPath, json));
+      } else {
+        throw jsonDecoder.missingKey(jsonPath, "contexts");
+      }
+      return new DiagnosticGetDiagnosticsResult(contexts);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, "diagnostic.getDiagnostics result", json);
+    }
+  }
+
+  factory DiagnosticGetDiagnosticsResult.fromResponse(Response response) {
+    return new DiagnosticGetDiagnosticsResult.fromJson(
+        new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), "result", response._result);
+  }
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["contexts"] = contexts.map((ContextData value) => value.toJson()).toList();
+    return result;
+  }
+
+  Response toResponse(String id) {
+    return new Response(id, result: toJson());
+  }
+
+  @override
+  String toString() => JSON.encode(toJson());
+
+  @override
+  bool operator==(other) {
+    if (other is DiagnosticGetDiagnosticsResult) {
+      return listEqual(contexts, other.contexts, (ContextData a, ContextData b) => a == b);
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, contexts.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
 
 /**
  * AddContentOverlay
@@ -9167,6 +9270,181 @@
 }
 
 /**
+ * ContextData
+ *
+ * {
+ *   "name": String
+ *   "explicitFileCount": int
+ *   "implicitFileCount": int
+ *   "workItemQueueLength": int
+ *   "cacheEntryExceptions": List<String>
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class ContextData implements HasToJson {
+  String _name;
+
+  int _explicitFileCount;
+
+  int _implicitFileCount;
+
+  int _workItemQueueLength;
+
+  List<String> _cacheEntryExceptions;
+
+  /**
+   * The name of the context.
+   */
+  String get name => _name;
+
+  /**
+   * The name of the context.
+   */
+  void set name(String value) {
+    assert(value != null);
+    this._name = value;
+  }
+
+  /**
+   * Explicitly analyzed files.
+   */
+  int get explicitFileCount => _explicitFileCount;
+
+  /**
+   * Explicitly analyzed files.
+   */
+  void set explicitFileCount(int value) {
+    assert(value != null);
+    this._explicitFileCount = value;
+  }
+
+  /**
+   * Implicitly analyzed files.
+   */
+  int get implicitFileCount => _implicitFileCount;
+
+  /**
+   * Implicitly analyzed files.
+   */
+  void set implicitFileCount(int value) {
+    assert(value != null);
+    this._implicitFileCount = value;
+  }
+
+  /**
+   * The number of work items in the queue.
+   */
+  int get workItemQueueLength => _workItemQueueLength;
+
+  /**
+   * The number of work items in the queue.
+   */
+  void set workItemQueueLength(int value) {
+    assert(value != null);
+    this._workItemQueueLength = value;
+  }
+
+  /**
+   * Exceptions associated with cache entries.
+   */
+  List<String> get cacheEntryExceptions => _cacheEntryExceptions;
+
+  /**
+   * Exceptions associated with cache entries.
+   */
+  void set cacheEntryExceptions(List<String> value) {
+    assert(value != null);
+    this._cacheEntryExceptions = value;
+  }
+
+  ContextData(String name, int explicitFileCount, int implicitFileCount, int workItemQueueLength, List<String> cacheEntryExceptions) {
+    this.name = name;
+    this.explicitFileCount = explicitFileCount;
+    this.implicitFileCount = implicitFileCount;
+    this.workItemQueueLength = workItemQueueLength;
+    this.cacheEntryExceptions = cacheEntryExceptions;
+  }
+
+  factory ContextData.fromJson(JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      String name;
+      if (json.containsKey("name")) {
+        name = jsonDecoder.decodeString(jsonPath + ".name", json["name"]);
+      } else {
+        throw jsonDecoder.missingKey(jsonPath, "name");
+      }
+      int explicitFileCount;
+      if (json.containsKey("explicitFileCount")) {
+        explicitFileCount = jsonDecoder.decodeInt(jsonPath + ".explicitFileCount", json["explicitFileCount"]);
+      } else {
+        throw jsonDecoder.missingKey(jsonPath, "explicitFileCount");
+      }
+      int implicitFileCount;
+      if (json.containsKey("implicitFileCount")) {
+        implicitFileCount = jsonDecoder.decodeInt(jsonPath + ".implicitFileCount", json["implicitFileCount"]);
+      } else {
+        throw jsonDecoder.missingKey(jsonPath, "implicitFileCount");
+      }
+      int workItemQueueLength;
+      if (json.containsKey("workItemQueueLength")) {
+        workItemQueueLength = jsonDecoder.decodeInt(jsonPath + ".workItemQueueLength", json["workItemQueueLength"]);
+      } else {
+        throw jsonDecoder.missingKey(jsonPath, "workItemQueueLength");
+      }
+      List<String> cacheEntryExceptions;
+      if (json.containsKey("cacheEntryExceptions")) {
+        cacheEntryExceptions = jsonDecoder.decodeList(jsonPath + ".cacheEntryExceptions", json["cacheEntryExceptions"], jsonDecoder.decodeString);
+      } else {
+        throw jsonDecoder.missingKey(jsonPath, "cacheEntryExceptions");
+      }
+      return new ContextData(name, explicitFileCount, implicitFileCount, workItemQueueLength, cacheEntryExceptions);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, "ContextData", json);
+    }
+  }
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["name"] = name;
+    result["explicitFileCount"] = explicitFileCount;
+    result["implicitFileCount"] = implicitFileCount;
+    result["workItemQueueLength"] = workItemQueueLength;
+    result["cacheEntryExceptions"] = cacheEntryExceptions;
+    return result;
+  }
+
+  @override
+  String toString() => JSON.encode(toJson());
+
+  @override
+  bool operator==(other) {
+    if (other is ContextData) {
+      return name == other.name &&
+          explicitFileCount == other.explicitFileCount &&
+          implicitFileCount == other.implicitFileCount &&
+          workItemQueueLength == other.workItemQueueLength &&
+          listEqual(cacheEntryExceptions, other.cacheEntryExceptions, (String a, String b) => a == b);
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, name.hashCode);
+    hash = JenkinsSmiHash.combine(hash, explicitFileCount.hashCode);
+    hash = JenkinsSmiHash.combine(hash, implicitFileCount.hashCode);
+    hash = JenkinsSmiHash.combine(hash, workItemQueueLength.hashCode);
+    hash = JenkinsSmiHash.combine(hash, cacheEntryExceptions.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
  * Element
  *
  * {
@@ -15000,8 +15278,8 @@
  * extractLocalVariable feedback
  *
  * {
- *   "coveringExpressionOffsets": List<int>
- *   "coveringExpressionLengths": List<int>
+ *   "coveringExpressionOffsets": optional List<int>
+ *   "coveringExpressionLengths": optional List<int>
  *   "names": List<String>
  *   "offsets": List<int>
  *   "lengths": List<int>
@@ -15031,7 +15309,6 @@
    * the down most to the up most.
    */
   void set coveringExpressionOffsets(List<int> value) {
-    assert(value != null);
     this._coveringExpressionOffsets = value;
   }
 
@@ -15046,7 +15323,6 @@
    * the down most to the up most.
    */
   void set coveringExpressionLengths(List<int> value) {
-    assert(value != null);
     this._coveringExpressionLengths = value;
   }
 
@@ -15097,7 +15373,7 @@
     this._lengths = value;
   }
 
-  ExtractLocalVariableFeedback(List<int> coveringExpressionOffsets, List<int> coveringExpressionLengths, List<String> names, List<int> offsets, List<int> lengths) {
+  ExtractLocalVariableFeedback(List<String> names, List<int> offsets, List<int> lengths, {List<int> coveringExpressionOffsets, List<int> coveringExpressionLengths}) {
     this.coveringExpressionOffsets = coveringExpressionOffsets;
     this.coveringExpressionLengths = coveringExpressionLengths;
     this.names = names;
@@ -15113,14 +15389,10 @@
       List<int> coveringExpressionOffsets;
       if (json.containsKey("coveringExpressionOffsets")) {
         coveringExpressionOffsets = jsonDecoder.decodeList(jsonPath + ".coveringExpressionOffsets", json["coveringExpressionOffsets"], jsonDecoder.decodeInt);
-      } else {
-        throw jsonDecoder.missingKey(jsonPath, "coveringExpressionOffsets");
       }
       List<int> coveringExpressionLengths;
       if (json.containsKey("coveringExpressionLengths")) {
         coveringExpressionLengths = jsonDecoder.decodeList(jsonPath + ".coveringExpressionLengths", json["coveringExpressionLengths"], jsonDecoder.decodeInt);
-      } else {
-        throw jsonDecoder.missingKey(jsonPath, "coveringExpressionLengths");
       }
       List<String> names;
       if (json.containsKey("names")) {
@@ -15140,7 +15412,7 @@
       } else {
         throw jsonDecoder.missingKey(jsonPath, "lengths");
       }
-      return new ExtractLocalVariableFeedback(coveringExpressionOffsets, coveringExpressionLengths, names, offsets, lengths);
+      return new ExtractLocalVariableFeedback(names, offsets, lengths, coveringExpressionOffsets: coveringExpressionOffsets, coveringExpressionLengths: coveringExpressionLengths);
     } else {
       throw jsonDecoder.mismatch(jsonPath, "extractLocalVariable feedback", json);
     }
@@ -15148,8 +15420,12 @@
 
   Map<String, dynamic> toJson() {
     Map<String, dynamic> result = {};
-    result["coveringExpressionOffsets"] = coveringExpressionOffsets;
-    result["coveringExpressionLengths"] = coveringExpressionLengths;
+    if (coveringExpressionOffsets != null) {
+      result["coveringExpressionOffsets"] = coveringExpressionOffsets;
+    }
+    if (coveringExpressionLengths != null) {
+      result["coveringExpressionLengths"] = coveringExpressionLengths;
+    }
     result["names"] = names;
     result["offsets"] = offsets;
     result["lengths"] = lengths;
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 60f8d8c..93c929c 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -23,6 +23,7 @@
 import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/source/embedder.dart';
 import 'package:analyzer/source/pub_package_map_provider.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
@@ -33,7 +34,7 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
-import 'package:glob/glob.dart';
+import 'package:analyzer/src/util/glob.dart';
 import 'package:plugin/plugin.dart';
 
 typedef void OptionUpdater(AnalysisOptionsImpl options);
@@ -472,22 +473,16 @@
   }
 
   /**
-   * Return the [AnalysisContext] that contains the given [path].
-   * Return `null` if no context contains the [path].
+   * Return the [AnalysisContext] for the "innermost" context whose associated
+   * folder is or contains the given path.  ("innermost" refers to the nesting
+   * of contexts, so if there is a context for path /foo and a context for
+   * path /foo/bar, then the innermost context containing /foo/bar/baz.dart is
+   * the context for /foo/bar.)
+   *
+   * If no context contains the given path, `null` is returned.
    */
   AnalysisContext getContainingContext(String path) {
-    Folder containingFolder = null;
-    AnalysisContext containingContext = null;
-    folderMap.forEach((Folder folder, AnalysisContext context) {
-      if (folder.isOrContains(path)) {
-        if (containingFolder == null ||
-            containingFolder.path.length < folder.path.length) {
-          containingFolder = folder;
-          containingContext = context;
-        }
-      }
-    });
-    return containingContext;
+    return contextManager.getContextFor(path);
   }
 
   /**
@@ -757,6 +752,10 @@
     if (context == null) {
       return null;
     }
+    // done if everything is already analyzed
+    if (isAnalysisComplete()) {
+      return new Future.value(AnalysisDoneReason.COMPLETE);
+    }
     // schedule context analysis
     schedulePerformAnalysisOperation(context);
     // associate with the context completer
@@ -1094,7 +1093,8 @@
         contextFound = true;
       }
       for (AnalysisContext context in folderMap.values) {
-        if (context.getKindOf(source) != SourceKind.UNKNOWN) {
+        if (context != preferredContext &&
+            context.getKindOf(source) != SourceKind.UNKNOWN) {
           sourceMap.putIfAbsent(context, () => <Source>[]).add(source);
           contextFound = true;
         }
@@ -1430,7 +1430,7 @@
       for (String pattern in patterns) {
         try {
           _analyzedFilesGlobs
-              .add(new Glob(pattern, context: JavaFile.pathContext));
+              .add(new Glob(JavaFile.pathContext.separator, pattern));
         } catch (exception, stackTrace) {
           AnalysisEngine.instance.logger.logError(
               'Invalid glob pattern: "$pattern"',
@@ -1447,7 +1447,8 @@
         AnalysisEngine.instance.createAnalysisContext();
     context.contentCache = analysisServer.overlayState;
     analysisServer.folderMap[folder] = context;
-    context.sourceFactory = _createSourceFactory(disposition);
+    _locateEmbedderYamls(context, disposition);
+    context.sourceFactory = _createSourceFactory(context, disposition);
     context.analysisOptions =
         new AnalysisOptionsImpl.from(analysisServer.defaultContextOptions);
     analysisServer._onContextsChangedController
@@ -1460,8 +1461,10 @@
   void applyChangesToContext(Folder contextFolder, ChangeSet changeSet) {
     AnalysisContext context = analysisServer.folderMap[contextFolder];
     if (context != null) {
-      context.applyChanges(changeSet);
-      analysisServer.schedulePerformAnalysisOperation(context);
+      ApplyChangesStatus changesStatus = context.applyChanges(changeSet);
+      if (changesStatus.hasChanges) {
+        analysisServer.schedulePerformAnalysisOperation(context);
+      }
       List<String> flushedFiles = new List<String>();
       for (Source source in changeSet.removedSources) {
         flushedFiles.add(source.fullName);
@@ -1516,7 +1519,7 @@
   void updateContextPackageUriResolver(
       Folder contextFolder, FolderDisposition disposition) {
     AnalysisContext context = analysisServer.folderMap[contextFolder];
-    context.sourceFactory = _createSourceFactory(disposition);
+    context.sourceFactory = _createSourceFactory(context, disposition);
     analysisServer._onContextsChangedController
         .add(new ContextsChangedEvent(changed: [context]));
     analysisServer.schedulePerformAnalysisOperation(context);
@@ -1534,15 +1537,39 @@
    * Set up a [SourceFactory] that resolves packages as appropriate for the
    * given [disposition].
    */
-  SourceFactory _createSourceFactory(FolderDisposition disposition) {
-    UriResolver dartResolver = new DartUriResolver(analysisServer.defaultSdk);
-    UriResolver resourceResolver = new ResourceUriResolver(resourceProvider);
+  SourceFactory _createSourceFactory(
+      InternalAnalysisContext context, FolderDisposition disposition) {
     List<UriResolver> resolvers = [];
-    resolvers.add(dartResolver);
-    resolvers.addAll(disposition.createPackageUriResolvers(resourceProvider));
-    resolvers.add(resourceResolver);
+    List<UriResolver> packageUriResolvers =
+        disposition.createPackageUriResolvers(resourceProvider);
+    EmbedderUriResolver embedderUriResolver =
+        new EmbedderUriResolver(context.embedderYamlLocator.embedderYamls);
+    if (embedderUriResolver.length == 0) {
+      // The embedder uri resolver has no mappings. Use the default Dart SDK
+      // uri resolver.
+      resolvers.add(new DartUriResolver(analysisServer.defaultSdk));
+    } else {
+      // The embedder uri resolver has mappings, use it instead of the default
+      // Dart SDK uri resolver.
+      resolvers.add(embedderUriResolver);
+    }
+    resolvers.addAll(packageUriResolvers);
+    resolvers.add(new ResourceUriResolver(resourceProvider));
     return new SourceFactory(resolvers, disposition.packages);
   }
+
+  /// If [disposition] has a package map, attempt to locate `_embedder.yaml`
+  /// files.
+  void _locateEmbedderYamls(
+      InternalAnalysisContext context, FolderDisposition disposition) {
+    Map<String, List<Folder>> packageMap;
+    if (disposition is PackageMapDisposition) {
+      packageMap = disposition.packageMap;
+    } else if (disposition is PackagesFileDisposition) {
+      packageMap = disposition.buildPackageMap(resourceProvider);
+    }
+    context.embedderYamlLocator.refresh(packageMap);
+  }
 }
 
 /**
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index e232607..14ce4ec 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -26,6 +26,9 @@
 import 'package:analyzer/src/generated/java_io.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/task/options.dart';
+import 'package:analyzer/src/util/absolute_path.dart';
+import 'package:analyzer/src/util/yaml.dart';
 import 'package:package_config/packages.dart';
 import 'package:package_config/packages_file.dart' as pkgfile show parse;
 import 'package:package_config/src/packages_impl.dart' show MapPackages;
@@ -226,6 +229,17 @@
   List<AnalysisContext> contextsInAnalysisRoot(Folder analysisRoot);
 
   /**
+   * Return the [AnalysisContext] for the "innermost" context whose associated
+   * folder is or contains the given path.  ("innermost" refers to the nesting
+   * of contexts, so if there is a context for path /foo and a context for
+   * path /foo/bar, then the innermost context containing /foo/bar/baz.dart is
+   * the context for /foo/bar.)
+   *
+   * If no context contains the given path, `null` is returned.
+   */
+  AnalysisContext getContextFor(String path);
+
+  /**
    * Return `true` if the given absolute [path] is in one of the current
    * root folders and is not excluded.
    */
@@ -341,6 +355,13 @@
   final ResourceProvider resourceProvider;
 
   /**
+   * The context used to work with absolute file system paths.
+   *
+   * TODO(scheglov) remove [pathContext].
+   */
+  AbsolutePathContext absolutePathContext;
+
+  /**
    * The context used to work with file system paths.
    */
   pathos.Context pathContext;
@@ -403,11 +424,12 @@
    * Stream subscription we are using to watch each analysis root directory for
    * changes.
    */
-  final Map<Folder, StreamSubscription<WatchEvent>> _changeSubscriptions =
+  final Map<Folder, StreamSubscription<WatchEvent>> changeSubscriptions =
       <Folder, StreamSubscription<WatchEvent>>{};
 
   ContextManagerImpl(this.resourceProvider, this.packageResolverProvider,
       this._packageMapProvider, this._instrumentationService) {
+    absolutePathContext = resourceProvider.absolutePathContext;
     pathContext = resourceProvider.pathContext;
   }
 
@@ -434,6 +456,11 @@
     return contexts;
   }
 
+  @override
+  AnalysisContext getContextFor(String path) {
+    return _getInnermostContextInfoFor(path)?.context;
+  }
+
   /**
    * For testing: get the [ContextInfo] object for the given [folder], if any.
    */
@@ -469,16 +496,8 @@
     Map<String, YamlNode> options;
     try {
       options = analysisOptionsProvider.getOptions(folder);
-    } catch (e, stacktrace) {
-      AnalysisEngine.instance.logger.logError(
-          'Error processing .analysis_options',
-          new CaughtException(e, stacktrace));
-      // TODO(pquitslund): contribute plugin that sends error notification on
-      // options file.
-      // Related test:
-      //   context_manager_test.test_analysis_options_parse_failure()
-      // AnalysisEngine.instance.optionsPlugin.optionsProcessors
-      //      .forEach((OptionsProcessor p) => p.onError(e));
+    } catch (_) {
+      // Parse errors are reported by GenerateOptionsErrorsTask.
     }
 
     if (options == null && !optionsRemoved) {
@@ -497,31 +516,36 @@
       }
     });
 
-    // In case options files are removed, revert to default options.
+    // In case options files are removed, revert to defaults.
     if (optionsRemoved) {
+      // Start with defaults.
       info.context.analysisOptions = new AnalysisOptionsImpl();
+
+      // Apply inherited options.
+      YamlMap embeddedOptions = _getEmbeddedOptions(info.context);
+      if (embeddedOptions != null) {
+        configureContextOptions(info.context, embeddedOptions);
+      }
       return;
     }
 
+    // Check for embedded options.
+    YamlMap embeddedOptions = _getEmbeddedOptions(info.context);
+    if (embeddedOptions != null) {
+      options = new Merger().merge(embeddedOptions, options);
+    }
+
     // Analysis options are processed 'in-line'.
-    YamlMap analyzer = options['analyzer'];
-    if (analyzer == null) {
+    var analyzer = options[AnalyzerOptions.analyzer];
+    if (analyzer is! Map) {
       // No options for analyzer.
       return;
     }
 
-    // Set strong mode (default is false).
-    bool strongMode = analyzer['strong-mode'] ?? false;
-    AnalysisContext context = info.context;
-    if (context.analysisOptions.strongMode != strongMode) {
-      AnalysisOptionsImpl options =
-          new AnalysisOptionsImpl.from(context.analysisOptions);
-      options.strongMode = strongMode;
-      context.analysisOptions = options;
-    }
+    configureContextOptions(info.context, options);
 
     // Set ignore patterns.
-    YamlList exclude = analyzer['exclude'];
+    YamlList exclude = analyzer[AnalyzerOptions.exclude];
     if (exclude != null) {
       setIgnorePatternsForContext(info, exclude);
     }
@@ -616,7 +640,7 @@
         return info.folder.isOrContains(includedFolder.path);
       });
       if (!wasIncluded) {
-        _changeSubscriptions[includedFolder] =
+        changeSubscriptions[includedFolder] =
             includedFolder.changes.listen(_handleWatchEvent);
         _createContexts(_rootInfo, includedFolder, false);
       }
@@ -752,7 +776,7 @@
       String path, ContextInfo info, Folder folder) {
     // Check to see if this is the .packages file for this context and if so,
     // update the context's source factory.
-    if (pathContext.basename(path) == PACKAGE_SPEC_NAME &&
+    if (absolutePathContext.basename(path) == PACKAGE_SPEC_NAME &&
         info.isPathToPackageDescription(path)) {
       File packagespec = resourceProvider.getFile(path);
       if (packagespec.exists) {
@@ -835,7 +859,8 @@
       callbacks.beginComputePackageMap();
       try {
         // Try .packages first.
-        if (pathContext.basename(packagespecFile.path) == PACKAGE_SPEC_NAME) {
+        if (absolutePathContext.basename(packagespecFile.path) ==
+            PACKAGE_SPEC_NAME) {
           Packages packages = _readPackagespec(packagespecFile);
           return new PackagesFileDisposition(packages);
         }
@@ -845,6 +870,7 @@
             return new CustomPackageResolverDisposition(resolver);
           }
         }
+
         ServerPerformanceStatistics.pub.makeCurrentWhile(() {
           packageMapInfo = _packageMapProvider.computePackageMap(folder);
         });
@@ -949,9 +975,7 @@
    * Clean up and destroy the context associated with the given folder.
    */
   void _destroyContext(ContextInfo info) {
-    if (_changeSubscriptions.containsKey(info.folder)) {
-      _changeSubscriptions[info.folder].cancel();
-    }
+    changeSubscriptions.remove(info.folder)?.cancel();
     callbacks.removeContext(info.folder, _computeFlushedFiles(info));
     bool wasRemoved = info.parent.children.remove(info);
     assert(wasRemoved);
@@ -1013,6 +1037,20 @@
     return packageSpec;
   }
 
+  /// Get analysis options associated with an `_embedder.yaml`. If there is
+  /// more than one `_embedder.yaml` associated with the given context, `null`
+  /// is returned.
+  YamlMap _getEmbeddedOptions(AnalysisContext context) {
+    if (context is InternalAnalysisContext) {
+      EmbedderYamlLocator locator = context.embedderYamlLocator;
+      Iterable<YamlMap> maps = locator.embedderYamls.values;
+      if (maps.length == 1) {
+        return maps.first;
+      }
+    }
+    return null;
+  }
+
   /**
    * Return the [ContextInfo] for the "innermost" context whose associated
    * folder is or contains the given path.  ("innermost" refers to the nesting
@@ -1077,7 +1115,7 @@
       case ChangeType.ADD:
         Resource resource = resourceProvider.getResource(path);
 
-        String directoryPath = pathContext.dirname(path);
+        String directoryPath = absolutePathContext.dirname(path);
 
         // Check to see if we need to create a new context.
         if (info.isTopLevel) {
@@ -1087,7 +1125,8 @@
             if (_isPubspec(path)) {
               // Check for a sibling .packages file.
               if (!resourceProvider
-                  .getFile(pathContext.join(directoryPath, PACKAGE_SPEC_NAME))
+                  .getFile(absolutePathContext.append(
+                      directoryPath, PACKAGE_SPEC_NAME))
                   .exists) {
                 _extractContext(info, resource);
                 return;
@@ -1096,7 +1135,8 @@
             if (_isPackagespec(path)) {
               // Check for a sibling pubspec.yaml file.
               if (!resourceProvider
-                  .getFile(pathContext.join(directoryPath, PUBSPEC_NAME))
+                  .getFile(
+                      absolutePathContext.append(directoryPath, PUBSPEC_NAME))
                   .exists) {
                 _extractContext(info, resource);
                 return;
@@ -1125,14 +1165,15 @@
         // Note that it's important to verify that there is NEITHER a .packages nor a
         // lingering pubspec.yaml before merging.
         if (!info.isTopLevel) {
-          String directoryPath = pathContext.dirname(path);
+          String directoryPath = absolutePathContext.dirname(path);
 
           // Only merge if this is the same directory described by our info object.
           if (info.folder.path == directoryPath) {
             if (_isPubspec(path)) {
               // Check for a sibling .packages file.
               if (!resourceProvider
-                  .getFile(pathContext.join(directoryPath, PACKAGE_SPEC_NAME))
+                  .getFile(absolutePathContext.append(
+                      directoryPath, PACKAGE_SPEC_NAME))
                   .exists) {
                 _mergeContext(info);
                 return;
@@ -1141,7 +1182,8 @@
             if (_isPackagespec(path)) {
               // Check for a sibling pubspec.yaml file.
               if (!resourceProvider
-                  .getFile(pathContext.join(directoryPath, PUBSPEC_NAME))
+                  .getFile(
+                      absolutePathContext.append(directoryPath, PUBSPEC_NAME))
                   .exists) {
                 _mergeContext(info);
                 return;
@@ -1180,9 +1222,12 @@
    * context root [root], contains a folder whose name starts with '.'.
    */
   bool _isContainedInDotFolder(String root, String path) {
-    String relativePath =
-        pathContext.relative(pathContext.dirname(path), from: root);
-    for (String pathComponent in pathContext.split(relativePath)) {
+    String pathDir = absolutePathContext.dirname(path);
+    String suffixPath = absolutePathContext.suffix(root, pathDir);
+    if (suffixPath == null) {
+      return false;
+    }
+    for (String pathComponent in absolutePathContext.split(suffixPath)) {
       if (pathComponent.startsWith('.') &&
           pathComponent != '.' &&
           pathComponent != '..') {
@@ -1202,7 +1247,7 @@
    */
   bool _isExcludedBy(List<String> excludedPaths, String path) {
     return excludedPaths.any((excludedPath) {
-      if (pathContext.isWithin(excludedPath, path)) {
+      if (absolutePathContext.isWithin(excludedPath, path)) {
         return true;
       }
       return path == excludedPath;
@@ -1214,8 +1259,11 @@
    * context root [root], contains a 'packages' folder.
    */
   bool _isInPackagesDir(String root, String path) {
-    String relativePath = pathContext.relative(path, from: root);
-    List<String> pathParts = pathContext.split(relativePath);
+    String suffixPath = absolutePathContext.suffix(root, path);
+    if (suffixPath == null) {
+      return false;
+    }
+    List<String> pathParts = absolutePathContext.split(suffixPath);
     return pathParts.contains(PACKAGES_NAME);
   }
 
@@ -1224,15 +1272,19 @@
    * context root [root].
    */
   bool _isInTopLevelDocDir(String root, String path) {
-    String relativePath = pathContext.relative(path, from: root);
-    return relativePath == DOC_DIR_NAME ||
-        relativePath.startsWith(DOC_DIR_NAME + pathContext.separator);
+    String suffixPath = absolutePathContext.suffix(root, path);
+    if (suffixPath == null) {
+      return false;
+    }
+    return suffixPath == DOC_DIR_NAME ||
+        suffixPath.startsWith(DOC_DIR_NAME + absolutePathContext.separator);
   }
 
   bool _isPackagespec(String path) =>
-      pathContext.basename(path) == PACKAGE_SPEC_NAME;
+      absolutePathContext.basename(path) == PACKAGE_SPEC_NAME;
 
-  bool _isPubspec(String path) => pathContext.basename(path) == PUBSPEC_NAME;
+  bool _isPubspec(String path) =>
+      absolutePathContext.basename(path) == PUBSPEC_NAME;
 
   /**
    * Merges [info] context into its parent.
@@ -1450,18 +1502,26 @@
   @override
   String get packageRoot => null;
 
+  Map<String, List<Folder>> buildPackageMap(ResourceProvider resourceProvider) {
+    Map<String, List<Folder>> packageMap = <String, List<Folder>>{};
+    if (packages == null) {
+      return packageMap;
+    }
+    packages.asMap().forEach((String name, Uri uri) {
+      if (uri.scheme == 'file' || uri.scheme == '' /* unspecified */) {
+        var path = resourceProvider.pathContext.fromUri(uri);
+        packageMap[name] = <Folder>[resourceProvider.getFolder(path)];
+      }
+    });
+    return packageMap;
+  }
+
   @override
   Iterable<UriResolver> createPackageUriResolvers(
       ResourceProvider resourceProvider) {
     if (packages != null) {
       // Construct package map for the SdkExtUriResolver.
-      Map<String, List<Folder>> packageMap = <String, List<Folder>>{};
-      packages.asMap().forEach((String name, Uri uri) {
-        if (uri.scheme == 'file' || uri.scheme == '' /* unspecified */) {
-          var path = resourceProvider.pathContext.fromUri(uri);
-          packageMap[name] = <Folder>[resourceProvider.getFolder(path)];
-        }
-      });
+      Map<String, List<Folder>> packageMap = buildPackageMap(resourceProvider);
       return <UriResolver>[new SdkExtUriResolver(packageMap)];
     } else {
       return const <UriResolver>[];
diff --git a/pkg/analysis_server/lib/src/domain_diagnostic.dart b/pkg/analysis_server/lib/src/domain_diagnostic.dart
new file mode 100644
index 0000000..e6c08c4
--- /dev/null
+++ b/pkg/analysis_server/lib/src/domain_diagnostic.dart
@@ -0,0 +1,95 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library src.domain_diagnostic;
+
+import 'dart:collection';
+import 'dart:core' hide Resource;
+
+import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analysis_server/src/analysis_server.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/generated/engine.dart'
+    hide AnalysisCache, AnalysisContextImpl;
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/task/driver.dart';
+import 'package:analyzer/task/model.dart';
+
+/// Extract context data from the given [context].
+ContextData extractData(AnalysisContext context) {
+  int explicitFiles = 0;
+  int implicitFiles = 0;
+  int workItems = 0;
+  Set<String> exceptions = new HashSet<String>();
+  if (context is AnalysisContextImpl) {
+    // Work Item count.
+    AnalysisDriver driver = context.driver;
+    List<WorkItem> items = driver.currentWorkOrder?.workItems;
+    workItems ??= items?.length;
+    var cache = context.analysisCache;
+    if (cache is AnalysisCache) {
+      Set<AnalysisTarget> countedTargets = new HashSet<AnalysisTarget>();
+      MapIterator<AnalysisTarget, CacheEntry> iterator = cache.iterator();
+      while (iterator.moveNext()) {
+        AnalysisTarget target = iterator.key;
+        if (countedTargets.add(target)) {
+          CacheEntry cacheEntry = iterator.value;
+          if (target is Source) {
+            if (cacheEntry.explicitlyAdded) {
+              explicitFiles++;
+            } else {
+              implicitFiles++;
+            }
+          }
+          // Caught exceptions.
+          if (cacheEntry.exception != null) {
+            exceptions.add(cacheEntry.exception.toString());
+          }
+        }
+      }
+    }
+  }
+  return new ContextData(context.name, explicitFiles, implicitFiles, workItems,
+      exceptions.toList());
+}
+
+/// Instances of the class [DiagnosticDomainHandler] implement a
+/// [RequestHandler] that handles requests in the `diagnostic` domain.
+class DiagnosticDomainHandler implements RequestHandler {
+  /// The name of the request used to get diagnostic information.
+  static const String DIAGNOSTICS = 'diagnostic.getDiagnostics';
+
+  /// The analysis server that is using this handler to process requests.
+  final AnalysisServer server;
+
+  /// Initialize a newly created handler to handle requests for the given
+  /// [server].
+  DiagnosticDomainHandler(this.server);
+
+  /// Answer the `diagnostic.diagnostics` request.
+  Response computeDiagnostics(Request request) {
+    List<ContextData> infos = <ContextData>[];
+    server.folderMap.forEach((Folder folder, AnalysisContext context) {
+      infos.add(extractData(context));
+    });
+
+    return new DiagnosticGetDiagnosticsResult(infos).toResponse(request.id);
+  }
+
+  @override
+  Response handleRequest(Request request) {
+    try {
+      String requestName = request.method;
+      if (requestName == DIAGNOSTICS) {
+        return computeDiagnostics(request);
+      }
+    } on RequestFailure catch (exception) {
+      return exception.response;
+    }
+    return null;
+  }
+}
diff --git a/pkg/analysis_server/lib/src/domain_execution.dart b/pkg/analysis_server/lib/src/domain_execution.dart
index 470d3c3..c2f8a5a 100644
--- a/pkg/analysis_server/lib/src/domain_execution.dart
+++ b/pkg/analysis_server/lib/src/domain_execution.dart
@@ -117,7 +117,11 @@
       }
       ContextSourcePair contextSource = server.getContextSourcePair(file);
       Source source = contextSource.source;
-      uri = context.sourceFactory.restoreUri(source).toString();
+      if (source.uriKind != UriKind.FILE_URI) {
+        uri = source.uri.toString();
+      } else {
+        uri = context.sourceFactory.restoreUri(source).toString();
+      }
       return new ExecutionMapUriResult(uri: uri).toResponse(request.id);
     } else if (uri != null) {
       Source source = context.sourceFactory.forUri(uri);
diff --git a/pkg/analysis_server/lib/src/domain_experimental.dart b/pkg/analysis_server/lib/src/domain_experimental.dart
deleted file mode 100644
index 43631f2..0000000
--- a/pkg/analysis_server/lib/src/domain_experimental.dart
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library src.domain_experimental;
-
-import 'dart:core' hide Resource;
-
-import 'package:analysis_server/plugin/protocol/protocol.dart';
-import 'package:analysis_server/src/analysis_server.dart';
-
-/**
- * Instances of the class [ExperimentalDomainHandler] implement a
- * [RequestHandler] that handles requests in the `experimental` domain.
- */
-class ExperimentalDomainHandler implements RequestHandler {
-  /**
-   * The analysis server that is using this handler to process requests.
-   */
-  final AnalysisServer server;
-
-  /**
-   * The name of the request used to get diagnostic information.
-   */
-  static const String EXPERIMENTAL_DIAGNOSTICS = 'experimental.diagnostics';
-
-  /**
-   * Initialize a newly created handler to handle requests for the given [server].
-   */
-  ExperimentalDomainHandler(this.server);
-
-  @override
-  Response handleRequest(Request request) {
-    try {
-      String requestName = request.method;
-      if (requestName == EXPERIMENTAL_DIAGNOSTICS) {
-        return computeDiagnostics(request);
-      }
-    } on RequestFailure catch (exception) {
-      return exception.response;
-    }
-    return null;
-  }
-
-  /**
-   * Implement the `experimental.diagnostics` request.
-   */
-  Response computeDiagnostics(Request request) {
-    return new Response.unknownRequest(request);
-  }
-}
diff --git a/pkg/analysis_server/lib/src/domains/analysis/navigation.dart b/pkg/analysis_server/lib/src/domains/analysis/navigation.dart
index 9911d92..c991353 100644
--- a/pkg/analysis_server/lib/src/domains/analysis/navigation.dart
+++ b/pkg/analysis_server/lib/src/domains/analysis/navigation.dart
@@ -13,7 +13,7 @@
 import 'package:analyzer/src/generated/engine.dart'
     show AnalysisContext, AnalysisEngine;
 import 'package:analyzer/src/generated/java_engine.dart' show CaughtException;
-import 'package:analyzer/src/generated/source.dart' show Source;
+import 'package:analyzer/src/generated/source.dart' show Source, SourceRange;
 
 /**
  * Compute all known navigation information for the given part of [source].
@@ -32,7 +32,7 @@
           new CaughtException(exception, stackTrace));
     }
   }
-  collector.sortRegions();
+  collector.createRegions();
   return collector;
 }
 
@@ -44,6 +44,8 @@
    * A list of navigation regions.
    */
   final List<protocol.NavigationRegion> regions = <protocol.NavigationRegion>[];
+  final Map<SourceRange, List<int>> regionMap =
+      new HashMap<SourceRange, List<int>>();
 
   /**
    * All the unique targets referenced by [regions].
@@ -61,13 +63,24 @@
   @override
   void addRegion(int offset, int length, protocol.ElementKind targetKind,
       protocol.Location targetLocation) {
+    SourceRange range = new SourceRange(offset, length);
+    // prepare targets
+    List<int> targets = regionMap[range];
+    if (targets == null) {
+      targets = <int>[];
+      regionMap[range] = targets;
+    }
+    // add new target
     int targetIndex = _addTarget(targetKind, targetLocation);
-    protocol.NavigationRegion region =
-        new protocol.NavigationRegion(offset, length, <int>[targetIndex]);
-    regions.add(region);
+    targets.add(targetIndex);
   }
 
-  void sortRegions() {
+  void createRegions() {
+    regionMap.forEach((range, targets) {
+      protocol.NavigationRegion region =
+          new protocol.NavigationRegion(range.offset, range.length, targets);
+      regions.add(region);
+    });
     regions.sort((a, b) {
       return a.offset - b.offset;
     });
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index 3931907..e14f3b3 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -558,7 +558,9 @@
       if (units.isNotEmpty) {
         refactoring = new ExtractLocalRefactoring(units[0], offset, length);
         feedback = new ExtractLocalVariableFeedback(
-            <int>[], <int>[], <String>[], <int>[], <int>[]);
+            <String>[], <int>[], <int>[],
+            coveringExpressionOffsets: <int>[],
+            coveringExpressionLengths: <int>[]);
       }
     }
     if (kind == RefactoringKind.EXTRACT_METHOD) {
@@ -626,6 +628,10 @@
       feedback.names = refactoring.names;
       feedback.offsets = refactoring.offsets;
       feedback.lengths = refactoring.lengths;
+      feedback.coveringExpressionOffsets =
+          refactoring.coveringExpressionOffsets;
+      feedback.coveringExpressionLengths =
+          refactoring.coveringExpressionLengths;
     }
     if (refactoring is ExtractMethodRefactoring) {
       ExtractMethodRefactoring refactoring = this.refactoring;
diff --git a/pkg/analysis_server/lib/src/plugin/server_plugin.dart b/pkg/analysis_server/lib/src/plugin/server_plugin.dart
index b4de83f..a7a13dd 100644
--- a/pkg/analysis_server/lib/src/plugin/server_plugin.dart
+++ b/pkg/analysis_server/lib/src/plugin/server_plugin.dart
@@ -20,8 +20,8 @@
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/domain_analysis.dart';
 import 'package:analysis_server/src/domain_completion.dart';
+import 'package:analysis_server/src/domain_diagnostic.dart';
 import 'package:analysis_server/src/domain_execution.dart';
-import 'package:analysis_server/src/domain_experimental.dart';
 import 'package:analysis_server/src/domain_server.dart';
 import 'package:analysis_server/src/domains/analysis/navigation_dart.dart';
 import 'package:analysis_server/src/domains/analysis/occurrences_dart.dart';
@@ -276,10 +276,10 @@
     // Register analyzed file patterns.
     //
     List<String> patterns = <String>[
-      '{*:/,/}**/*.${AnalysisEngine.SUFFIX_DART}',
-      '{*:/,/}**/*.${AnalysisEngine.SUFFIX_HTML}',
-      '{*:/,/}**/*.${AnalysisEngine.SUFFIX_HTM}',
-      '{*:/,/}**/${AnalysisEngine.ANALYSIS_OPTIONS_FILE}'
+      '**/*.${AnalysisEngine.SUFFIX_DART}',
+      '**/*.${AnalysisEngine.SUFFIX_HTML}',
+      '**/*.${AnalysisEngine.SUFFIX_HTM}',
+      '**/${AnalysisEngine.ANALYSIS_OPTIONS_FILE}'
     ];
     registerExtension(ANALYZED_FILE_PATTERNS_EXTENSION_POINT_ID, patterns);
     //
@@ -316,7 +316,7 @@
     registerExtension(domainId,
         (AnalysisServer server) => new ExecutionDomainHandler(server));
     registerExtension(domainId,
-        (AnalysisServer server) => new ExperimentalDomainHandler(server));
+        (AnalysisServer server) => new DiagnosticDomainHandler(server));
     //
     // Register fix contributors.
     //
diff --git a/pkg/analysis_server/lib/src/provisional/completion/completion_core.dart b/pkg/analysis_server/lib/src/provisional/completion/completion_core.dart
index 75f830b..af69cd0 100644
--- a/pkg/analysis_server/lib/src/provisional/completion/completion_core.dart
+++ b/pkg/analysis_server/lib/src/provisional/completion/completion_core.dart
@@ -6,15 +6,42 @@
 
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/task/model.dart';
 
 /**
- * An object used to produce completions for a specific error. Completion
- * contributors are long-lived objects and must not retain any state between
- * invocations of [computeSuggestions].
+ * A method or function called when the requested analysis has been performed.
+ */
+typedef AnalysisRequest AnalysisCallback<V>(
+    CompletionRequest request, V computedValue);
+
+/**
+ * A request from a contributor for additional analysis.
+ */
+class AnalysisRequest<V> {
+  /**
+   * An object with which an analysis result can be associated.
+   */
+  AnalysisTarget target;
+
+  /**
+   * A description of an analysis result that can be computed by an [AnalysisTask].
+   */
+  ResultDescriptor<V> descriptor;
+
+  /**
+   * A method or function called when the requested analysis has been performed.
+   */
+  AnalysisCallback<V> callback;
+
+  AnalysisRequest(this.target, this.descriptor, this.callback);
+}
+
+/**
+ * An object used to produce completions at a specific location within a file.
  *
- * Clients may implement this class when implementing plugins.
+ * Clients may extend this class when implementing plugins.
  */
 abstract class CompletionContributor {
   /**
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index f00f452..1238a1c 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -383,6 +383,7 @@
     //
     String logFilePath = results[INSTRUMENTATION_LOG_FILE];
     if (logFilePath != null) {
+      _rollLogFiles(logFilePath, 5);
       FileInstrumentationServer fileBasedServer =
           new FileInstrumentationServer(logFilePath);
       instrumentationServer = instrumentationServer != null
@@ -428,11 +429,11 @@
     }
 
     _captureExceptions(service, () {
-      stdioServer.serveStdio().then((_) {
+      stdioServer.serveStdio().then((_) async {
         if (serve_http) {
           httpServer.close();
         }
-        service.shutdown();
+        await service.shutdown();
         exit(0);
       });
     },
@@ -578,4 +579,20 @@
     }
     return uuid;
   }
+
+  /**
+   * Perform log files rolling.
+   *
+   * Rename existing files with names `[path].(x)` to `[path].(x+1)`.
+   * Keep at most [numOld] files.
+   * Rename the file with the given [path] to `[path].1`.
+   */
+  static void _rollLogFiles(String path, int numOld) {
+    for (int i = numOld - 1; i >= 0; i--) {
+      try {
+        String oldPath = i == 0 ? path : '$path.$i';
+        new File(oldPath).renameSync('$path.${i+1}');
+      } catch (e) {}
+    }
+  }
 }
diff --git a/pkg/analysis_server/lib/src/services/completion/common_usage_computer.dart b/pkg/analysis_server/lib/src/services/completion/common_usage_computer.dart
index e3c44ce..7351ad0 100644
--- a/pkg/analysis_server/lib/src/services/completion/common_usage_computer.dart
+++ b/pkg/analysis_server/lib/src/services/completion/common_usage_computer.dart
@@ -13,6 +13,10 @@
     show DART_RELEVANCE_COMMON_USAGE;
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
+import 'package:analysis_server/src/provisional/completion/completion_core.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
+import 'package:analyzer/task/dart.dart';
+import 'package:analyzer/src/task/dart.dart';
 
 part 'common_usage_generated.dart';
 
@@ -33,9 +37,28 @@
   CommonUsageComputer([this.selectorRelevance = defaultSelectorRelevance]);
 
   @override
-  void sort(DartCompletionRequest request,
-      Iterable<CompletionSuggestion> suggestions) {
+  AnalysisRequest sort(
+      CompletionRequest request, Iterable<CompletionSuggestion> suggestions) {
     _update(request, suggestions);
+    return null;
+  }
+
+  CompletionTarget _getCompletionTarget(CompletionRequest request) {
+    // TODO (danrubel) get cached completion target
+    var libSrcs = request.context.getLibrariesContaining(request.source);
+    if (libSrcs.length == 0) {
+      return null;
+    }
+    var libElem = request.context.getResult(libSrcs[0], LIBRARY_ELEMENT1);
+    if (libElem is LibraryElement) {
+      var unit = request.context.getResult(
+          new LibrarySpecificUnit(libElem.source, request.source),
+          RESOLVED_UNIT3);
+      if (unit is CompilationUnit) {
+        return new CompletionTarget.forOffset(unit, request.offset);
+      }
+    }
+    return null;
   }
 
   /**
@@ -43,16 +66,19 @@
    * The compilation unit and completion node
    * in the given completion context may not be resolved.
    */
-  void _update(DartCompletionRequest request,
-      Iterable<CompletionSuggestion> suggestions) {
-    var visitor = new _BestTypeVisitor(request.target.entity);
-    DartType type = request.target.containingNode.accept(visitor);
-    if (type != null) {
-      Element typeElem = type.element;
-      if (typeElem != null) {
-        LibraryElement libElem = typeElem.library;
-        if (libElem != null) {
-          _updateInvocationRelevance(request, type, libElem, suggestions);
+  void _update(
+      CompletionRequest request, Iterable<CompletionSuggestion> suggestions) {
+    var target = _getCompletionTarget(request);
+    if (target != null) {
+      var visitor = new _BestTypeVisitor(target.entity);
+      DartType type = target.containingNode.accept(visitor);
+      if (type != null) {
+        Element typeElem = type.element;
+        if (typeElem != null) {
+          LibraryElement libElem = typeElem.library;
+          if (libElem != null) {
+            _updateInvocationRelevance(type, libElem, suggestions);
+          }
         }
       }
     }
@@ -62,8 +88,8 @@
    * Adjusts the relevance of all method suggestions based upon the given
    * target type and library.
    */
-  void _updateInvocationRelevance(DartCompletionRequest request, DartType type,
-      LibraryElement libElem, Iterable<CompletionSuggestion> suggestions) {
+  void _updateInvocationRelevance(DartType type, LibraryElement libElem,
+      Iterable<CompletionSuggestion> suggestions) {
     String typeName = type.name;
     List<String> selectors = selectorRelevance['${libElem.name}.${typeName}'];
     if (selectors != null) {
diff --git a/pkg/analysis_server/lib/src/services/completion/contribution_sorter.dart b/pkg/analysis_server/lib/src/services/completion/contribution_sorter.dart
index 3d9dd87..cc7b457 100644
--- a/pkg/analysis_server/lib/src/services/completion/contribution_sorter.dart
+++ b/pkg/analysis_server/lib/src/services/completion/contribution_sorter.dart
@@ -6,6 +6,7 @@
 
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analysis_server/src/provisional/completion/completion_dart.dart';
+import 'package:analysis_server/src/provisional/completion/completion_core.dart';
 
 /**
  * The abstract class `ContributionSorter` defines the behavior of objects
@@ -17,10 +18,10 @@
   /**
    * After [CompletionSuggestion]s have been computed,
    * this method is called to adjust the relevance of those suggestions.
-   * The compilation unit and completion node
-   * in the given completion context may not be resolved.
+   * Return an [AnalysisRequest] if more analysis is needed,
+   * or `null` if suggestion sorting is complete.
    * This method should execute quickly and not block.
    */
-  void sort(DartCompletionRequest request,
-      Iterable<CompletionSuggestion> suggestions);
+  AnalysisRequest sort(
+      CompletionRequest request, Iterable<CompletionSuggestion> suggestions);
 }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart_completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart_completion_manager.dart
index 161197d..2edb62a 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
@@ -9,7 +9,7 @@
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/provisional/completion/completion_core.dart'
-    show CompletionRequest;
+    show AnalysisRequest, CompletionRequest;
 import 'package:analysis_server/src/provisional/completion/completion_dart.dart'
     as newApi;
 import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
@@ -27,10 +27,14 @@
 import 'package:analysis_server/src/services/completion/uri_contributor.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/cancelable_future.dart';
+import 'package:analyzer/src/context/context.dart'
+    show AnalysisFutureHelper, AnalysisContextImpl;
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/engine.dart' hide AnalysisContextImpl;
 import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/task/model.dart';
 
 const int DART_RELEVANCE_COMMON_USAGE = 1200;
 const int DART_RELEVANCE_DEFAULT = 1000;
@@ -181,9 +185,11 @@
           return c.computeFast(request);
         });
       });
-      contributionSorter.sort(
-          new OldRequestWrapper(request), request.suggestions);
-
+      _processAnalysisRequest(request,
+          contributionSorter.sort(request, request.suggestions));
+      // TODO (danrubel) if request is obsolete
+      // (processAnalysisRequest returns false)
+      // then send empty results
       if (todo.isEmpty) {
         sendResults(request, todo.isEmpty);
       }
@@ -223,8 +229,11 @@
               performance.logElapseTime(completeTag);
               bool last = --count == 0;
               if (changed || last) {
-                contributionSorter.sort(
-                    new OldRequestWrapper(request), request.suggestions);
+                _processAnalysisRequest(request,
+                    contributionSorter.sort(request, request.suggestions));
+                // TODO (danrubel) if request is obsolete
+                // (processAnalysisRequest returns false)
+                // then send empty results
                 sendResults(request, last);
               }
             });
@@ -282,6 +291,38 @@
       return null;
     }, test: (e) => e is AnalysisNotScheduledError);
   }
+
+  /**
+   * Process the analysis [analysis] and any subsequent requests.
+   * Return a [Future] that returns `true`
+   * once all analysis requests have been processed
+   * or `false` if the original completion request is obsolete
+   * and processing requests was terminated before finished.
+   */
+  Future<bool> _processAnalysisRequest(
+      CompletionRequest request, AnalysisRequest analysis) {
+    // Return if no additional analysis is necessary
+    if (analysis == null) {
+      return new Future.value(true);
+    }
+
+    // Check to see if the result is already cached
+    var cachedValue = context.getResult(analysis.target, analysis.descriptor);
+    if (cachedValue != null) {
+      return _processAnalysisRequest(
+          request, analysis.callback(request, cachedValue));
+    }
+
+    // TODO (danrubel) determine when completion request is obsolete
+    // and analysis should be terminated before requesting additional analysis
+
+    // Request additional analysis
+    return new AnalysisFutureHelper((context as AnalysisContextImpl),
+        analysis.target, analysis.descriptor).computeAsync().then((value) {
+      return _processAnalysisRequest(
+          request, analysis.callback(request, cachedValue));
+    });
+  }
 }
 
 /**
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index 3fe6567..73f9bd5 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -72,6 +72,7 @@
     errorCode ==
         CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT ||
     errorCode == CompileTimeErrorCode.URI_DOES_NOT_EXIST ||
+    errorCode == HintCode.CAN_BE_NULL_AFTER_NULL_AWARE ||
     errorCode == HintCode.DEAD_CODE ||
     errorCode == HintCode.DIVISION_OPTIMIZATION ||
     errorCode == HintCode.TYPE_CHECK_IS_NOT_NULL ||
@@ -169,8 +170,8 @@
       'REMOVE_PARENTHESIS_IN_GETTER_INVOCATION',
       50,
       "Remove parentheses in getter invocation");
-  static const REMOVE_UNNECASSARY_CAST =
-      const FixKind('REMOVE_UNNECASSARY_CAST', 50, "Remove unnecessary cast");
+  static const REMOVE_UNNECESSARY_CAST =
+      const FixKind('REMOVE_UNNECESSARY_CAST', 50, "Remove unnecessary cast");
   static const REMOVE_UNUSED_CATCH_CLAUSE =
       const FixKind('REMOVE_UNUSED_CATCH', 50, "Remove unused 'catch' clause");
   static const REMOVE_UNUSED_CATCH_STACK = const FixKind(
@@ -187,6 +188,10 @@
       'REPLACE_RETURN_TYPE_FUTURE',
       50,
       "Return 'Future' from 'async' function");
+  static const REPLACE_WITH_NULL_AWARE = const FixKind(
+      'REPLACE_WITH_NULL_AWARE',
+      50,
+      "Replace the '.' with a '?.' in the invocation");
   static const USE_CONST = const FixKind('USE_CONST', 50, "Change to constant");
   static const USE_EFFECTIVE_INTEGER_DIVISION = const FixKind(
       'USE_EFFECTIVE_INTEGER_DIVISION',
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 a6f3099..d2c1f86 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -159,6 +159,9 @@
       _addFix_createPartUri();
       _addFix_replaceImportUri();
     }
+    if (errorCode == HintCode.CAN_BE_NULL_AFTER_NULL_AWARE) {
+      _addFix_canBeNullAfterNullAware();
+    }
     if (errorCode == HintCode.DEAD_CODE) {
       _addFix_removeDeadCode();
     }
@@ -445,6 +448,25 @@
     _addFix(DartFixKind.REPLACE_BOOLEAN_WITH_BOOL, []);
   }
 
+  void _addFix_canBeNullAfterNullAware() {
+    AstNode node = coveredNode;
+    if (node is Expression) {
+      AstNode parent = node.parent;
+      while (parent != null) {
+        if (parent is MethodInvocation && parent.target == node) {
+          _addReplaceEdit(rf.rangeToken(parent.operator), '?.');
+        } else if (parent is PropertyAccess && parent.target == node) {
+          _addReplaceEdit(rf.rangeToken(parent.operator), '?.');
+        } else {
+          break;
+        }
+        node = parent;
+        parent = node.parent;
+      }
+      _addFix(DartFixKind.REPLACE_WITH_NULL_AWARE, []);
+    }
+  }
+
   void _addFix_createClass() {
     Element prefixElement = null;
     String name = null;
@@ -1595,7 +1617,7 @@
     _addRemoveEdit(rf.rangeEndEnd(expression, asExpression));
     _removeEnclosingParentheses(asExpression, expressionPrecedence);
     // done
-    _addFix(DartFixKind.REMOVE_UNNECASSARY_CAST, []);
+    _addFix(DartFixKind.REMOVE_UNNECESSARY_CAST, []);
   }
 
   void _addFix_removeUnusedCatchClause() {
diff --git a/pkg/analysis_server/lib/src/services/correction/strings.dart b/pkg/analysis_server/lib/src/services/correction/strings.dart
index c2ea6cb..1689c7c 100644
--- a/pkg/analysis_server/lib/src/services/correction/strings.dart
+++ b/pkg/analysis_server/lib/src/services/correction/strings.dart
@@ -41,6 +41,17 @@
   return a.compareTo(b);
 }
 
+int countLeadingWhitespaces(String str) {
+  int i = 0;
+  for (; i < str.length; i++) {
+    int c = str.codeUnitAt(i);
+    if (!isWhitespace(c)) {
+      break;
+    }
+  }
+  return i;
+}
+
 /**
  * Counts how many times [sub] appears in [str].
  */
@@ -57,6 +68,17 @@
   return count;
 }
 
+int countTrailingWhitespaces(String str) {
+  int i = 0;
+  for (; i < str.length; i++) {
+    int c = str.codeUnitAt(str.length - 1 - i);
+    if (!isWhitespace(c)) {
+      break;
+    }
+  }
+  return i;
+}
+
 /**
  * Returns the number of characters common to the end of [a] and the start
  * of [b].
diff --git a/pkg/analysis_server/lib/src/services/correction/util.dart b/pkg/analysis_server/lib/src/services/correction/util.dart
index a74488f..434c3fe 100644
--- a/pkg/analysis_server/lib/src/services/correction/util.dart
+++ b/pkg/analysis_server/lib/src/services/correction/util.dart
@@ -78,7 +78,7 @@
 }
 
 /**
- * Climbs up [PrefixedIdentifier] and [ProperyAccess] nodes that include [node].
+ * Climbs up [PrefixedIdentifier] and [PropertyAccess] nodes that include [node].
  */
 Expression climbPropertyAccess(AstNode node) {
   while (true) {
@@ -1235,30 +1235,6 @@
   }
 
   /**
-   * @return <code>true</code> if given range of [BinaryExpression] can be extracted.
-   */
-  bool validateBinaryExpressionRange(
-      BinaryExpression binaryExpression, SourceRange range) {
-    // only parts of associative expression are safe to extract
-    if (!binaryExpression.operator.type.isAssociativeOperator) {
-      return false;
-    }
-    // prepare selected operands
-    List<Expression> operands = _getOperandsInOrderFor(binaryExpression);
-    List<Expression> subOperands = _getOperandsForSourceRange(operands, range);
-    // if empty, then something wrong with selection
-    if (subOperands.isEmpty) {
-      return false;
-    }
-    // may be some punctuation included into selection - operators, braces, etc
-    if (_selectionIncludesNonWhitespaceOutsideOperands(range, subOperands)) {
-      return false;
-    }
-    // OK
-    return true;
-  }
-
-  /**
    * @return the [ImportElement] used to import given [Element] into [library].
    *         May be `null` if was not imported, i.e. declared in the same library.
    */
@@ -1344,11 +1320,12 @@
     }
     if (expression is ParenthesizedExpression) {
       ParenthesizedExpression pe = expression;
-      Expression innerExpresion = pe.expression;
-      while (innerExpresion is ParenthesizedExpression) {
-        innerExpresion = (innerExpresion as ParenthesizedExpression).expression;
+      Expression innerExpression = pe.expression;
+      while (innerExpression is ParenthesizedExpression) {
+        innerExpression =
+            (innerExpression as ParenthesizedExpression).expression;
       }
-      return _invertCondition0(innerExpresion);
+      return _invertCondition0(innerExpression);
     }
     DartType type = expression.bestType;
     if (type.displayName == "bool") {
@@ -1369,12 +1346,6 @@
     return true;
   }
 
-  bool _selectionIncludesNonWhitespaceOutsideOperands(
-      SourceRange selection, List<Expression> operands) {
-    return _selectionIncludesNonWhitespaceOutsideRange(
-        selection, rangeNodes(operands));
-  }
-
   /**
    * @return <code>true</code> if "selection" covers "range" and there are any non-whitespace tokens
    *         between "selection" and "range" start/end.
@@ -1396,66 +1367,6 @@
     // only whitespace in selection around range
     return false;
   }
-
-  /**
-   * @return [Expression]s from <code>operands</code> which are completely covered by given
-   *         [SourceRange]. Range should start and end between given [Expression]s.
-   */
-  static List<Expression> _getOperandsForSourceRange(
-      List<Expression> operands, SourceRange range) {
-    assert(!operands.isEmpty);
-    List<Expression> subOperands = [];
-    // track range enter/exit
-    bool entered = false;
-    bool exited = false;
-    // may be range starts before or on first operand
-    if (range.offset <= operands[0].offset) {
-      entered = true;
-    }
-    // iterate over gaps between operands
-    for (int i = 0; i < operands.length - 1; i++) {
-      Expression operand = operands[i];
-      Expression nextOperand = operands[i + 1];
-      SourceRange inclusiveGap =
-          rangeEndStart(operand, nextOperand).getMoveEnd(1);
-      // add operand, if already entered range
-      if (entered) {
-        subOperands.add(operand);
-        // may be last operand in range
-        if (range.endsIn(inclusiveGap)) {
-          exited = true;
-        }
-      } else {
-        // may be first operand in range
-        if (range.startsIn(inclusiveGap)) {
-          entered = true;
-        }
-      }
-    }
-    // check if last operand is in range
-    Expression lastGroupMember = operands[operands.length - 1];
-    if (range.end == lastGroupMember.end) {
-      subOperands.add(lastGroupMember);
-      exited = true;
-    }
-    // we expect that range covers only given operands
-    if (!exited) {
-      return [];
-    }
-    // done
-    return subOperands;
-  }
-
-  /**
-   * @return all operands of the given [BinaryExpression] and its children with the same
-   *         operator.
-   */
-  static List<Expression> _getOperandsInOrderFor(BinaryExpression groupRoot) {
-    List<Expression> operands = [];
-    TokenType groupOperatorType = groupRoot.operator.type;
-    groupRoot.accept(new _OrderedOperandsVisitor(groupOperatorType, operands));
-    return operands;
-  }
 }
 
 /**
@@ -1547,7 +1458,7 @@
 
   static _InvertedCondition _binary2(
       _InvertedCondition left, String operation, _InvertedCondition right) {
-    // TODO(scheglov) conside merging with "_binary()" after testing
+    // TODO(scheglov) consider merging with "_binary()" after testing
     return new _InvertedCondition(
         1 << 20, "${left._source}${operation}${right._source}");
   }
@@ -1567,19 +1478,3 @@
   static _InvertedCondition _simple(String source) =>
       new _InvertedCondition(2147483647, source);
 }
-
-class _OrderedOperandsVisitor extends GeneralizingAstVisitor {
-  final TokenType groupOperatorType;
-  final List<Expression> operands;
-
-  _OrderedOperandsVisitor(this.groupOperatorType, this.operands);
-
-  @override
-  Object visitExpression(Expression node) {
-    if (node is BinaryExpression && node.operator.type == groupOperatorType) {
-      return super.visitNode(node);
-    }
-    operands.add(node);
-    return null;
-  }
-}
diff --git a/pkg/analysis_server/lib/src/services/linter/linter.dart b/pkg/analysis_server/lib/src/services/linter/linter.dart
index 87692ea..675836ce 100644
--- a/pkg/analysis_server/lib/src/services/linter/linter.dart
+++ b/pkg/analysis_server/lib/src/services/linter/linter.dart
@@ -4,11 +4,10 @@
 
 library services.src.linter;
 
-import 'package:analyzer/plugin/options.dart';
 import 'package:analyzer/analyzer.dart';
-import 'package:yaml/yaml.dart';
+import 'package:analyzer/plugin/options.dart';
 import 'package:linter/src/rules.dart';
-import 'package:linter/src/linter.dart';
+import 'package:yaml/yaml.dart';
 
 /**
  * An error code indicating an undefined lint rule.
@@ -18,7 +17,7 @@
  */
 const AnalysisOptionsWarningCode UNDEFINED_LINT_WARNING =
     const AnalysisOptionsWarningCode(
-        'UNDEFINED_LINT_WARNING', "Undefined lint rule '{0}'");
+        'UNDEFINED_LINT_WARNING', "'{0}' is not a recognized lint rule");
 
 /// Validates `linter` rule configurations.
 class LinterRuleOptionsValidator extends OptionsValidator {
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
index 6cfd951..c865aec 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
@@ -40,6 +40,8 @@
 
   String name;
   bool extractAll = true;
+  final List<int> coveringExpressionOffsets = <int>[];
+  final List<int> coveringExpressionLengths = <int>[];
   final List<String> names = <String>[];
   final List<int> offsets = <int>[];
   final List<int> lengths = <int>[];
@@ -178,19 +180,58 @@
 
   /**
    * Checks if [selectionRange] selects [Expression] which can be extracted, and
-   * location of this [DartExpression] in AST allows extracting.
+   * location of this [Expression] in AST allows extracting.
    */
   RefactoringStatus _checkSelection() {
-    _ExtractExpressionAnalyzer _selectionAnalyzer =
-        new _ExtractExpressionAnalyzer(selectionRange);
-    unit.accept(_selectionAnalyzer);
-    AstNode coveringNode = _selectionAnalyzer.coveringNode;
-    // may be fatal error
+    String selectionStr;
+    // exclude whitespaces
     {
-      RefactoringStatus status = _selectionAnalyzer.status;
-      if (status.hasFatalError) {
-        return status;
+      selectionStr = utils.getRangeText(selectionRange);
+      int numLeading = countLeadingWhitespaces(selectionStr);
+      int numTrailing = countTrailingWhitespaces(selectionStr);
+      int offset = selectionRange.offset + numLeading;
+      int end = selectionRange.end - numTrailing;
+      selectionRange = new SourceRange(offset, end - offset);
+    }
+    // get covering node
+    AstNode coveringNode = new NodeLocator(
+        selectionRange.offset, selectionRange.end).searchWithin(unit);
+    // compute covering expressions
+    for (AstNode node = coveringNode; node is Expression; node = node.parent) {
+      AstNode parent = node.parent;
+      // cannot extract the name part of a property access
+      if (parent is PrefixedIdentifier && parent.identifier == node ||
+          parent is PropertyAccess && parent.propertyName == node) {
+        continue;
       }
+      // fatal selection problems
+      if (coveringExpressionOffsets.isEmpty) {
+        if (node is SimpleIdentifier) {
+          Element element = node.bestElement;
+          if (element is FunctionElement || element is MethodElement) {
+            return new RefactoringStatus.fatal(
+                'Cannot extract a single method name.',
+                newLocation_fromNode(node));
+          }
+          if (node.inDeclarationContext()) {
+            return new RefactoringStatus.fatal(
+                'Cannot extract the name part of a declaration.',
+                newLocation_fromNode(node));
+          }
+        }
+        if (parent is AssignmentExpression && parent.leftHandSide == node) {
+          return new RefactoringStatus.fatal(
+              'Cannot extract the left-hand side of an assignment.',
+              newLocation_fromNode(node));
+        }
+      }
+      // set selected expression
+      if (coveringExpressionOffsets.isEmpty) {
+        rootExpression = node;
+      }
+      // add the expression range
+      coveringExpressionOffsets.add(node.offset);
+      coveringExpressionLengths.add(node.length);
     }
     // we need enclosing block to add variable declaration statement
     if (coveringNode == null ||
@@ -201,38 +242,18 @@
     }
     // part of string literal
     if (coveringNode is StringLiteral) {
-      stringLiteralPart = utils.getRangeText(selectionRange);
-      if (stringLiteralPart.startsWith("'") ||
-          stringLiteralPart.startsWith('"') ||
-          stringLiteralPart.endsWith("'") ||
-          stringLiteralPart.endsWith('"')) {
-        return new RefactoringStatus.fatal(
-            'Cannot extract only leading or trailing quote of string literal.');
+      if (selectionRange.offset > coveringNode.offset &&
+          selectionRange.end < coveringNode.end) {
+        stringLiteralPart = selectionStr;
+        return new RefactoringStatus();
       }
-      return new RefactoringStatus();
     }
     // single node selected
-    if (_selectionAnalyzer.selectedNodes.length == 1 &&
-        !utils.selectionIncludesNonWhitespaceOutsideNode(
-            selectionRange, _selectionAnalyzer.firstSelectedNode)) {
-      AstNode selectedNode = _selectionAnalyzer.firstSelectedNode;
-      if (selectedNode is Expression) {
-        rootExpression = selectedNode;
-        singleExpression = rootExpression;
-        wholeStatementExpression =
-            singleExpression.parent is ExpressionStatement;
-        return new RefactoringStatus();
-      }
-    }
-    // fragment of binary expression selected
-    if (coveringNode is BinaryExpression) {
-      BinaryExpression binaryExpression = coveringNode;
-      if (utils.validateBinaryExpressionRange(
-          binaryExpression, selectionRange)) {
-        rootExpression = binaryExpression;
-        singleExpression = null;
-        return new RefactoringStatus();
-      }
+    if (rootExpression != null) {
+      singleExpression = rootExpression;
+      selectionRange = rangeNode(singleExpression);
+      wholeStatementExpression = singleExpression.parent is ExpressionStatement;
+      return new RefactoringStatus();
     }
     // invalid selection
     return new RefactoringStatus.fatal(
@@ -259,7 +280,7 @@
    * Returns an [Element]-sensitive encoding of [tokens].
    * Each [Token] with a [LocalVariableElement] has a suffix of the element id.
    *
-   * So, we can distingush different local variables with the same name, if
+   * So, we can distinguish different local variables with the same name, if
    * there are multiple variables with the same name are declared in the
    * function we are searching occurrences in.
    */
@@ -475,7 +496,7 @@
   }
 
   /**
-   * Records fatal error with given message and [Locatiom].
+   * Records fatal error with given [message] and [location].
    */
   void _invalidSelection(String message, Location location) {
     status.addFatalError(message, location);
@@ -523,7 +544,7 @@
   @override
   Object visitStringLiteral(StringLiteral node) {
     if (ref.stringLiteralPart != null) {
-      int occuLength = ref.stringLiteralPart.length;
+      int length = ref.stringLiteralPart.length;
       String value = ref.utils.getNodeText(node);
       int lastIndex = 0;
       while (true) {
@@ -531,10 +552,10 @@
         if (index == -1) {
           break;
         }
-        lastIndex = index + occuLength;
-        int occuStart = node.offset + index;
-        SourceRange occuRange = rangeStartLength(occuStart, occuLength);
-        occurrences.add(occuRange);
+        lastIndex = index + length;
+        int start = node.offset + index;
+        SourceRange range = rangeStartLength(start, length);
+        occurrences.add(range);
       }
       return null;
     }
@@ -560,8 +581,8 @@
     List<Token> nodeTokens = TokenUtils.getTokens(nodeSource);
     nodeSource = ref._encodeExpressionTokens(node, nodeTokens);
     if (nodeSource == selectionSource) {
-      SourceRange occuRange = rangeNode(node);
-      _addOccurrence(occuRange);
+      SourceRange range = rangeNode(node);
+      _addOccurrence(range);
     }
   }
 
@@ -587,10 +608,10 @@
       Token startToken = nodeTokens[startTokenIndex];
       Token endToken = nodeTokens[endTokenIndex];
       // add occurrence range
-      int occuStart = nodeOffset + startToken.offset;
-      int occuEnd = nodeOffset + endToken.end;
-      SourceRange occuRange = rangeStartEnd(occuStart, occuEnd);
-      _addOccurrence(occuRange);
+      int start = nodeOffset + startToken.offset;
+      int end = nodeOffset + endToken.end;
+      SourceRange range = rangeStartEnd(start, end);
+      _addOccurrence(range);
     }
   }
 }
diff --git a/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart b/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
index a4d3c6b..baeab25 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
@@ -72,6 +72,18 @@
   }
 
   /**
+   * The lengths of the expressions that cover the specified selection,
+   * from the down most to the up most.
+   */
+  List<int> get coveringExpressionLengths;
+
+  /**
+   * The offsets of the expressions that cover the specified selection,
+   * from the down most to the up most.
+   */
+  List<int> get coveringExpressionOffsets;
+
+  /**
    * True if all occurrences of the expression within the scope in which the
    * variable will be defined should be replaced by a reference to the local
    * variable. The expression used to initiate the refactoring will always be
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
index 00fa3b9..12d8aee 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
@@ -102,7 +102,6 @@
       }
       // ignore references from SDK and pub cache
       if (isElementInSdkOrPubCache(reference.element)) {
-        print('ignore: $reference');
         continue;
       }
       // check the element being renamed is accessible
diff --git a/pkg/analysis_server/lib/src/status/get_handler.dart b/pkg/analysis_server/lib/src/status/get_handler.dart
index a83d95e..8aa840a 100644
--- a/pkg/analysis_server/lib/src/status/get_handler.dart
+++ b/pkg/analysis_server/lib/src/status/get_handler.dart
@@ -515,7 +515,7 @@
           //
           // Write task model timing information.
           //
-          buffer.write('<p><b>Task performace data</b></p>');
+          buffer.write('<p><b>Task performance data</b></p>');
           buffer.write(
               '<table style="border-collapse: separate; border-spacing: 10px 5px;">');
           _writeRow(
@@ -557,51 +557,6 @@
               classes: [null, "right", "right", "right"]);
           buffer.write('</table>');
         });
-        //
-        // Write task model inputs timing information.
-        //
-        {
-          buffer.write('<p><b>Task inputs performace data</b></p>');
-          buffer.write(
-              '<table style="border-collapse: separate; border-spacing: 10px 5px;">');
-          _writeRow(
-              buffer,
-              [
-                'Task Name',
-                'Count',
-                'Total Time (in ms)',
-                'Average Time (in ms)'
-              ],
-              header: true);
-
-          Map<TaskDescriptor, int> countMap = WorkItem.countMap;
-          Map<TaskDescriptor, Stopwatch> stopwatchMap = WorkItem.stopwatchMap;
-          List<TaskDescriptor> taskClasses = stopwatchMap.keys.toList();
-          taskClasses.sort((TaskDescriptor first, TaskDescriptor second) {
-            String firstName = first.name;
-            String secondName = second.name;
-            return firstName.compareTo(secondName);
-          });
-          taskClasses.forEach((TaskDescriptor descriptor) {
-            int count = countMap[descriptor];
-            if (count == null) {
-              count = 0;
-            }
-            int taskTime = stopwatchMap[descriptor].elapsedMilliseconds;
-            _writeRow(buffer, [
-              descriptor.name,
-              count,
-              taskTime,
-              count <= 0 ? '-' : (taskTime / count).toStringAsFixed(3)
-            ], classes: [
-              null,
-              "right",
-              "right",
-              "right"
-            ]);
-          });
-          buffer.write('</table>');
-        }
       });
     });
   }
@@ -1558,6 +1513,12 @@
     }
   }
 
+  void _writeListItem(StringBuffer buffer, writer()) {
+    buffer.write('<li>');
+    writer();
+    buffer.write('</li>');
+  }
+
   void _writeListOfStrings(
       StringBuffer buffer, String listName, Iterable<String> items) {
     List<String> itemList = items.toList();
@@ -1566,12 +1527,12 @@
       b = b.toLowerCase();
       return a.compareTo(b);
     });
-    buffer.write('List "listName" containing ${itemList.length} entries:');
+    buffer.write('List "$listName" containing ${itemList.length} entries:');
     buffer.write('<ul>');
     for (String member in itemList) {
-      buffer.write('<li>');
-      buffer.write(member);
-      buffer.write('</li>');
+      _writeListItem(buffer, () {
+        buffer.write(member);
+      });
     }
     buffer.write('</ul>');
   }
@@ -1769,6 +1730,9 @@
       buffer.write('<br>');
       buffer.write('Version: ');
       buffer.write(AnalysisServer.VERSION);
+      buffer.write('<br>');
+      buffer.write('Process ID: ');
+      buffer.write(pid);
       buffer.write('</p>');
 
       buffer.write('<p><b>Performance Data</b></p>');
@@ -1929,9 +1893,9 @@
       buffer.write('List containing ${value.length} entries');
       buffer.write('<ul>');
       for (var entry in value) {
-        buffer.write('<li>');
-        _writeValueAsHtml(buffer, entry, linkParameters);
-        buffer.write('</li>');
+        _writeListItem(buffer, () {
+          _writeValueAsHtml(buffer, entry, linkParameters);
+        });
       }
       buffer.write('</ul>');
     } else if (value is AstNode) {
@@ -1944,19 +1908,24 @@
       buffer.write('<i>$link</i>');
     } else if (value is UsedLocalElements) {
       buffer.write('<ul>');
-      {
+      _writeListItem(buffer, () {
         HashSet<Element> elements = value.elements;
         buffer.write('List "elements" containing ${elements.length} entries');
         buffer.write('<ul>');
         for (Element element in elements) {
-          buffer.write('<li>');
-          buffer.write('<i>${element.runtimeType}</i>  $element');
-          buffer.write('</li>');
+          _writeListItem(buffer, () {
+            String elementStr = HTML_ESCAPE.convert(element.toString());
+            buffer.write('<i>${element.runtimeType}</i>  $elementStr');
+          });
         }
         buffer.write('</ul>');
-      }
-      _writeListOfStrings(buffer, 'members', value.members);
-      _writeListOfStrings(buffer, 'readMembers', value.readMembers);
+      });
+      _writeListItem(buffer, () {
+        _writeListOfStrings(buffer, 'members', value.members);
+      });
+      _writeListItem(buffer, () {
+        _writeListOfStrings(buffer, 'readMembers', value.readMembers);
+      });
       buffer.write('</ul>');
     } else {
       buffer.write(HTML_ESCAPE.convert(value.toString()));
diff --git a/pkg/analysis_server/pubspec.yaml b/pkg/analysis_server/pubspec.yaml
index 3f53b5b..951b5b4 100644
--- a/pkg/analysis_server/pubspec.yaml
+++ b/pkg/analysis_server/pubspec.yaml
@@ -6,7 +6,7 @@
 environment:
   sdk: '>=1.12.0 <2.0.0'
 dependencies:
-  analyzer: '>=0.26.1+16 <0.27.0'
+  analyzer: '>=0.26.2+1 <0.27.0'
   args: '>=0.13.0 <0.14.0'
   dart_style: '>=0.2.0 <0.3.0'
   linter: ^0.1.3+2
diff --git a/pkg/analysis_server/test/analysis/get_errors_test.dart b/pkg/analysis_server/test/analysis/get_errors_test.dart
index 65a524a4..205cbbe 100644
--- a/pkg/analysis_server/test/analysis/get_errors_test.dart
+++ b/pkg/analysis_server/test/analysis/get_errors_test.dart
@@ -8,7 +8,6 @@
 
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analysis_server/src/domain_analysis.dart';
-import 'package:analyzer/file_system/file_system.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
 
@@ -100,10 +99,7 @@
     Request request = _createGetErrorsRequest();
     server.handleRequest(request);
     // remove context, causes sending an "invalid file" error
-    {
-      Folder projectFolder = resourceProvider.getResource(projectPath);
-      server.contextManager.callbacks.removeContext(projectFolder, <String>[]);
-    }
+    resourceProvider.deleteFolder(projectPath);
     // wait for an error response
     return serverChannel.waitForResponse(request).then((Response response) {
       expect(response.error, isNotNull);
diff --git a/pkg/analysis_server/test/analysis/navigation_collector_test.dart b/pkg/analysis_server/test/analysis/navigation_collector_test.dart
new file mode 100644
index 0000000..e0f118f
--- /dev/null
+++ b/pkg/analysis_server/test/analysis/navigation_collector_test.dart
@@ -0,0 +1,80 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.analysis.navigation_collector;
+
+import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analysis_server/src/domains/analysis/navigation.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../utils.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(NavigationCollectorImplTest);
+}
+
+@reflectiveTest
+class NavigationCollectorImplTest {
+  NavigationCollectorImpl collector = new NavigationCollectorImpl();
+
+  void test_multipleTargets() {
+    collector.addRegion(
+        10, 5, ElementKind.CLASS, new Location('file', 11, 12, 13, 14));
+    collector.addRegion(
+        10, 5, ElementKind.CLASS, new Location('file', 21, 22, 23, 24));
+    collector.createRegions();
+    List<NavigationRegion> regions = collector.regions;
+    expect(regions, hasLength(1));
+    {
+      NavigationRegion region = regions[0];
+      expect(region.offset, 10);
+      expect(region.length, 5);
+      expect(region.targets, hasLength(2));
+      {
+        NavigationTarget target = collector.targets[region.targets[0]];
+        expect(target.offset, 11);
+        expect(target.length, 12);
+      }
+      {
+        NavigationTarget target = collector.targets[region.targets[1]];
+        expect(target.offset, 21);
+        expect(target.length, 22);
+      }
+    }
+  }
+
+  void test_unique() {
+    collector.addRegion(
+        100, 10, ElementKind.CLASS, new Location('file', 11, 12, 13, 14));
+    collector.addRegion(
+        200, 20, ElementKind.CLASS, new Location('file', 21, 22, 23, 24));
+    collector.createRegions();
+    List<NavigationRegion> regions = collector.regions;
+    expect(regions, hasLength(2));
+    {
+      NavigationRegion region = regions[0];
+      expect(region.offset, 100);
+      expect(region.length, 10);
+      expect(region.targets, hasLength(1));
+      {
+        NavigationTarget target = collector.targets[region.targets[0]];
+        expect(target.offset, 11);
+        expect(target.length, 12);
+      }
+    }
+    {
+      NavigationRegion region = regions[1];
+      expect(region.offset, 200);
+      expect(region.length, 20);
+      expect(region.targets, hasLength(1));
+      {
+        NavigationTarget target = collector.targets[region.targets[0]];
+        expect(target.offset, 21);
+        expect(target.length, 22);
+      }
+    }
+  }
+}
diff --git a/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart b/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart
index 1d4c9d1..966559b 100644
--- a/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart
@@ -43,6 +43,8 @@
 
   AnalysisContext get testContext => server.getContainingContext(testFile);
 
+  List<AnalysisError> get testFileErrors => filesErrors[testFile];
+
   void addOptionsFile(String contents) {
     addFile(optionsFilePath, contents);
   }
@@ -83,9 +85,74 @@
   @override
   void tearDown() {
     AnalysisEngine.instance.useTaskModel = wasTaskModelEnabled;
+    filesErrors[optionsFilePath] = [];
+    filesErrors[testFile] = [];
     super.tearDown();
   }
 
+  test_error_filter() async {
+    addOptionsFile('''
+analyzer:
+  errors:
+    unused_local_variable: ignore
+''');
+
+    addTestFile('''
+main() {
+  String unused = "";
+}
+''');
+
+    setAnalysisRoot();
+
+    await waitForTasksFinished();
+
+    // Verify options file.
+    expect(optionsFileErrors, hasLength(0));
+
+    // Verify test file.
+    expect(testFileErrors, hasLength(0));
+  }
+
+  test_error_filter_removed() async {
+    addOptionsFile('''
+analyzer:
+  errors:
+    unused_local_variable: ignore
+''');
+
+    addTestFile('''
+main() {
+  String unused = "";
+}
+''');
+
+    setAnalysisRoot();
+
+    await waitForTasksFinished();
+
+    // Verify options file.
+    expect(optionsFileErrors, hasLength(0));
+
+    // Verify test file.
+    expect(testFileErrors, hasLength(0));
+
+    addOptionsFile('''
+analyzer:
+  errors:
+  #  unused_local_variable: ignore
+''');
+
+    await pumpEventQueue();
+    await waitForTasksFinished();
+
+    // Verify options file.
+    expect(optionsFileErrors, hasLength(0));
+
+    // Verify test file.
+    expect(testFileErrors, hasLength(1));
+  }
+
   test_lint_options_changes() async {
     addOptionsFile('''
 linter:
@@ -185,7 +252,7 @@
     verifyStrongMode(enabled: false);
   }
 
-  test_strong_mode_changed() async {
+  test_strong_mode_changed_off() async {
     setStrongMode(true);
 
     addTestFile(testSource);
@@ -206,6 +273,24 @@
     verifyStrongMode(enabled: false);
   }
 
+  test_strong_mode_changed_on() async {
+    setStrongMode(false);
+
+    addTestFile(testSource);
+    setAnalysisRoot();
+
+    await waitForTasksFinished();
+
+    verifyStrongMode(enabled: false);
+
+    setStrongMode(true);
+
+    await pumpEventQueue();
+    await waitForTasksFinished();
+
+    verifyStrongMode(enabled: true);
+  }
+
   void verifyLintsEnabled(List<String> lints) {
     expect(testContext.analysisOptions.lint, true);
     var rules = getLints(testContext).map((rule) => rule.name);
diff --git a/pkg/analysis_server/test/analysis/set_priority_files_test.dart b/pkg/analysis_server/test/analysis/set_priority_files_test.dart
index 8626ef8..770a036 100644
--- a/pkg/analysis_server/test/analysis/set_priority_files_test.dart
+++ b/pkg/analysis_server/test/analysis/set_priority_files_test.dart
@@ -6,6 +6,9 @@
 
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analysis_server/src/domain_analysis.dart';
+import 'package:analyzer/src/generated/engine.dart'
+    show InternalAnalysisContext;
+import 'package:analyzer/src/generated/source.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
 
@@ -35,15 +38,30 @@
 
   test_fileInAnalysisRoot() async {
     addTestFile('');
+    // wait for analysis to ensure that the file is known to the context
+    await server.onAnalysisComplete;
+    // set priority files
     Response response = await _setPriorityFile(testFile);
     expect(response, isResponseSuccess('0'));
+    // verify
+    InternalAnalysisContext context = server.getContainingContext(testFile);
+    List<Source> prioritySources = context.prioritySources;
+    expect(prioritySources, hasLength(1));
+    expect(prioritySources.first.fullName, testFile);
   }
 
   test_fileInSdk() async {
     addTestFile('');
     await server.onAnalysisComplete;
-    Response response = await _setPriorityFile('/lib/convert/convert.dart');
+    // set priority files
+    String filePath = '/lib/convert/convert.dart';
+    Response response = await _setPriorityFile(filePath);
     expect(response, isResponseSuccess('0'));
+    // verify
+    InternalAnalysisContext sdkContext = server.defaultSdk.context;
+    List<Source> prioritySources = sdkContext.prioritySources;
+    expect(prioritySources, hasLength(1));
+    expect(prioritySources.first.fullName, filePath);
   }
 
   test_fileNotInAnalysisRoot() async {
diff --git a/pkg/analysis_server/test/analysis/test_all.dart b/pkg/analysis_server/test/analysis/test_all.dart
index 05b49f3d..a0cd6d3 100644
--- a/pkg/analysis_server/test/analysis/test_all.dart
+++ b/pkg/analysis_server/test/analysis/test_all.dart
@@ -9,7 +9,9 @@
 import 'get_errors_test.dart' as get_errors_test;
 import 'get_hover_test.dart' as get_hover_test;
 import 'get_navigation_test.dart' as get_navigation_test;
-import 'notification_analysis_options_test.dart' as notification_analysis_options_test;
+import 'navigation_collector_test.dart' as navigation_collector_test;
+import 'notification_analysis_options_test.dart'
+    as notification_analysis_options_test;
 import 'notification_analyzedFiles_test.dart'
     as notification_analyzedFiles_test;
 import 'notification_errors_test.dart' as notification_errors_test;
@@ -32,6 +34,7 @@
     get_errors_test.main();
     get_hover_test.main();
     get_navigation_test.main();
+    navigation_collector_test.main();
     notification_analysis_options_test.main();
     notification_analyzedFiles_test.main();
     notification_errors_test.main();
diff --git a/pkg/analysis_server/test/analysis_server_test.dart b/pkg/analysis_server/test/analysis_server_test.dart
index d964390..5275d3a 100644
--- a/pkg/analysis_server/test/analysis_server_test.dart
+++ b/pkg/analysis_server/test/analysis_server_test.dart
@@ -242,20 +242,15 @@
     String dir1Path = '/dir1';
     String dir2Path = dir1Path + '/dir2';
     String filePath = dir2Path + '/file.dart';
-    Folder dir1 = resourceProvider.newFolder(dir1Path);
-    Folder dir2 = resourceProvider.newFolder(dir2Path);
+    resourceProvider.newFile('$dir1Path/.packages', '');
+    resourceProvider.newFile('$dir2Path/.packages', '');
     resourceProvider.newFile(filePath, 'library lib;');
-
-    AnalysisContext context1 = AnalysisEngine.instance.createAnalysisContext();
-    AnalysisContext context2 = AnalysisEngine.instance.createAnalysisContext();
-    _configureSourceFactory(context1);
-    _configureSourceFactory(context2);
-    server.folderMap[dir1] = context1;
-    server.folderMap[dir2] = context2;
-
+    // create contexts
+    server.setAnalysisRoots('0', [dir1Path], [], {});
+    // get pair
     ContextSourcePair pair = server.getContextSourcePair(filePath);
     Source source = pair.source;
-    expect(pair.context, same(context2));
+    _assertContextOfFolder(pair.context, dir2Path);
     expect(source, isNotNull);
     expect(source.uri.scheme, 'file');
     expect(source.fullName, filePath);
@@ -284,14 +279,12 @@
     packageMapProvider.packageMap = <String, List<Folder>>{
       'my_package': <Folder>[rootFolder]
     };
-
-    AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
-    _configureSourceFactory(context);
-    server.folderMap[rootFolder] = context;
-
+    // create contexts
+    server.setAnalysisRoots('0', [rootPath], [], {});
+    // get pair
     ContextSourcePair pair = server.getContextSourcePair(filePath);
     Source source = pair.source;
-    expect(pair.context, same(context));
+    _assertContextOfFolder(pair.context, rootPath);
     expect(source, isNotNull);
     expect(source.uri.scheme, 'package');
     expect(source.fullName, filePath);
@@ -300,16 +293,13 @@
   test_getContextSourcePair_simple() {
     String dirPath = '/dir';
     String filePath = dirPath + '/file.dart';
-    Folder dir = resourceProvider.newFolder(dirPath);
     resourceProvider.newFile(filePath, 'library lib;');
-
-    AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
-    _configureSourceFactory(context);
-    server.folderMap[dir] = context;
-
+    // create contexts
+    server.setAnalysisRoots('0', [dirPath], [], {});
+    // get pair
     ContextSourcePair pair = server.getContextSourcePair(filePath);
     Source source = pair.source;
-    expect(pair.context, same(context));
+    _assertContextOfFolder(pair.context, dirPath);
     expect(source, isNotNull);
     expect(source.uri.scheme, 'file');
     expect(source.fullName, filePath);
@@ -484,6 +474,37 @@
     });
   }
 
+  test_watch_modifyFile_hasOverlay() async {
+    server.serverServices.add(ServerService.STATUS);
+    // configure the project
+    String projectPath = '/root';
+    String filePath = '/root/test.dart';
+    resourceProvider.newFolder(projectPath);
+    resourceProvider.newFile(filePath, '// 111');
+    server.setAnalysisRoots('0', ['/root'], [], {});
+    await pumpEventQueue();
+    // add overlay
+    server.updateContent('1', {filePath: new AddContentOverlay('// 222')});
+    await pumpEventQueue();
+    // update the file
+    channel.notificationsReceived.clear();
+    resourceProvider.modifyFile(filePath, '// 333');
+    await pumpEventQueue();
+    // the file has an overlay, so the file-system change was ignored
+    expect(channel.notificationsReceived.any((notification) {
+      return notification.event == SERVER_STATUS;
+    }), isFalse);
+  }
+
+  void _assertContextOfFolder(
+      AnalysisContext context, String expectedFolderPath) {
+    Folder expectedFolder = resourceProvider.newFolder(expectedFolderPath);
+    ContextInfo expectedContextInfo = (server.contextManager
+        as ContextManagerImpl).getContextInfoFor(expectedFolder);
+    expect(expectedContextInfo, isNotNull);
+    expect(context, same(expectedContextInfo.context));
+  }
+
   void _configureSourceFactory(AnalysisContext context) {
     var resourceUriResolver = new ResourceUriResolver(resourceProvider);
     var packageUriResolver = new PackageMapUriResolver(
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index 081c8b6..dd3961c 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -10,7 +10,9 @@
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/source/embedder.dart';
 import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:package_config/packages.dart';
@@ -91,6 +93,80 @@
     resourceProvider.newFolder(projPath);
   }
 
+  test_embedder_options() async {
+    // Create files.
+    String libPath = newFolder([projPath, LIB_NAME]);
+    String sdkExtPath = newFolder([projPath, 'sdk_ext']);
+    newFile([projPath, 'test', 'test.dart']);
+    newFile([sdkExtPath, 'entry.dart']);
+    // Setup _embedder.yaml.
+    newFile(
+        [libPath, '_embedder.yaml'],
+        r'''
+embedder_libs:
+  "dart:foobar": "../sdk_ext/entry.dart"
+analyzer:
+  strong-mode: true
+  language:
+    enableSuperMixins: true
+''');
+    // Setup .packages file
+    newFile(
+        [projPath, '.packages'],
+        r'''
+test_pack:lib/''');
+
+    // Setup .analysis_options
+    newFile(
+        [projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE],
+        r'''
+analyzer:
+  exclude:
+    - 'test/**'
+  language:
+    enableGenericMethods: true
+  errors:
+    unused_local_variable: false
+''');
+
+    // Setup context.
+    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+    await pumpEventQueue();
+
+    // Confirm that one context was created.
+    var contexts =
+        manager.contextsInAnalysisRoot(resourceProvider.newFolder(projPath));
+    expect(contexts, isNotNull);
+    expect(contexts, hasLength(1));
+    var context = contexts[0];
+
+    // Verify options.
+    //   * from `_embedder.yaml`:
+    expect(context.analysisOptions.strongMode, isTrue);
+    expect(context.analysisOptions.enableSuperMixins, isTrue);
+    //   * from `.analysis_options`:
+    expect(context.analysisOptions.enableGenericMethods, isTrue);
+    //     verify tests are excluded
+    expect(callbacks.currentContextFilePaths[projPath].keys,
+        ['/my/proj/sdk_ext/entry.dart']);
+
+    // Verify filter setup.
+    List<ErrorFilter> filters =
+        callbacks.currentContext.getConfigurationData(CONFIGURED_ERROR_FILTERS);
+    expect(filters, hasLength(1));
+    expect(
+        filters.first(new AnalysisError(
+            new TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [
+          ['x']
+        ])),
+        isTrue);
+
+    // Sanity check embedder libs.
+    var source = context.sourceFactory.forUri('dart:foobar');
+    expect(source, isNotNull);
+    expect(source.fullName, '/my/proj/sdk_ext/entry.dart');
+  }
+
   test_analysis_options_parse_failure() async {
     // Create files.
     String libPath = newFolder([projPath, LIB_NAME]);
@@ -136,6 +212,146 @@
     expect(contexts, contains(subProjContextInfo.context));
   }
 
+  test_embedder_packagespec() async {
+    // Create files.
+    String libPath = newFolder([projPath, LIB_NAME]);
+    newFile([libPath, 'main.dart']);
+    newFile([libPath, 'nope.dart']);
+    String sdkExtPath = newFolder([projPath, 'sdk_ext']);
+    newFile([sdkExtPath, 'entry.dart']);
+    String sdkExtSrcPath = newFolder([projPath, 'sdk_ext', 'src']);
+    newFile([sdkExtSrcPath, 'part.dart']);
+    // Setup _embedder.yaml.
+    newFile(
+        [libPath, '_embedder.yaml'],
+        r'''
+embedder_libs:
+  "dart:foobar": "../sdk_ext/entry.dart"
+  "dart:typed_data": "../sdk_ext/src/part"
+  ''');
+    // Setup .packages file
+    newFile(
+        [projPath, '.packages'],
+        r'''
+test_pack:lib/''');
+    // Setup context.
+
+    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+    await pumpEventQueue();
+    // Confirm that one context was created.
+    var contexts =
+        manager.contextsInAnalysisRoot(resourceProvider.newFolder(projPath));
+    expect(contexts, isNotNull);
+    expect(contexts.length, equals(1));
+    var context = contexts[0];
+    var source = context.sourceFactory.forUri('dart:foobar');
+    expect(source, isNotNull);
+    expect(source.fullName, equals('/my/proj/sdk_ext/entry.dart'));
+    // We can't find dart:core because we didn't list it in our
+    // embedder_libs map.
+    expect(context.sourceFactory.forUri('dart:core'), isNull);
+    // We can find dart:typed_data because we listed it in our
+    // embedder_libs map.
+    expect(context.sourceFactory.forUri('dart:typed_data'), isNotNull);
+  }
+
+  test_error_filter_analysis_option() async {
+    // Create files.
+    newFile(
+        [projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE],
+        r'''
+analyzer:
+  errors:
+    unused_local_variable: ignore
+''');
+    // Setup context.
+    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+
+    // Verify filter setup.
+    List<ErrorFilter> filters =
+        callbacks.currentContext.getConfigurationData(CONFIGURED_ERROR_FILTERS);
+    expect(filters, isNotNull);
+    expect(filters, hasLength(1));
+    expect(
+        filters.first(new AnalysisError(
+            new TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [
+          ['x']
+        ])),
+        isTrue);
+  }
+
+  test_error_filter_analysis_option_multiple_filters() async {
+    // Create files.
+    newFile(
+        [projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE],
+        r'''
+analyzer:
+  errors:
+    invalid_assignment: ignore
+    unused_local_variable: ignore
+''');
+    // Setup context.
+    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+
+    // Verify filter setup.
+    List<ErrorFilter> filters =
+        callbacks.currentContext.getConfigurationData(CONFIGURED_ERROR_FILTERS);
+    expect(filters, isNotNull);
+    expect(filters, hasLength(2));
+
+    var unused_error = new AnalysisError(
+        new TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [
+      ['x']
+    ]);
+
+    var invalid_assignment_error =
+        new AnalysisError(new TestSource(), 0, 1, HintCode.INVALID_ASSIGNMENT, [
+      ['x'],
+      ['y']
+    ]);
+
+    expect(filters.any((filter) => filter(unused_error)), isTrue);
+    expect(filters.any((filter) => filter(invalid_assignment_error)), isTrue);
+  }
+
+  test_error_filter_analysis_option_synonyms() async {
+    // Create files.
+    newFile(
+        [projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE],
+        r'''
+analyzer:
+  errors:
+    unused_local_variable: ignore
+    ambiguous_import: false
+''');
+    // Setup context.
+    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+
+    // Verify filter setup.
+    List<ErrorFilter> filters =
+        callbacks.currentContext.getConfigurationData(CONFIGURED_ERROR_FILTERS);
+    expect(filters, isNotNull);
+    expect(filters, hasLength(2));
+  }
+
+  test_error_filter_analysis_option_unpsecified() async {
+    // Create files.
+    newFile(
+        [projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE],
+        r'''
+analyzer:
+#  errors:
+#    unused_local_variable: ignore
+''');
+    // Setup context.
+    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+
+    // Verify filter setup.
+    List<ErrorFilter> filters =
+        callbacks.currentContext.getConfigurationData(CONFIGURED_ERROR_FILTERS);
+    expect(filters, isEmpty);
+  }
+
   test_ignoreFilesInPackagesFolder() {
     // create a context with a pubspec.yaml file
     String pubspecPath = posix.join(projPath, 'pubspec.yaml');
@@ -233,7 +449,7 @@
     newFile([sdkExtSrcPath, 'part.dart']);
     // Setup analysis options file with ignore list.
     newFile(
-        [projPath, '.analysis_options'],
+        [projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE],
         r'''
 analyzer:
   exclude:
@@ -270,7 +486,7 @@
     // Setup analysis options file with ignore list that ignores the 'other_lib'
     // directory by name.
     newFile(
-        [projPath, '.analysis_options'],
+        [projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE],
         r'''
 analyzer:
   exclude:
@@ -306,7 +522,7 @@
     // Setup analysis options file with ignore list that ignores 'other_lib'
     // and all descendants.
     newFile(
-        [projPath, '.analysis_options'],
+        [projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE],
         r'''
 analyzer:
   exclude:
@@ -342,7 +558,7 @@
     // Setup analysis options file with ignore list that ignores 'other_lib'
     // and all immediate children.
     newFile(
-        [projPath, '.analysis_options'],
+        [projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE],
         r'''
 analyzer:
   exclude:
@@ -490,8 +706,7 @@
     newFile(
         [projPath, '.packages'],
         r'''
-test_pack:lib/
-''');
+test_pack:lib/''');
     // Setup context.
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
     // Confirm that one context was created.
@@ -1025,9 +1240,11 @@
     resourceProvider.newFile(pubspecPath, '');
     // add one root - there is a context
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+    expect(manager.changeSubscriptions, hasLength(1));
     expect(callbacks.currentContextPaths, hasLength(1));
     // set empty roots - no contexts
     manager.setRoots(<String>[], <String>[], <String, String>{});
+    expect(manager.changeSubscriptions, hasLength(0));
     expect(callbacks.currentContextPaths, hasLength(0));
     expect(callbacks.currentContextFilePaths, hasLength(0));
   }
@@ -1146,7 +1363,7 @@
   test_strong_mode_analysis_option() async {
     // Create files.
     newFile(
-        [projPath, '.analysis_options'],
+        [projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE],
         r'''
 analyzer:
   strong-mode: true
@@ -1809,7 +2026,19 @@
     currentContextSources[path] = new HashSet<Source>();
     currentContextDispositions[path] = disposition;
     currentContext = AnalysisEngine.instance.createAnalysisContext();
+    _locateEmbedderYamls(currentContext, disposition);
     List<UriResolver> resolvers = [];
+    if (currentContext is InternalAnalysisContext) {
+      EmbedderYamlLocator embedderYamlLocator =
+          (currentContext as InternalAnalysisContext).embedderYamlLocator;
+      EmbedderUriResolver embedderUriResolver =
+          new EmbedderUriResolver(embedderYamlLocator.embedderYamls);
+      if (embedderUriResolver.length > 0) {
+        // We have some embedder dart: uri mappings, add the resolver
+        // to the list.
+        resolvers.add(embedderUriResolver);
+      }
+    }
     resolvers.addAll(disposition.createPackageUriResolvers(resourceProvider));
     resolvers.add(new FileUriResolver());
     currentContext.sourceFactory =
@@ -1878,6 +2107,19 @@
       Folder contextFolder, FolderDisposition disposition) {
     currentContextDispositions[contextFolder.path] = disposition;
   }
+
+  /// If [disposition] has a package map, attempt to locate `_embedder.yaml`
+  /// files.
+  void _locateEmbedderYamls(
+      InternalAnalysisContext context, FolderDisposition disposition) {
+    Map<String, List<Folder>> packageMap;
+    if (disposition is PackageMapDisposition) {
+      packageMap = disposition.packageMap;
+    } else if (disposition is PackagesFileDisposition) {
+      packageMap = disposition.buildPackageMap(resourceProvider);
+    }
+    context.embedderYamlLocator.refresh(packageMap);
+  }
 }
 
 /**
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index f0d6f83..6c4b295 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -15,7 +15,7 @@
 import 'package:analysis_server/src/domain_completion.dart';
 import 'package:analysis_server/src/plugin/server_plugin.dart';
 import 'package:analysis_server/src/provisional/completion/completion_core.dart'
-    show CompletionRequest, CompletionResult;
+    show AnalysisRequest, CompletionRequest, CompletionResult;
 import 'package:analysis_server/src/provisional/completion/completion_dart.dart'
     as newApi;
 import 'package:analysis_server/src/services/completion/completion_manager.dart';
@@ -30,6 +30,9 @@
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/dart.dart';
+import 'package:analyzer/task/dart.dart';
+import 'package:analyzer/task/model.dart';
 import 'package:plugin/manager.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
@@ -617,6 +620,28 @@
     });
   }
 
+  test_relevancy_sorter_analysis() {
+    var originalSorter = DartCompletionManager.defaultContributionSorter;
+
+    // Setup the mock sorter to request additional analysis
+    var mockSorter = new MockRelevancySorter();
+    mockSorter.addTask(PARSED_UNIT);
+    mockSorter.addTask(LIBRARY_ELEMENT1);
+    mockSorter.addTask(RESOLVED_UNIT3);
+    mockSorter.addTask(RESOLVED_UNIT3);
+
+    DartCompletionManager.defaultContributionSorter = mockSorter;
+    addTestFile('main() {Map m; m.^}');
+
+    return getSuggestions().then((_) {
+      DartCompletionManager.defaultContributionSorter = originalSorter;
+      mockSorter.enabled = false;
+
+      // Assert that the analysis requests were processed
+      mockSorter.assertAnalysisRequestsProcessed();
+    });
+  }
+
   test_simple() {
     addTestFile('''
       void main() {
@@ -724,13 +749,36 @@
 
 class MockRelevancySorter implements ContributionSorter {
   bool enabled = true;
+  List<ResultDescriptor> descriptors = <ResultDescriptor>[];
+
+  void addTask(ResultDescriptor descriptor) {
+    descriptors.add(descriptor);
+  }
+
+  void assertAnalysisRequestsProcessed() {
+    expect(descriptors, hasLength(0));
+  }
 
   @override
-  void sort(newApi.DartCompletionRequest request,
-      List<CompletionSuggestion> suggestions) {
+  AnalysisRequest sort(
+      CompletionRequest request, Iterable<CompletionSuggestion> suggestions) {
     if (!enabled) {
       throw 'unexpected sort';
     }
+    return _nextAnalysisRequest(request);
+  }
+
+  AnalysisRequest _callback(CompletionRequest request, var value) {
+    expect(value, isNotNull);
+    return _nextAnalysisRequest(request);
+  }
+
+  AnalysisRequest _nextAnalysisRequest(CompletionRequest request) {
+    if (descriptors.length == 0) {
+      return null;
+    }
+    return new AnalysisRequest(
+        request.source, descriptors.removeAt(0), _callback);
   }
 }
 
diff --git a/pkg/analysis_server/test/domain_diagnostic_test.dart b/pkg/analysis_server/test/domain_diagnostic_test.dart
new file mode 100644
index 0000000..fdb336e
--- /dev/null
+++ b/pkg/analysis_server/test/domain_diagnostic_test.dart
@@ -0,0 +1,76 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.domain.diagnostic;
+
+import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analysis_server/src/analysis_server.dart';
+import 'package:analysis_server/src/domain_diagnostic.dart';
+import 'package:analysis_server/src/plugin/server_plugin.dart';
+import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:plugin/manager.dart';
+import 'package:unittest/unittest.dart';
+
+import 'mock_sdk.dart';
+import 'mocks.dart';
+import 'utils.dart';
+
+main() {
+  AnalysisServer server;
+  DiagnosticDomainHandler handler;
+  MemoryResourceProvider resourceProvider;
+
+  initializeTestEnvironment();
+
+  setUp(() {
+    var serverChannel = new MockServerChannel();
+    resourceProvider = new MemoryResourceProvider();
+    ExtensionManager manager = new ExtensionManager();
+    ServerPlugin serverPlugin = new ServerPlugin();
+    manager.processPlugins([serverPlugin]);
+    server = new AnalysisServer(
+        serverChannel,
+        resourceProvider,
+        new MockPackageMapProvider(),
+        null,
+        serverPlugin,
+        new AnalysisServerOptions(),
+        new MockSdk(),
+        InstrumentationService.NULL_SERVICE);
+    handler = new DiagnosticDomainHandler(server);
+  });
+
+  group('DiagnosticDomainHandler', () {
+    test('getDiagnostics', () async {
+      String file = '/project/bin/test.dart';
+      resourceProvider.newFile('/project/pubspec.yaml', 'name: project');
+      resourceProvider.newFile(file, 'main() {}');
+
+      server.setAnalysisRoots('0', ['/project/'], [], {});
+
+      await server.onAnalysisComplete;
+
+      var request = new DiagnosticGetDiagnosticsParams().toRequest('0');
+      var response = handler.handleRequest(request);
+
+      int fileCount = MockSdk.LIBRARIES.length + 1 /* test.dart */;
+
+      var json = response.toJson()[Response.RESULT];
+      expect(json['contexts'], hasLength(1));
+      var context = json['contexts'][0];
+      expect(context['name'], '/project');
+      expect(context['explicitFileCount'], fileCount);
+      expect(context['implicitFileCount'], 0);
+      expect(context['workItemQueueLength'], isNotNull);
+    });
+
+    test('getDiagnostics - (no root)', () async {
+      var request = new DiagnosticGetDiagnosticsParams().toRequest('0');
+      var response = handler.handleRequest(request);
+      var json = response.toJson()[Response.RESULT];
+      expect(json['contexts'], hasLength(0));
+    });
+  });
+}
diff --git a/pkg/analysis_server/test/domain_execution_test.dart b/pkg/analysis_server/test/domain_execution_test.dart
index 927d46d..a142adb 100644
--- a/pkg/analysis_server/test/domain_execution_test.dart
+++ b/pkg/analysis_server/test/domain_execution_test.dart
@@ -19,9 +19,11 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:plugin/manager.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:typed_mock/typed_mock.dart';
 import 'package:unittest/unittest.dart';
 
+import 'analysis_abstract.dart';
 import 'mock_sdk.dart';
 import 'mocks.dart';
 import 'operation/operation_queue_test.dart';
@@ -29,6 +31,7 @@
 
 main() {
   initializeTestEnvironment();
+  defineReflectiveTests(ExecutionDomainTest);
   group('ExecutionDomainHandler', () {
     MemoryResourceProvider provider = new MemoryResourceProvider();
     AnalysisServer server;
@@ -90,6 +93,15 @@
     group('mapUri', () {
       String contextId;
 
+      void createExecutionContextIdForFile(String path) {
+        Request request = new ExecutionCreateContextParams(path).toRequest('0');
+        Response response = handler.handleRequest(request);
+        expect(response, isResponseSuccess('0'));
+        ExecutionCreateContextResult result =
+            new ExecutionCreateContextResult.fromResponse(response);
+        contextId = result.id;
+      }
+
       setUp(() {
         Folder folder = provider.newFile('/a/b.dart', '').parent;
         server.folderMap.putIfAbsent(folder, () {
@@ -100,13 +112,7 @@
           context.sourceFactory = factory;
           return context;
         });
-        Request request =
-            new ExecutionCreateContextParams('/a/b.dart').toRequest('0');
-        Response response = handler.handleRequest(request);
-        expect(response, isResponseSuccess('0'));
-        ExecutionCreateContextResult result =
-            new ExecutionCreateContextResult.fromResponse(response);
-        contextId = result.id;
+        createExecutionContextIdForFile('/a/b.dart');
       });
 
       tearDown(() {
@@ -131,17 +137,6 @@
           Response response = handler.handleRequest(request);
           expect(response, isResponseFailure('2'));
         });
-
-        test('valid', () {
-          Request request = new ExecutionMapUriParams(contextId,
-              file: '/a/b.dart').toRequest('2');
-          Response response = handler.handleRequest(request);
-          expect(response, isResponseSuccess('2'));
-          ExecutionMapUriResult result =
-              new ExecutionMapUriResult.fromResponse(response);
-          expect(result.file, isNull);
-          expect(result.uri, 'file:///a/b.dart');
-        });
       });
 
       group('URI to file', () {
@@ -151,17 +146,6 @@
           Response response = handler.handleRequest(request);
           expect(response, isResponseFailure('2'));
         });
-
-        test('valid', () {
-          Request request = new ExecutionMapUriParams(contextId,
-              uri: 'file:///a/b.dart').toRequest('2');
-          Response response = handler.handleRequest(request);
-          expect(response, isResponseSuccess('2'));
-          ExecutionMapUriResult result =
-              new ExecutionMapUriResult.fromResponse(response);
-          expect(result.file, '/a/b.dart');
-          expect(result.uri, isNull);
-        });
       });
 
       test('invalid context id', () {
@@ -287,35 +271,74 @@
   });
 }
 
-/**
- * Return a matcher that will match an [ExecutableFile] if it has the given
- * [source] and [kind].
- */
-Matcher isExecutableFile(Source source, ExecutableKind kind) {
-  return new IsExecutableFile(source.fullName, kind);
-}
-
-/**
- * A matcher that will match an [ExecutableFile] if it has a specified [source]
- * and [kind].
- */
-class IsExecutableFile extends Matcher {
-  String expectedFile;
-  ExecutableKind expectedKind;
-
-  IsExecutableFile(this.expectedFile, this.expectedKind);
+@reflectiveTest
+class ExecutionDomainTest extends AbstractAnalysisTest {
+  String contextId;
 
   @override
-  Description describe(Description description) {
-    return description.add('ExecutableFile($expectedFile, $expectedKind)');
+  void setUp() {
+    super.setUp();
+    createProject();
+    handler = new ExecutionDomainHandler(server);
+    _createExecutionContext(testFile);
   }
 
   @override
-  bool matches(item, Map matchState) {
-    if (item is! ExecutableFile) {
-      return false;
-    }
-    return item.file == expectedFile && item.kind == expectedKind;
+  void tearDown() {
+    super.tearDown();
+    _disposeExecutionContext();
+  }
+
+  void test_mapUri_file() {
+    String path = '/a/b.dart';
+    resourceProvider.newFile(path, '');
+    // map the file
+    ExecutionMapUriResult result = _mapUri(file: path);
+    expect(result.file, isNull);
+    expect(result.uri, 'file:///a/b.dart');
+  }
+
+  void test_mapUri_file_dartUriKind() {
+    String path = server.defaultSdk.mapDartUri('dart:async').fullName;
+    // hack - pretend that the SDK file exists in the project FS
+    resourceProvider.newFile(path, '// hack');
+    // map file
+    ExecutionMapUriResult result = _mapUri(file: path);
+    expect(result.file, isNull);
+    expect(result.uri, 'dart:async');
+  }
+
+  void test_mapUri_uri() {
+    String path = '/a/b.dart';
+    resourceProvider.newFile(path, '');
+    // map the uri
+    ExecutionMapUriResult result = _mapUri(uri: 'file://$path');
+    expect(result.file, '/a/b.dart');
+    expect(result.uri, isNull);
+  }
+
+  void _createExecutionContext(String path) {
+    Request request = new ExecutionCreateContextParams(path).toRequest('0');
+    Response response = handler.handleRequest(request);
+    expect(response, isResponseSuccess('0'));
+    ExecutionCreateContextResult result =
+        new ExecutionCreateContextResult.fromResponse(response);
+    contextId = result.id;
+  }
+
+  void _disposeExecutionContext() {
+    Request request =
+        new ExecutionDeleteContextParams(contextId).toRequest('1');
+    Response response = handler.handleRequest(request);
+    expect(response, isResponseSuccess('1'));
+  }
+
+  ExecutionMapUriResult _mapUri({String file, String uri}) {
+    Request request = new ExecutionMapUriParams(contextId, file: file, uri: uri)
+        .toRequest('2');
+    Response response = handler.handleRequest(request);
+    expect(response, isResponseSuccess('2'));
+    return new ExecutionMapUriResult.fromResponse(response);
   }
 }
 
diff --git a/pkg/analysis_server/test/edit/refactoring_test.dart b/pkg/analysis_server/test/edit/refactoring_test.dart
index 0cc4971..fcb0568 100644
--- a/pkg/analysis_server/test/edit/refactoring_test.dart
+++ b/pkg/analysis_server/test/edit/refactoring_test.dart
@@ -275,6 +275,26 @@
     super.tearDown();
   }
 
+  test_coveringExpressions() {
+    addTestFile('''
+main() {
+  var v = 111 + 222 + 333;
+}
+''');
+    return getRefactoringResult(() {
+      return sendExtractRequest(testCode.indexOf('222 +'), 0, 'res', true);
+    }).then((result) {
+      ExtractLocalVariableFeedback feedback = result.feedback;
+      expect(feedback.coveringExpressionOffsets, [
+        testCode.indexOf('222 +'),
+        testCode.indexOf('111 +'),
+        testCode.indexOf('111 +')
+      ]);
+      expect(feedback.coveringExpressionLengths,
+          ['222'.length, '111 + 222'.length, '111 + 222 + 333'.length]);
+    });
+  }
+
   test_extractAll() {
     addTestFile('''
 main() {
@@ -1881,7 +1901,7 @@
     await waitForTasksFinished();
     Request request =
         new EditGetAvailableRefactoringsParams(testFile, 0, 0).toRequest('0');
-    return _assertErrorResposeNoIndex(request);
+    return _assertErrorResponseNoIndex(request);
   }
 
   test_getRefactoring_noSearchEngine() async {
@@ -1894,10 +1914,10 @@
     Request request = new EditGetRefactoringParams(
             RefactoringKind.EXTRACT_LOCAL_VARIABLE, testFile, 0, 0, true)
         .toRequest('0');
-    return _assertErrorResposeNoIndex(request);
+    return _assertErrorResponseNoIndex(request);
   }
 
-  _assertErrorResposeNoIndex(Request request) async {
+  _assertErrorResponseNoIndex(Request request) async {
     Response response = await serverChannel.sendRequest(request);
     expect(response.error, isNotNull);
     expect(response.error.code, RequestErrorCode.NO_INDEX_GENERATED);
diff --git a/pkg/analysis_server/test/integration/analysis/analysis_options_test.dart b/pkg/analysis_server/test/integration/analysis/analysis_options_test.dart
index c1cabe0..33ad500 100644
--- a/pkg/analysis_server/test/integration/analysis/analysis_options_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/analysis_options_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
diff --git a/pkg/analysis_server/test/integration/integration_test_methods.dart b/pkg/analysis_server/test/integration/integration_test_methods.dart
index bfe19dd..24933ef 100644
--- a/pkg/analysis_server/test/integration/integration_test_methods.dart
+++ b/pkg/analysis_server/test/integration/integration_test_methods.dart
@@ -1629,6 +1629,23 @@
   StreamController<ExecutionLaunchDataParams> _onExecutionLaunchData;
 
   /**
+   * Return server diagnostics.
+   *
+   * Returns
+   *
+   * contexts ( List<ContextData> )
+   *
+   *   The list of analysis contexts.
+   */
+  Future<DiagnosticGetDiagnosticsResult> sendDiagnosticGetDiagnostics() {
+    return server.send("diagnostic.getDiagnostics", null)
+        .then((result) {
+      ResponseDecoder decoder = new ResponseDecoder(null);
+      return new DiagnosticGetDiagnosticsResult.fromJson(decoder, 'result', result);
+    });
+  }
+
+  /**
    * Initialize the fields in InttestMixin, and ensure that notifications will
    * be handled.
    */
diff --git a/pkg/analysis_server/test/integration/protocol_matchers.dart b/pkg/analysis_server/test/integration/protocol_matchers.dart
index 6d0ec42..6663f98 100644
--- a/pkg/analysis_server/test/integration/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/protocol_matchers.dart
@@ -1007,6 +1007,23 @@
   }));
 
 /**
+ * diagnostic.getDiagnostics params
+ */
+final Matcher isDiagnosticGetDiagnosticsParams = isNull;
+
+/**
+ * diagnostic.getDiagnostics result
+ *
+ * {
+ *   "contexts": List<ContextData>
+ * }
+ */
+final Matcher isDiagnosticGetDiagnosticsResult = new LazyMatcher(() => new MatchesJsonObject(
+  "diagnostic.getDiagnostics result", {
+    "contexts": isListOf(isContextData)
+  }));
+
+/**
  * AddContentOverlay
  *
  * {
@@ -1259,6 +1276,26 @@
 ]);
 
 /**
+ * ContextData
+ *
+ * {
+ *   "name": String
+ *   "explicitFileCount": int
+ *   "implicitFileCount": int
+ *   "workItemQueueLength": int
+ *   "cacheEntryExceptions": List<String>
+ * }
+ */
+final Matcher isContextData = new LazyMatcher(() => new MatchesJsonObject(
+  "ContextData", {
+    "name": isString,
+    "explicitFileCount": isInt,
+    "implicitFileCount": isInt,
+    "workItemQueueLength": isInt,
+    "cacheEntryExceptions": isListOf(isString)
+  }));
+
+/**
  * Element
  *
  * {
@@ -2243,8 +2280,8 @@
  * extractLocalVariable feedback
  *
  * {
- *   "coveringExpressionOffsets": List<int>
- *   "coveringExpressionLengths": List<int>
+ *   "coveringExpressionOffsets": optional List<int>
+ *   "coveringExpressionLengths": optional List<int>
  *   "names": List<String>
  *   "offsets": List<int>
  *   "lengths": List<int>
@@ -2252,11 +2289,12 @@
  */
 final Matcher isExtractLocalVariableFeedback = new LazyMatcher(() => new MatchesJsonObject(
   "extractLocalVariable feedback", {
-    "coveringExpressionOffsets": isListOf(isInt),
-    "coveringExpressionLengths": isListOf(isInt),
     "names": isListOf(isString),
     "offsets": isListOf(isInt),
     "lengths": isListOf(isInt)
+  }, optionalFields: {
+    "coveringExpressionOffsets": isListOf(isInt),
+    "coveringExpressionLengths": isListOf(isInt)
   }));
 
 /**
diff --git a/pkg/analysis_server/test/services/completion/common_usage_computer_test.dart b/pkg/analysis_server/test/services/completion/common_usage_computer_test.dart
index 3e15f2e..8ed33f1 100644
--- a/pkg/analysis_server/test/services/completion/common_usage_computer_test.dart
+++ b/pkg/analysis_server/test/services/completion/common_usage_computer_test.dart
@@ -172,6 +172,23 @@
     assertNoResult('A');
   }
 
+  test_PrefixedIdentifier_field_inPart() async {
+    // SimpleIdentifier  PrefixedIdentifeir  ExpressionStatement
+    addFile('/project/bin/myLib.dart',
+        'library L; part "$testFile"; class A {static int s2;}');
+    addTestFile('part of L; foo() {A.^}');
+    await getSuggestions({
+      'L.A': ['s2']
+    });
+    expect(replacementOffset, equals(completionOffset));
+    expect(replacementLength, equals(0));
+    assertHasResult(
+        CompletionSuggestionKind.INVOCATION, 's2', DART_RELEVANCE_COMMON_USAGE);
+    assertNoResult('Future');
+    assertNoResult('Object');
+    assertNoResult('A');
+  }
+
   test_PrefixedIdentifier_getter() async {
     // SimpleIdentifier  PrefixedIdentifeir  ExpressionStatement
     addTestFile('class A {int get g1 => 1; int get g2 => 2; x() {new A().^}}');
diff --git a/pkg/analysis_server/test/services/correction/fix_test.dart b/pkg/analysis_server/test/services/correction/fix_test.dart
index 14f2fc8..5d124f0 100644
--- a/pkg/analysis_server/test/services/correction/fix_test.dart
+++ b/pkg/analysis_server/test/services/correction/fix_test.dart
@@ -335,35 +335,34 @@
 ''');
     List<AnalysisError> errors = context.computeErrors(testSource);
     expect(errors, hasLength(2));
-    // ParserError: Expected to find ';'
-    {
-      AnalysisError error = errors[0];
-      expect(error.message, "Expected to find ';'");
-      List<Fix> fixes = _computeFixes(error);
-      expect(fixes, isEmpty);
-    }
-    // Undefined name 'await'
-    {
-      AnalysisError error = errors[1];
-      expect(error.message, "Undefined name 'await'");
-      List<Fix> fixes = _computeFixes(error);
-      // has exactly one fix
-      expect(fixes, hasLength(1));
-      Fix fix = fixes[0];
-      expect(fix.kind, DartFixKind.ADD_ASYNC);
-      // apply to "file"
-      List<SourceFileEdit> fileEdits = fix.change.edits;
-      expect(fileEdits, hasLength(1));
-      resultCode = SourceEdit.applySequence(testCode, fileEdits[0].edits);
-      // verify
-      expect(
-          resultCode,
-          '''
+    String message1 = "Expected to find ';'";
+    String message2 = "Undefined name 'await'";
+    expect(errors.map((e) => e.message), unorderedEquals([message1, message2]));
+    for (AnalysisError error in errors) {
+      if (error.message == message1) {
+        List<Fix> fixes = _computeFixes(error);
+        expect(fixes, isEmpty);
+      }
+      if (error.message == message2) {
+        List<Fix> fixes = _computeFixes(error);
+        // has exactly one fix
+        expect(fixes, hasLength(1));
+        Fix fix = fixes[0];
+        expect(fix.kind, DartFixKind.ADD_ASYNC);
+        // apply to "file"
+        List<SourceFileEdit> fileEdits = fix.change.edits;
+        expect(fileEdits, hasLength(1));
+        resultCode = SourceEdit.applySequence(testCode, fileEdits[0].edits);
+        // verify
+        expect(
+            resultCode,
+            '''
 foo() {}
 main() async {
   await foo();
 }
 ''');
+      }
     }
   }
 
@@ -398,6 +397,51 @@
 ''');
   }
 
+  void test_canBeNullAfterNullAware_chain() {
+    resolveTestUnit('''
+main(x) {
+  x?.a.b.c;
+}
+''');
+    assertHasFix(
+        DartFixKind.REPLACE_WITH_NULL_AWARE,
+        '''
+main(x) {
+  x?.a?.b?.c;
+}
+''');
+  }
+
+  void test_canBeNullAfterNullAware_methodInvocation() {
+    resolveTestUnit('''
+main(x) {
+  x?.a.b();
+}
+''');
+    assertHasFix(
+        DartFixKind.REPLACE_WITH_NULL_AWARE,
+        '''
+main(x) {
+  x?.a?.b();
+}
+''');
+  }
+
+  void test_canBeNullAfterNullAware_propertyAccess() {
+    resolveTestUnit('''
+main(x) {
+  x?.a().b;
+}
+''');
+    assertHasFix(
+        DartFixKind.REPLACE_WITH_NULL_AWARE,
+        '''
+main(x) {
+  x?.a()?.b;
+}
+''');
+  }
+
   void test_changeToStaticAccess_method() {
     resolveTestUnit('''
 class A {
@@ -3253,7 +3297,7 @@
 }
 ''');
     assertHasFix(
-        DartFixKind.REMOVE_UNNECASSARY_CAST,
+        DartFixKind.REMOVE_UNNECESSARY_CAST,
         '''
 main(Object p) {
   if (p is String) {
diff --git a/pkg/analysis_server/test/services/refactoring/extract_local_test.dart b/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
index a5dd25a..4dfb55d 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
@@ -82,33 +82,6 @@
         expectedMessage: 'Cannot extract a single method name.');
   }
 
-  test_checkInitialConditions_nameOfProperty_prefixedIdentifier() async {
-    indexTestUnit('''
-main(p) {
-  p.value; // marker
-}
-''');
-    _createRefactoringWithSuffix('value', '; // marker');
-    // check conditions
-    RefactoringStatus status = await refactoring.checkAllConditions();
-    assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL,
-        expectedMessage: 'Cannot extract name part of a property access.');
-  }
-
-  test_checkInitialConditions_nameOfProperty_propertyAccess() async {
-    indexTestUnit('''
-main() {
-  foo().length; // marker
-}
-String foo() => '';
-''');
-    _createRefactoringWithSuffix('length', '; // marker');
-    // check conditions
-    RefactoringStatus status = await refactoring.checkAllConditions();
-    assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL,
-        expectedMessage: 'Cannot extract name part of a property access.');
-  }
-
   test_checkInitialConditions_namePartOfDeclaration_variable() async {
     indexTestUnit('''
 main() {
@@ -122,6 +95,17 @@
         expectedMessage: 'Cannot extract the name part of a declaration.');
   }
 
+  test_checkInitialConditions_noExpression() async {
+    indexTestUnit('''
+main() {
+  // abc
+}
+''');
+    _createRefactoringForString('abc');
+    // check conditions
+    _assertInitialConditions_fatal_selection();
+  }
+
   test_checkInitialConditions_notPartOfFunction() async {
     indexTestUnit('''
 int a = 1 + 2;
@@ -141,11 +125,13 @@
 }
 ''');
     _createRefactoringForString("'a");
-    // check conditions
-    RefactoringStatus status = await refactoring.checkAllConditions();
-    assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL,
-        expectedMessage:
-            'Cannot extract only leading or trailing quote of string literal.');
+    // apply refactoring
+    return _assertSuccessfulRefactoring('''
+main() {
+  var res = 'abc';
+  var vvv = res;
+}
+''');
   }
 
   test_checkInitialConditions_stringSelection_trailingQuote() async {
@@ -155,11 +141,13 @@
 }
 ''');
     _createRefactoringForString("c'");
-    // check conditions
-    RefactoringStatus status = await refactoring.checkAllConditions();
-    assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL,
-        expectedMessage:
-            'Cannot extract only leading or trailing quote of string literal.');
+    // apply refactoring
+    return _assertSuccessfulRefactoring('''
+main() {
+  var res = 'abc';
+  var vvv = res;
+}
+''');
   }
 
   test_checkLocalName() {
@@ -334,6 +322,27 @@
 ''');
   }
 
+  test_coveringExpressions() async {
+    indexTestUnit('''
+main() {
+  int aaa = 1;
+  int bbb = 2;
+  var c = aaa + bbb * 2 + 3;
+}
+''');
+    _createRefactoring(testCode.indexOf('bb * 2'), 0);
+    // check conditions
+    await refactoring.checkInitialConditions();
+    List<String> subExpressions = <String>[];
+    for (int i = 0; i < refactoring.coveringExpressionOffsets.length; i++) {
+      int offset = refactoring.coveringExpressionOffsets[i];
+      int length = refactoring.coveringExpressionLengths[i];
+      subExpressions.add(testCode.substring(offset, offset + length));
+    }
+    expect(subExpressions,
+        ['bbb', 'bbb * 2', 'aaa + bbb * 2', 'aaa + bbb * 2 + 3']);
+  }
+
   test_fragmentExpression() {
     indexTestUnit('''
 main() {
@@ -344,8 +353,8 @@
     // apply refactoring
     return _assertSuccessfulRefactoring('''
 main() {
-  var res = 2 + 3;
-  int a = 1 + res + 4;
+  var res = 1 + 2 + 3;
+  int a = res + 4;
 }
 ''');
   }
@@ -357,8 +366,13 @@
 }
 ''');
     _createRefactoringForString('+ 2');
-    // check conditions
-    return _assertInitialConditions_fatal_selection();
+    // apply refactoring
+    return _assertSuccessfulRefactoring('''
+main() {
+  var res = 1 + 2;
+  int a = res + 3 + 4;
+}
+''');
   }
 
   test_fragmentExpression_leadingPartialSelection() {
@@ -368,8 +382,13 @@
 }
 ''');
     _createRefactoringForString('11 + 2');
-    // check conditions
-    return _assertInitialConditions_fatal_selection();
+    // apply refactoring
+    return _assertSuccessfulRefactoring('''
+main() {
+  var res = 111 + 2;
+  int a = res + 3 + 4;
+}
+''');
   }
 
   test_fragmentExpression_leadingWhitespace() {
@@ -382,8 +401,8 @@
     // apply refactoring
     return _assertSuccessfulRefactoring('''
 main() {
-  var res =  2 + 3;
-  int a = 1 +res + 4;
+  var res = 1 + 2 + 3;
+  int a = res + 4;
 }
 ''');
   }
@@ -395,8 +414,13 @@
 }
 ''');
     _createRefactoringForString('2 - 3');
-    // check conditions
-    return _assertInitialConditions_fatal_selection();
+    // apply refactoring
+    return _assertSuccessfulRefactoring('''
+main() {
+  var res = 1 - 2 - 3;
+  int a = res - 4;
+}
+''');
   }
 
   test_fragmentExpression_trailingNotWhitespace() {
@@ -405,20 +429,30 @@
   int a = 1 + 2 + 3 + 4;
 }
 ''');
-    _createRefactoringForString('2 + 3 +');
-    // check conditions
-    return _assertInitialConditions_fatal_selection();
+    _createRefactoringForString('1 + 2 +');
+    // apply refactoring
+    return _assertSuccessfulRefactoring('''
+main() {
+  var res = 1 + 2 + 3;
+  int a = res + 4;
+}
+''');
   }
 
   test_fragmentExpression_trailingPartialSelection() {
     indexTestUnit('''
 main() {
-  int a = 1 + 2 + 3 + 444;
+  int a = 1 + 2 + 333 + 4;
 }
 ''');
-    _createRefactoringForString('2 + 3 + 44');
-    // check conditions
-    return _assertInitialConditions_fatal_selection();
+    _createRefactoringForString('2 + 33');
+    // apply refactoring
+    return _assertSuccessfulRefactoring('''
+main() {
+  var res = 1 + 2 + 333;
+  int a = res + 4;
+}
+''');
   }
 
   test_fragmentExpression_trailingWhitespace() {
@@ -431,8 +465,8 @@
     // apply refactoring
     return _assertSuccessfulRefactoring('''
 main() {
-  var res = 2 + 3 ;
-  int a = 1 + res+ 4;
+  var res = 1 + 2 + 3;
+  int a = res + 4;
 }
 ''');
   }
@@ -446,7 +480,7 @@
     _createRefactoringForString('222 + 333');
     // check guesses
     await refactoring.checkInitialConditions();
-    expect(refactoring.names, isEmpty);
+    expect(refactoring.names, unorderedEquals(['i']));
   }
 
   test_guessNames_singleExpression() async {
@@ -477,7 +511,7 @@
     expect(refactoring.names, unorderedEquals(['helloBob', 'bob']));
   }
 
-  test_occurences_differentVariable() {
+  test_occurrences_differentVariable() {
     indexTestUnit('''
 main() {
   {
@@ -509,7 +543,7 @@
 ''');
   }
 
-  test_occurences_disableOccurences() {
+  test_occurrences_disableOccurrences() {
     indexTestUnit('''
 int foo() => 42;
 main() {
@@ -530,7 +564,7 @@
 ''');
   }
 
-  test_occurences_ignore_assignmentLeftHandSize() {
+  test_occurrences_ignore_assignmentLeftHandSize() {
     indexTestUnit('''
 main() {
   int v = 1;
@@ -554,7 +588,7 @@
 ''');
   }
 
-  test_occurences_ignore_nameOfVariableDeclariton() {
+  test_occurrences_ignore_nameOfVariableDeclaration() {
     indexTestUnit('''
 main() {
   int v = 1;
@@ -572,7 +606,7 @@
 ''');
   }
 
-  test_occurences_singleExpression() {
+  test_occurrences_singleExpression() {
     indexTestUnit('''
 int foo() => 42;
 main() {
@@ -592,7 +626,7 @@
 ''');
   }
 
-  test_occurences_useDominator() {
+  test_occurrences_useDominator() {
     indexTestUnit('''
 main() {
   if (true) {
@@ -616,7 +650,7 @@
 ''');
   }
 
-  test_occurences_whenComment() {
+  test_occurrences_whenComment() {
     indexTestUnit('''
 int foo() => 42;
 main() {
@@ -636,7 +670,7 @@
 ''');
   }
 
-  test_occurences_withSpace() {
+  test_occurrences_withSpace() {
     indexTestUnit('''
 int foo(String s) => 42;
 main() {
@@ -800,26 +834,65 @@
 }
 ''');
     _createRefactoringForString('+ 345');
-    // check conditions
-    return _assertInitialConditions_fatal_selection();
+    // apply refactoring
+    return _assertSuccessfulRefactoring('''
+main() {
+  var res = 12 + 345;
+  int a = res;
+}
+''');
   }
 
   test_singleExpression_leadingWhitespace() {
     indexTestUnit('''
 main() {
-  int a = 12 /*abc*/ + 345;
+  int a = 1 /*abc*/ + 2 + 345;
 }
 ''');
-    _createRefactoringForString('12 /*abc*/');
+    _createRefactoringForString('1 /*abc*/');
     // apply refactoring
     return _assertSuccessfulRefactoring('''
 main() {
-  var res = 12 /*abc*/;
+  var res = 1 /*abc*/ + 2;
   int a = res + 345;
 }
 ''');
   }
 
+  test_singleExpression_nameOfProperty_prefixedIdentifier() async {
+    indexTestUnit('''
+main(p) {
+  var v = p.value; // marker
+}
+''');
+    _createRefactoringWithSuffix('value', '; // marker');
+    // apply refactoring
+    return _assertSuccessfulRefactoring('''
+main(p) {
+  var res = p.value;
+  var v = res; // marker
+}
+''');
+  }
+
+  test_singleExpression_nameOfProperty_propertyAccess() async {
+    indexTestUnit('''
+main() {
+  var v = foo().length; // marker
+}
+String foo() => '';
+''');
+    _createRefactoringWithSuffix('length', '; // marker');
+    // apply refactoring
+    return _assertSuccessfulRefactoring('''
+main() {
+  var res = foo().length;
+  var v = res; // marker
+}
+String foo() => '';
+''');
+  }
+
   /**
    * Here we use knowledge how exactly `1 + 2 + 3 + 41 is parsed. We know that
    * `1 + 2` will be a separate and complete binary expression, so it can be
@@ -841,22 +914,6 @@
 ''');
   }
 
-  test_singleExpression_trailingComment() {
-    indexTestUnit('''
-main() {
-  int a =  1 + 2;
-}
-''');
-    _createRefactoringForString(' 1 + 2');
-    // apply refactoring
-    return _assertSuccessfulRefactoring('''
-main() {
-  var res =  1 + 2;
-  int a = res;
-}
-''');
-  }
-
   test_singleExpression_trailingNotWhitespace() {
     indexTestUnit('''
 main() {
@@ -864,8 +921,13 @@
 }
 ''');
     _createRefactoringForString('12 +');
-    // check conditions
-    return _assertInitialConditions_fatal_selection();
+    // apply refactoring
+    return _assertSuccessfulRefactoring('''
+main() {
+  var res = 12 + 345;
+  int a = res;
+}
+''');
   }
 
   test_singleExpression_trailingWhitespace() {
@@ -878,8 +940,8 @@
     // apply refactoring
     return _assertSuccessfulRefactoring('''
 main() {
-  var res = 1 + 2 ;
-  int a = res;
+  var res = 1 + 2;
+  int a = res ;
 }
 ''');
   }
@@ -944,8 +1006,8 @@
   }
 
   /**
-   * Checks that all conditions are OK and the result of applying the [Change]
-   * to [testUnit] is [expectedCode].
+   * Checks that all conditions are OK and the result of applying the
+   * [SourceChange] to [testUnit] is [expectedCode].
    */
   Future _assertSuccessfulRefactoring(String expectedCode) async {
     await assertRefactoringConditionsOK();
diff --git a/pkg/analysis_server/test/stress/utilities/git.dart b/pkg/analysis_server/test/stress/utilities/git.dart
new file mode 100644
index 0000000..30e45f7
--- /dev/null
+++ b/pkg/analysis_server/test/stress/utilities/git.dart
@@ -0,0 +1,542 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * Support for interacting with a git repository.
+ */
+library analysis_server.test.stress.utilities.git;
+
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:analyzer/src/util/glob.dart';
+import 'package:path/path.dart' as path;
+
+/**
+ * A representation of the differences between two blobs.
+ */
+class BlobDiff {
+  /**
+   * The regular expression used to identify the beginning of a hunk.
+   */
+  static final RegExp hunkHeaderRegExp =
+      new RegExp(r'@@ -([0-9]+)(?:,[0-9]+)? \+([0-9]+)(?:,[0-9]+)? @@');
+
+  /**
+   * A list of the hunks in the diff.
+   */
+  List<DiffHunk> hunks = <DiffHunk>[];
+
+  /**
+   * Initialize a newly created blob diff by parsing the result of the git diff
+   * command (the [input]).
+   *
+   * This is only intended to be invoked from [GitRepository.getBlobDiff].
+   */
+  BlobDiff._(List<String> input) {
+    _parseInput(input);
+  }
+
+  /**
+   * Parse the result of the git diff command (the [input]).
+   */
+  void _parseInput(List<String> input) {
+    for (String line in input) {
+      _parseLine(line);
+    }
+  }
+
+  /**
+   * Parse a single [line] from the result of the git diff command.
+   */
+  void _parseLine(String line) {
+    DiffHunk currentHunk = hunks.isEmpty ? null : hunks.last;
+    if (line.startsWith('@@')) {
+      Match match = hunkHeaderRegExp.matchAsPrefix(line);
+      int srcLine = int.parse(match.group(1));
+      int dstLine = int.parse(match.group(2));
+      hunks.add(new DiffHunk(srcLine, dstLine));
+    } else if (currentHunk != null && line.startsWith('+')) {
+      currentHunk.addLines.add(line.substring(1));
+    } else if (currentHunk != null && line.startsWith('-')) {
+      currentHunk.removeLines.add(line.substring(1));
+    }
+  }
+}
+
+/**
+ * A representation of the differences between two commits.
+ */
+class CommitDelta {
+  /**
+   * The length (in characters) of a SHA.
+   */
+  static final int SHA_LENGTH = 40;
+
+  /**
+   * The code-point for a colon (':').
+   */
+  static final int COLON = ':'.codeUnitAt(0);
+
+  /**
+   * The code-point for a nul character.
+   */
+  static final int NUL = 0;
+
+  /**
+   * The code-point for a tab.
+   */
+  static final int TAB = '\t'.codeUnitAt(0);
+
+  /**
+   * The repository from which the commits were taken.
+   */
+  final GitRepository repository;
+
+  /**
+   * The records of the files that were changed.
+   */
+  final List<DiffRecord> diffRecords = <DiffRecord>[];
+
+  /**
+   * Initialize a newly created representation of the differences between two
+   * commits. The differences are computed by parsing the result of a git diff
+   * command (the [diffResults]).
+   *
+   * This is only intended to be invoked from [GitRepository.getBlobDiff].
+   */
+  CommitDelta._(this.repository, String diffResults) {
+    _parseInput(diffResults);
+  }
+
+  /**
+   * Return `true` if there are differences.
+   */
+  bool get hasDiffs => diffRecords.isNotEmpty;
+
+  /**
+   * Return the absolute paths of all of the files in this commit whose name
+   * matches the given [fileName].
+   */
+  Iterable<String> filesMatching(String fileName) {
+    return diffRecords
+        .where((DiffRecord record) => record.isFor(fileName))
+        .map((DiffRecord record) => record.srcPath);
+  }
+
+  /**
+   * Remove any diffs for files that are either (a) outside the given
+   * [inclusionPaths], or (b) are files that do not match one of the given
+   * [globPatterns].
+   */
+  void filterDiffs(List<String> inclusionPaths, List<Glob> globPatterns) {
+    diffRecords.retainWhere((DiffRecord record) {
+      String filePath = record.srcPath ?? record.dstPath;
+      for (String inclusionPath in inclusionPaths) {
+        if (path.isWithin(inclusionPath, filePath)) {
+          for (Glob glob in globPatterns) {
+            if (glob.matches(filePath)) {
+              return true;
+            }
+          }
+        }
+      }
+      return false;
+    });
+  }
+
+  /**
+   * Return the index of the first nul character in the given [string] that is
+   * at or after the given [start] index.
+   */
+  int _findEnd(String string, int start) {
+    int length = string.length;
+    int end = start;
+    while (end < length && string.codeUnitAt(end) != NUL) {
+      end++;
+    }
+    return end;
+  }
+
+  /**
+   * Return the result of converting the given [relativePath] to an absolute
+   * path. The path is assumed to be relative to the root of the repository.
+   */
+  String _makeAbsolute(String relativePath) {
+    return path.join(repository.path, relativePath);
+  }
+
+  /**
+   * Parse all of the diff records in the given [input].
+   */
+  void _parseInput(String input) {
+    int length = input.length;
+    int start = 0;
+    while (start < length) {
+      start = _parseRecord(input, start);
+    }
+  }
+
+  /**
+   * Parse a single record from the given [input], assuming that the record
+   * starts at the given [startIndex].
+   *
+   * Each record is formatted as a sequence of fields. The fields are, from the
+   * left to the right:
+   *
+   * 1. a colon.
+   * 2. mode for "src"; 000000 if creation or unmerged.
+   * 3. a space.
+   * 4. mode for "dst"; 000000 if deletion or unmerged.
+   * 5. a space.
+   * 6. sha1 for "src"; 0{40} if creation or unmerged.
+   * 7. a space.
+   * 8. sha1 for "dst"; 0{40} if creation, unmerged or "look at work tree".
+   * 9. a space.
+   * 10. status, followed by optional "score" number.
+   * 11. a tab or a NUL when -z option is used.
+   * 12. path for "src"
+   * 13. a tab or a NUL when -z option is used; only exists for C or R.
+   * 14. path for "dst"; only exists for C or R.
+   * 15. an LF or a NUL when -z option is used, to terminate the record.
+   */
+  int _parseRecord(String input, int startIndex) {
+    // Skip the first five fields.
+    startIndex += 15;
+    // Parse field 6
+    String srcSha = input.substring(startIndex, startIndex + SHA_LENGTH);
+    startIndex += SHA_LENGTH + 1;
+    // Parse field 8
+    String dstSha = input.substring(startIndex, startIndex + SHA_LENGTH);
+    startIndex += SHA_LENGTH + 1;
+    // Parse field 10
+    int endIndex = _findEnd(input, startIndex);
+    String status = input.substring(startIndex, endIndex);
+    startIndex = endIndex + 1;
+    // Parse field 12
+    endIndex = _findEnd(input, startIndex);
+    String srcPath = _makeAbsolute(input.substring(startIndex, endIndex));
+    startIndex = endIndex + 1;
+    // Parse field 14
+    String dstPath = null;
+    if (status.startsWith('C') || status.startsWith('R')) {
+      endIndex = _findEnd(input, startIndex);
+      dstPath = _makeAbsolute(input.substring(startIndex, endIndex));
+    }
+    // Create the record.
+    diffRecords.add(
+        new DiffRecord(repository, srcSha, dstSha, status, srcPath, dstPath));
+    return endIndex + 1;
+  }
+}
+
+/**
+ * Representation of a single diff hunk.
+ */
+class DiffHunk {
+  /**
+   * The index of the first line that was changed in the src as returned by the
+   * diff command. The diff command numbers lines starting at 1, but it
+   * subtracts 1 from the line number if there are no lines on the source side
+   * of the hunk.
+   */
+  int diffSrcLine;
+
+  /**
+   * The index of the first line that was changed in the dst as returned by the
+   * diff command. The diff command numbers lines starting at 1, but it
+   * subtracts 1 from the line number if there are no lines on the destination
+   * side of the hunk.
+   */
+  int diffDstLine;
+
+  /**
+   * A list of the individual lines that were removed from the src.
+   */
+  List<String> removeLines = <String>[];
+
+  /**
+   * A list of the individual lines that were added to the dst.
+   */
+  List<String> addLines = <String>[];
+
+  /**
+   * Initialize a newly created hunk. The lines will be added after the object
+   * has been created.
+   */
+  DiffHunk(this.diffSrcLine, this.diffDstLine);
+
+  /**
+   * Return the index of the first line that was changed in the dst. Unlike the
+   * [diffDstLine] field, this getter adjusts the line number to be consistent
+   * whether or not there were any changed lines.
+   */
+  int get dstLine {
+    return addLines.isEmpty ? diffDstLine : diffDstLine - 1;
+  }
+
+  /**
+   * Return the index of the first line that was changed in the src. Unlike the
+   * [diffDstLine] field, this getter adjusts the line number to be consistent
+   * whether or not there were any changed lines.
+   */
+  int get srcLine {
+    return removeLines.isEmpty ? diffSrcLine : diffSrcLine - 1;
+  }
+}
+
+/**
+ * A representation of a single line (record) from a raw diff.
+ */
+class DiffRecord {
+  /**
+   * The repository containing the file(s) that were modified.
+   */
+  final GitRepository repository;
+
+  /**
+   * The SHA1 of the blob in the src.
+   */
+  final String srcBlob;
+
+  /**
+   * The SHA1 of the blob in the dst.
+   */
+  final String dstBlob;
+
+  /**
+   * The status of the change. Valid values are:
+   * * A: addition of a file
+   * * C: copy of a file into a new one
+   * * D: deletion of a file
+   * * M: modification of the contents or mode of a file
+   * * R: renaming of a file
+   * * T: change in the type of the file
+   * * U: file is unmerged (you must complete the merge before it can be committed)
+   * * X: "unknown" change type (most probably a bug, please report it)
+   *
+   * Status letters C and R are always followed by a score (denoting the
+   * percentage of similarity between the source and target of the move or
+   * copy), and are the only ones to be so.
+   */
+  final String status;
+
+  /**
+   * The path of the src.
+   */
+  final String srcPath;
+
+  /**
+   * The path of the dst if this was either a copy or a rename operation.
+   */
+  final String dstPath;
+
+  /**
+   * Initialize a newly created diff record.
+   */
+  DiffRecord(this.repository, this.srcBlob, this.dstBlob, this.status,
+      this.srcPath, this.dstPath);
+
+  /**
+   * Return `true` if this record represents a file that was added.
+   */
+  bool get isAddition => status == 'A';
+
+  /**
+   * Return `true` if this record represents a file that was copied.
+   */
+  bool get isCopy => status.startsWith('C');
+
+  /**
+   * Return `true` if this record represents a file that was deleted.
+   */
+  bool get isDeletion => status == 'D';
+
+  /**
+   * Return `true` if this record represents a file that was modified.
+   */
+  bool get isModification => status == 'M';
+
+  /**
+   * Return `true` if this record represents a file that was renamed.
+   */
+  bool get isRename => status.startsWith('R');
+
+  /**
+   * Return `true` if this record represents an entity whose type was changed
+   * (for example, from a file to a directory).
+   */
+  bool get isTypeChange => status == 'T';
+
+  /**
+   * Return a representation of the individual blobs within this diff.
+   */
+  BlobDiff getBlobDiff() => repository.getBlobDiff(srcBlob, dstBlob);
+
+  /**
+   * Return `true` if this diff applies to a file with the given name.
+   */
+  bool isFor(String fileName) =>
+      (srcPath != null && fileName == path.basename(srcPath)) ||
+          (dstPath != null && fileName == path.basename(dstPath));
+
+  @override
+  String toString() => srcPath ?? dstPath;
+}
+
+/**
+ * A representation of a git repository.
+ */
+class GitRepository {
+  /**
+   * The absolute path of the directory containing the repository.
+   */
+  final String path;
+
+  /**
+   * Initialize a newly created repository to represent the git repository at
+   * the given [path].
+   */
+  GitRepository(this.path);
+
+  /**
+   * Checkout the given [commit] from the repository. This is done by running
+   * the command `git checkout <sha>`.
+   */
+  void checkout(String commit) {
+    _run(['checkout', commit]);
+  }
+
+  /**
+   * Return details about the differences between the two blobs identified by
+   * the SHA1 of the [srcBlob] and the SHA1 of the [dstBlob]. This is done by
+   * running the command `git diff <blob> <blob>`.
+   */
+  BlobDiff getBlobDiff(String srcBlob, String dstBlob) {
+    ProcessResult result = _run(['diff', '-U0', srcBlob, dstBlob]);
+    List<String> diffResults = LineSplitter.split(result.stdout).toList();
+    return new BlobDiff._(diffResults);
+  }
+
+  /**
+   * Return details about the differences between the two commits identified by
+   * the [srcCommit] and [dstCommit]. This is done by running the command
+   * `git diff --raw --no-abbrev --no-renames -z <sha> <sha>`.
+   */
+  CommitDelta getCommitDiff(String srcCommit, String dstCommit) {
+    // Consider --find-renames instead of --no-renames if rename information is
+    // desired.
+    ProcessResult result = _run([
+      'diff',
+      '--raw',
+      '--no-abbrev',
+      '--no-renames',
+      '-z',
+      srcCommit,
+      dstCommit
+    ]);
+    return new CommitDelta._(this, result.stdout);
+  }
+
+  /**
+   * Return a representation of the history of this repository. This is done by
+   * running the command `git rev-list --first-parent HEAD`.
+   */
+  LinearCommitHistory getCommitHistory() {
+    ProcessResult result = _run(['rev-list', '--first-parent', 'HEAD']);
+    List<String> commitIds = LineSplitter.split(result.stdout).toList();
+    return new LinearCommitHistory(this, commitIds);
+  }
+
+  /**
+   * Synchronously run the given [executable] with the given [arguments]. Return
+   * the result of running the process.
+   */
+  ProcessResult _run(List<String> arguments) {
+    return Process.runSync('git', arguments,
+        stderrEncoding: UTF8, stdoutEncoding: UTF8, workingDirectory: path);
+  }
+}
+
+/**
+ * A representation of the history of a Git repository. This only represents a
+ * single linear path in the history graph.
+ */
+class LinearCommitHistory {
+  /**
+   * The repository whose history is being represented.
+   */
+  final GitRepository repository;
+
+  /**
+   * The id's (SHA's) of the commits in the repository, with the most recent
+   * commit being first and the oldest commit being last.
+   */
+  final List<String> commitIds;
+
+  /**
+   * Initialize a commit history for the given [repository] to have the given
+   * [commitIds].
+   */
+  LinearCommitHistory(this.repository, this.commitIds);
+
+  /**
+   * Return an iterator that can be used to iterate over this commit history.
+   */
+  LinearCommitHistoryIterator iterator() {
+    return new LinearCommitHistoryIterator(this);
+  }
+}
+
+/**
+ * An iterator over the history of a Git repository.
+ */
+class LinearCommitHistoryIterator {
+  /**
+   * The commit history being iterated over.
+   */
+  final LinearCommitHistory history;
+
+  /**
+   * The index of the current commit in the list of [commitIds].
+   */
+  int currentCommit;
+
+  /**
+   * Initialize a newly created iterator to iterate over the commits with the
+   * given [commitIds];
+   */
+  LinearCommitHistoryIterator(this.history) {
+    currentCommit = history.commitIds.length;
+  }
+
+  /**
+   * Return the SHA1 of the commit after the current commit (the 'dst' of the
+   * [next] diff).
+   */
+  String get dstCommit => history.commitIds[currentCommit - 1];
+
+  /**
+   * Return the SHA1 of the current commit (the 'src' of the [next] diff).
+   */
+  String get srcCommit => history.commitIds[currentCommit];
+
+  /**
+   * Advance to the next commit in the history. Return `true` if it is safe to
+   * ask for the [next] diff.
+   */
+  bool moveNext() {
+    if (currentCommit <= 1) {
+      return false;
+    }
+    currentCommit--;
+    return true;
+  }
+
+  /**
+   * Return the difference between the current commit and the commit that
+   * followed it.
+   */
+  CommitDelta next() => history.repository.getCommitDiff(srcCommit, dstCommit);
+}
diff --git a/pkg/analysis_server/test/stress/utilities/server.dart b/pkg/analysis_server/test/stress/utilities/server.dart
new file mode 100644
index 0000000..149dcdf
--- /dev/null
+++ b/pkg/analysis_server/test/stress/utilities/server.dart
@@ -0,0 +1,86 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * Support for interacting with an analysis server running in a separate
+ * process.
+ */
+library analysis_server.test.stress.utilities.server;
+
+import 'dart:async';
+import 'dart:collection';
+
+import 'package:analysis_server/plugin/protocol/protocol.dart';
+
+import '../../integration/integration_test_methods.dart';
+import '../../integration/integration_tests.dart' as base;
+
+/**
+ * An interface for starting and communicating with an analysis server running
+ * in a separate process.
+ */
+class Server extends base.Server with IntegrationTestMixin {
+  /**
+   * A list containing the paths of files for which an overlay has been created.
+   */
+  List<String> filesWithOverlays = <String>[];
+
+  /**
+   * A table mapping the absolute paths of files to the most recent set of
+   * errors received for that file.
+   */
+  Map<String, List<AnalysisError>> _errorMap =
+      new HashMap<String, List<AnalysisError>>();
+
+  /**
+   * Initialize a new analysis server. The analysis server is not running and
+   * must be started using [start].
+   */
+  Server() {
+    initializeInttestMixin();
+    onAnalysisErrors.listen(_recordErrors);
+  }
+
+  /**
+   * Return a table mapping the absolute paths of files to the most recent set
+   * of errors received for that file. The content of the map will not change
+   * when new sets of errors are received.
+   */
+  Map<String, List<AnalysisError>> get errorMap =>
+      new HashMap<String, List<AnalysisError>>.from(_errorMap);
+
+  @override
+  base.Server get server => this;
+
+  /**
+   * Remove any existing overlays.
+   */
+  Future<AnalysisUpdateContentResult> removeAllOverlays() {
+    Map<String, dynamic> files = new HashMap<String, dynamic>();
+    for (String path in filesWithOverlays) {
+      files[path] = new RemoveContentOverlay();
+    }
+    return sendAnalysisUpdateContent(files);
+  }
+
+  @override
+  Future<AnalysisUpdateContentResult> sendAnalysisUpdateContent(
+      Map<String, dynamic> files) {
+    files.forEach((String path, dynamic overlay) {
+      if (overlay is AddContentOverlay) {
+        filesWithOverlays.add(path);
+      } else if (overlay is RemoveContentOverlay) {
+        filesWithOverlays.remove(path);
+      }
+    });
+    return super.sendAnalysisUpdateContent(files);
+  }
+
+  /**
+   * Record the errors in the given [params].
+   */
+  void _recordErrors(AnalysisErrorsParams params) {
+    _errorMap[params.file] = params.errors;
+  }
+}
diff --git a/pkg/analysis_server/test/test_all.dart b/pkg/analysis_server/test/test_all.dart
index a89913d..0a4a883 100644
--- a/pkg/analysis_server/test/test_all.dart
+++ b/pkg/analysis_server/test/test_all.dart
@@ -10,6 +10,7 @@
 import 'context_manager_test.dart' as context_manager_test;
 import 'domain_analysis_test.dart' as domain_analysis_test;
 import 'domain_completion_test.dart' as domain_completion_test;
+import 'domain_diagnostic_test.dart' as domain_experimental_test;
 import 'domain_execution_test.dart' as domain_execution_test;
 import 'domain_server_test.dart' as domain_server_test;
 import 'edit/test_all.dart' as edit_all;
@@ -38,6 +39,7 @@
     domain_analysis_test.main();
     domain_completion_test.main();
     domain_execution_test.main();
+    domain_experimental_test.main();
     domain_server_test.main();
     edit_all.main();
     operation_test_all.main();
diff --git a/pkg/analysis_server/tool/spec/api.dart b/pkg/analysis_server/tool/spec/api.dart
index a558f17..b5443aa 100644
--- a/pkg/analysis_server/tool/spec/api.dart
+++ b/pkg/analysis_server/tool/spec/api.dart
@@ -22,8 +22,9 @@
   final Refactorings refactorings;
 
   Api(this.version, this.domains, this.types, this.refactorings,
-      dom.Element html)
-      : super(html);
+      dom.Element html,
+      {bool experimental})
+      : super(html, experimental);
 }
 
 /**
@@ -31,11 +32,17 @@
  */
 class ApiNode {
   /**
+   * A flag to indicate if this API is experimental.
+   */
+  final bool experimental;
+
+  /**
    * Html element representing this part of the API.
    */
   final dom.Element html;
 
-  ApiNode(this.html);
+  ApiNode(this.html, bool experimental)
+      : this.experimental = experimental ?? false;
 }
 
 /**
@@ -63,8 +70,9 @@
   final List<Request> requests;
   final List<Notification> notifications;
 
-  Domain(this.name, this.requests, this.notifications, dom.Element html)
-      : super(html);
+  Domain(this.name, this.requests, this.notifications, dom.Element html,
+      {bool experimental})
+      : super(html, experimental);
 }
 
 /**
@@ -195,8 +203,9 @@
    */
   final TypeObject params;
 
-  Notification(this.domainName, this.event, this.params, dom.Element html)
-      : super(html);
+  Notification(this.domainName, this.event, this.params, dom.Element html,
+      {bool experimental})
+      : super(html, experimental);
 
   /**
    * Get the name of the notification, including the domain prefix.
@@ -240,8 +249,9 @@
    */
   final TypeObject options;
 
-  Refactoring(this.kind, this.feedback, this.options, dom.Element html)
-      : super(html);
+  Refactoring(this.kind, this.feedback, this.options, dom.Element html,
+      {bool experimental})
+      : super(html, experimental);
 }
 
 /**
@@ -250,7 +260,8 @@
 class Refactorings extends ApiNode with IterableMixin<Refactoring> {
   final List<Refactoring> refactorings;
 
-  Refactorings(this.refactorings, dom.Element html) : super(html);
+  Refactorings(this.refactorings, dom.Element html, {bool experimental})
+      : super(html, experimental);
 
   @override
   Iterator<Refactoring> get iterator => refactorings.iterator;
@@ -283,8 +294,9 @@
   final TypeObject result;
 
   Request(
-      this.domainName, this.method, this.params, this.result, dom.Element html)
-      : super(html);
+      this.domainName, this.method, this.params, this.result, dom.Element html,
+      {bool experimental})
+      : super(html, experimental);
 
   /**
    * Get the name of the request, including the domain prefix.
@@ -329,7 +341,7 @@
  * Base class for all possible types.
  */
 abstract class TypeDecl extends ApiNode {
-  TypeDecl(dom.Element html) : super(html);
+  TypeDecl(dom.Element html, bool experimental) : super(html, experimental);
 
   accept(ApiVisitor visitor);
 }
@@ -341,7 +353,8 @@
   final String name;
   final TypeDecl type;
 
-  TypeDefinition(this.name, this.type, dom.Element html) : super(html);
+  TypeDefinition(this.name, this.type, dom.Element html, {bool experimental})
+      : super(html, experimental);
 }
 
 /**
@@ -351,7 +364,8 @@
 class TypeEnum extends TypeDecl {
   final List<TypeEnumValue> values;
 
-  TypeEnum(this.values, dom.Element html) : super(html);
+  TypeEnum(this.values, dom.Element html, {bool experimental})
+      : super(html, experimental);
 
   accept(ApiVisitor visitor) => visitor.visitTypeEnum(this);
 }
@@ -362,7 +376,8 @@
 class TypeEnumValue extends ApiNode {
   final String value;
 
-  TypeEnumValue(this.value, dom.Element html) : super(html);
+  TypeEnumValue(this.value, dom.Element html, {bool experimental})
+      : super(html, experimental);
 }
 
 /**
@@ -371,7 +386,8 @@
 class TypeList extends TypeDecl {
   final TypeDecl itemType;
 
-  TypeList(this.itemType, dom.Element html) : super(html);
+  TypeList(this.itemType, dom.Element html, {bool experimental})
+      : super(html, experimental);
 
   accept(ApiVisitor visitor) => visitor.visitTypeList(this);
 }
@@ -392,7 +408,8 @@
    */
   final TypeDecl valueType;
 
-  TypeMap(this.keyType, this.valueType, dom.Element html) : super(html);
+  TypeMap(this.keyType, this.valueType, dom.Element html, {bool experimental})
+      : super(html, experimental);
 
   accept(ApiVisitor visitor) => visitor.visitTypeMap(this);
 }
@@ -403,7 +420,8 @@
 class TypeObject extends TypeDecl {
   final List<TypeObjectField> fields;
 
-  TypeObject(this.fields, dom.Element html) : super(html);
+  TypeObject(this.fields, dom.Element html, {bool experimental})
+      : super(html, experimental);
 
   accept(ApiVisitor visitor) => visitor.visitTypeObject(this);
 
@@ -434,8 +452,8 @@
   final Object value;
 
   TypeObjectField(this.name, this.type, dom.Element html,
-      {this.optional: false, this.value})
-      : super(html);
+      {this.optional: false, this.value, bool experimental})
+      : super(html, experimental);
 }
 
 /**
@@ -445,7 +463,8 @@
 class TypeReference extends TypeDecl {
   final String typeName;
 
-  TypeReference(this.typeName, dom.Element html) : super(html) {
+  TypeReference(this.typeName, dom.Element html, {bool experimental})
+      : super(html, experimental) {
     if (typeName.isEmpty) {
       throw new Exception('Empty type name');
     }
@@ -460,7 +479,8 @@
 class Types extends ApiNode with IterableMixin<TypeDefinition> {
   final Map<String, TypeDefinition> types;
 
-  Types(this.types, dom.Element html) : super(html);
+  Types(this.types, dom.Element html, {bool experimental})
+      : super(html, experimental);
 
   @override
   Iterator<TypeDefinition> get iterator => types.values.iterator;
@@ -483,7 +503,8 @@
    */
   final String field;
 
-  TypeUnion(this.choices, this.field, dom.Element html) : super(html);
+  TypeUnion(this.choices, this.field, dom.Element html, {bool experimental})
+      : super(html, experimental);
 
   accept(ApiVisitor visitor) => visitor.visitTypeUnion(this);
 }
diff --git a/pkg/analysis_server/tool/spec/check_all_test.dart b/pkg/analysis_server/tool/spec/check_all_test.dart
index f068f42..d43b320 100644
--- a/pkg/analysis_server/tool/spec/check_all_test.dart
+++ b/pkg/analysis_server/tool/spec/check_all_test.dart
@@ -6,9 +6,9 @@
 
 import 'dart:io';
 
+import 'package:analyzer/src/codegen/tools.dart';
 import 'package:path/path.dart';
 
-import 'codegen_tools.dart';
 import 'generate_all.dart';
 
 /**
@@ -17,26 +17,6 @@
  */
 main() {
   String script = Platform.script.toFilePath(windows: Platform.isWindows);
-  Directory.current = new Directory(dirname(script));
-  bool generateAllNeeded = false;
-  for (GeneratedContent generatedContent in allTargets) {
-    if (!generatedContent.check()) {
-      print(
-          '${generatedContent.outputFile.absolute} does not have expected contents.');
-      generateAllNeeded = true;
-    }
-  }
-  if (generateAllNeeded) {
-    print('Please regenerate using:');
-    String executable = Platform.executable;
-    String packageRoot = '';
-    if (Platform.packageRoot.isNotEmpty) {
-      packageRoot = ' --package-root=${Platform.packageRoot}';
-    }
-    String generateScript = join(dirname(script), 'generate_all.dart');
-    print('  $executable$packageRoot $generateScript');
-    exit(1);
-  } else {
-    print('All generated files up to date.');
-  }
+  String pkgPath = normalize(join(dirname(script), '..', '..'));
+  GeneratedContent.checkAll(pkgPath, 'tool/spec/generate_all.dart', allTargets);
 }
diff --git a/pkg/analysis_server/tool/spec/codegen_analysis_server.dart b/pkg/analysis_server/tool/spec/codegen_analysis_server.dart
index 8b3c897..323c39c 100644
--- a/pkg/analysis_server/tool/spec/codegen_analysis_server.dart
+++ b/pkg/analysis_server/tool/spec/codegen_analysis_server.dart
@@ -7,21 +7,15 @@
  */
 library java.generator.server;
 
+import 'package:analyzer/src/codegen/tools.dart';
+
 import 'api.dart';
 import 'codegen_java.dart';
-import 'codegen_tools.dart';
 
 final GeneratedFile target = javaGeneratedFile(
-    'generated/java/AnalysisServer.java',
+    'tool/spec/generated/java/AnalysisServer.java',
     (Api api) => new CodegenAnalysisServer(api));
 
-/**
- * Translate spec_input.html into AnalysisServer.java.
- */
-main() {
-  target.generate();
-}
-
 class CodegenAnalysisServer extends CodegenJavaVisitor {
   CodegenAnalysisServer(Api api) : super(api);
 
diff --git a/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart b/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
index b77f4ef..fc389a4 100644
--- a/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
+++ b/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
@@ -6,23 +6,16 @@
 
 import 'dart:convert';
 
+import 'package:analyzer/src/codegen/tools.dart';
 import 'package:html/dom.dart' as dom;
 
 import 'api.dart';
 import 'codegen_dart.dart';
-import 'codegen_tools.dart';
 import 'from_html.dart';
 import 'implied_types.dart';
 import 'to_html.dart';
 
 /**
- * Translate spec_input.html into protocol_matchers.dart.
- */
-main() {
-  target.generate();
-}
-
-/**
  * Special flags that need to be inserted into the declaration of the Element
  * class.
  */
@@ -35,9 +28,9 @@
   'deprecated': '0x20'
 };
 
-final GeneratedFile target =
-    new GeneratedFile('../../lib/plugin/protocol/generated_protocol.dart', () {
-  CodegenProtocolVisitor visitor = new CodegenProtocolVisitor(readApi());
+final GeneratedFile target = new GeneratedFile(
+    'lib/plugin/protocol/generated_protocol.dart', (String pkgPath) {
+  CodegenProtocolVisitor visitor = new CodegenProtocolVisitor(readApi(pkgPath));
   return visitor.collectCode(visitor.visitApi);
 });
 
diff --git a/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart b/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart
index bdc8910..3b5fde0 100644
--- a/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart
+++ b/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart
@@ -9,27 +9,21 @@
 
 import 'dart:convert';
 
+import 'package:analyzer/src/codegen/tools.dart';
+
 import 'api.dart';
 import 'codegen_dart.dart';
-import 'codegen_tools.dart';
 import 'from_html.dart';
 import 'to_html.dart';
 
 final GeneratedFile target = new GeneratedFile(
-    '../../test/integration/integration_test_methods.dart', () {
+    'test/integration/integration_test_methods.dart', (String pkgPath) {
   CodegenInttestMethodsVisitor visitor =
-      new CodegenInttestMethodsVisitor(readApi());
+      new CodegenInttestMethodsVisitor(readApi(pkgPath));
   return visitor.collectCode(visitor.visitApi);
 });
 
 /**
- * Translate spec_input.html into protocol_matchers.dart.
- */
-main() {
-  target.generate();
-}
-
-/**
  * Visitor that generates the code for integration_test_methods.dart
  */
 class CodegenInttestMethodsVisitor extends DartCodegenVisitor
@@ -108,7 +102,8 @@
     writeln("import 'dart:async';");
     writeln();
     writeln("import 'package:analysis_server/plugin/protocol/protocol.dart';");
-    writeln("import 'package:analysis_server/src/protocol/protocol_internal.dart';");
+    writeln(
+        "import 'package:analysis_server/src/protocol/protocol_internal.dart';");
     writeln("import 'package:unittest/unittest.dart';");
     writeln();
     writeln("import 'integration_tests.dart';");
diff --git a/pkg/analysis_server/tool/spec/codegen_java.dart b/pkg/analysis_server/tool/spec/codegen_java.dart
index a06af6b..3b7a4d2 100644
--- a/pkg/analysis_server/tool/spec/codegen_java.dart
+++ b/pkg/analysis_server/tool/spec/codegen_java.dart
@@ -7,10 +7,10 @@
  */
 library CodegenJava;
 
+import 'package:analyzer/src/codegen/tools.dart';
 import 'package:html/dom.dart' as dom;
 
 import 'api.dart';
-import 'codegen_tools.dart';
 import 'from_html.dart';
 import 'to_html.dart';
 
@@ -20,8 +20,8 @@
  */
 GeneratedFile javaGeneratedFile(
     String path, CodegenJavaVisitor createVisitor(Api api)) {
-  return new GeneratedFile(path, () {
-    CodegenJavaVisitor visitor = createVisitor(readApi());
+  return new GeneratedFile(path, (String pkgPath) {
+    CodegenJavaVisitor visitor = createVisitor(readApi(pkgPath));
     return visitor.collectCode(visitor.visitApi);
   });
 }
diff --git a/pkg/analysis_server/tool/spec/codegen_java_types.dart b/pkg/analysis_server/tool/spec/codegen_java_types.dart
index 2dec54c..0389ea4 100644
--- a/pkg/analysis_server/tool/spec/codegen_java_types.dart
+++ b/pkg/analysis_server/tool/spec/codegen_java_types.dart
@@ -7,69 +7,14 @@
  */
 library java.generator.types;
 
+import 'package:analyzer/src/codegen/tools.dart';
 import 'package:html/dom.dart' as dom;
 
 import 'api.dart';
 import 'codegen_java.dart';
-import 'codegen_tools.dart';
 import 'from_html.dart';
 import 'implied_types.dart';
 
-final String pathToGenTypes = 'generated/java/types/';
-
-final GeneratedDirectory targetDir = new GeneratedDirectory(pathToGenTypes, () {
-  Api api = readApi();
-  Map<String, ImpliedType> impliedTypes = computeImpliedTypes(api);
-  Map<String, FileContentsComputer> map =
-      new Map<String, FileContentsComputer>();
-  for (ImpliedType impliedType in impliedTypes.values) {
-    String typeNameInSpec = capitalize(impliedType.camelName);
-    bool isRefactoringFeedback = impliedType.kind == 'refactoringFeedback';
-    bool isRefactoringOption = impliedType.kind == 'refactoringOptions';
-    if (impliedType.kind == 'typeDefinition' ||
-        isRefactoringFeedback ||
-        isRefactoringOption) {
-      TypeDecl type = impliedType.type;
-      if (type is TypeObject || type is TypeEnum) {
-        // This is for situations such as 'Override' where the name in the spec
-        // doesn't match the java object that we generate:
-        String typeNameInJava = typeNameInSpec;
-        if (_typeRenames.containsKey(typeNameInSpec)) {
-          typeNameInJava = _typeRenames[typeNameInSpec];
-        }
-        map['${typeNameInJava}.java'] = () {
-          String superclassName = null;
-          if (isRefactoringFeedback) {
-            superclassName = 'RefactoringFeedback';
-          }
-          if (isRefactoringOption) {
-            superclassName = 'RefactoringOptions';
-          }
-          // configure accessors
-          bool generateGetters = true;
-          bool generateSetters = false;
-          if (isRefactoringOption ||
-              typeNameInSpec == 'Outline' ||
-              typeNameInSpec == 'RefactoringMethodParameter') {
-            generateSetters = true;
-          }
-          // create the visitor
-          CodegenJavaType visitor = new CodegenJavaType(api, typeNameInJava,
-              superclassName, generateGetters, generateSetters);
-          return visitor.collectCode(() {
-            dom.Element doc = type.html;
-            if (impliedType.apiNode is TypeDefinition) {
-              doc = (impliedType.apiNode as TypeDefinition).html;
-            }
-            visitor.emitType(type, doc);
-          });
-        };
-      }
-    }
-  }
-  return map;
-});
-
 /**
  * A map between the field names and values for the Element object such as:
  *
@@ -105,12 +50,62 @@
  */
 const Map<String, String> _typeRenames = const {'Override': 'OverrideMember',};
 
-/**
- * Translate spec_input.html into AnalysisServer.java.
- */
-main() {
-  targetDir.generate();
-}
+final String pathToGenTypes = 'tool/spec/generated/java/types';
+
+final GeneratedDirectory targetDir =
+    new GeneratedDirectory(pathToGenTypes, (String pkgPath) {
+  Api api = readApi(pkgPath);
+  Map<String, ImpliedType> impliedTypes = computeImpliedTypes(api);
+  Map<String, FileContentsComputer> map =
+      new Map<String, FileContentsComputer>();
+  for (ImpliedType impliedType in impliedTypes.values) {
+    String typeNameInSpec = capitalize(impliedType.camelName);
+    bool isRefactoringFeedback = impliedType.kind == 'refactoringFeedback';
+    bool isRefactoringOption = impliedType.kind == 'refactoringOptions';
+    if (impliedType.kind == 'typeDefinition' ||
+        isRefactoringFeedback ||
+        isRefactoringOption) {
+      TypeDecl type = impliedType.type;
+      if (type is TypeObject || type is TypeEnum) {
+        // This is for situations such as 'Override' where the name in the spec
+        // doesn't match the java object that we generate:
+        String typeNameInJava = typeNameInSpec;
+        if (_typeRenames.containsKey(typeNameInSpec)) {
+          typeNameInJava = _typeRenames[typeNameInSpec];
+        }
+        map['${typeNameInJava}.java'] = (String pkgPath) {
+          String superclassName = null;
+          if (isRefactoringFeedback) {
+            superclassName = 'RefactoringFeedback';
+          }
+          if (isRefactoringOption) {
+            superclassName = 'RefactoringOptions';
+          }
+          // configure accessors
+          bool generateGetters = true;
+          bool generateSetters = false;
+          if (isRefactoringOption ||
+              typeNameInSpec == 'Outline' ||
+              typeNameInSpec == 'RefactoringMethodParameter') {
+            generateSetters = true;
+          }
+          // create the visitor
+          CodegenJavaType visitor = new CodegenJavaType(api, typeNameInJava,
+              superclassName, generateGetters, generateSetters);
+          return visitor.collectCode(() {
+            dom.Element doc = type.html;
+            if (impliedType.apiNode is TypeDefinition) {
+              doc = (impliedType.apiNode as TypeDefinition).html;
+            }
+            visitor.emitType(type, doc);
+          });
+        };
+      }
+    }
+  }
+  print(map.keys);
+  return map;
+});
 
 class CodegenJavaType extends CodegenJavaVisitor {
   final String className;
diff --git a/pkg/analysis_server/tool/spec/codegen_matchers.dart b/pkg/analysis_server/tool/spec/codegen_matchers.dart
index 5786493..be2f847 100644
--- a/pkg/analysis_server/tool/spec/codegen_matchers.dart
+++ b/pkg/analysis_server/tool/spec/codegen_matchers.dart
@@ -9,25 +9,19 @@
 
 import 'dart:convert';
 
+import 'package:analyzer/src/codegen/tools.dart';
+
 import 'api.dart';
-import 'codegen_tools.dart';
 import 'from_html.dart';
 import 'implied_types.dart';
 import 'to_html.dart';
 
-final GeneratedFile target =
-    new GeneratedFile('../../test/integration/protocol_matchers.dart', () {
-  CodegenMatchersVisitor visitor = new CodegenMatchersVisitor(readApi());
+final GeneratedFile target = new GeneratedFile(
+    'test/integration/protocol_matchers.dart', (String pkgPath) {
+  CodegenMatchersVisitor visitor = new CodegenMatchersVisitor(readApi(pkgPath));
   return visitor.collectCode(visitor.visitApi);
 });
 
-/**
- * Translate spec_input.html into protocol_matchers.dart.
- */
-main() {
-  target.generate();
-}
-
 class CodegenMatchersVisitor extends HierarchicalApiVisitor with CodeGenerator {
   /**
    * Visitor used to produce doc comments.
diff --git a/pkg/analysis_server/tool/spec/codegen_tools.dart b/pkg/analysis_server/tool/spec/codegen_tools.dart
deleted file mode 100644
index f3fcb5d..0000000
--- a/pkg/analysis_server/tool/spec/codegen_tools.dart
+++ /dev/null
@@ -1,557 +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.
-
-/**
- * Tools for code generation.
- */
-library codegen.tools;
-
-import 'dart:io';
-
-import 'package:html/dom.dart' as dom;
-import 'package:path/path.dart';
-
-import 'html_tools.dart';
-import 'text_formatter.dart';
-
-final RegExp trailingWhitespaceRegExp = new RegExp(r'[\n ]+$');
-final RegExp trailingSpacesInLineRegExp = new RegExp(r' +$', multiLine: true);
-
-/**
- * Join the given strings using camelCase.  If [doCapitalize] is true, the first
- * part will be capitalized as well.
- */
-String camelJoin(List<String> parts, {bool doCapitalize: false}) {
-  List<String> upcasedParts = <String>[];
-  for (int i = 0; i < parts.length; i++) {
-    if (i == 0 && !doCapitalize) {
-      upcasedParts.add(parts[i]);
-    } else {
-      upcasedParts.add(capitalize(parts[i]));
-    }
-  }
-  return upcasedParts.join();
-}
-
-/**
- * Capitalize and return the passed String.
- */
-String capitalize(String string) {
-  return string[0].toUpperCase() + string.substring(1);
-}
-
-/**
- * Type of functions used to compute the contents of a set of generated files.
- */
-typedef Map<String, FileContentsComputer> DirectoryContentsComputer();
-
-/**
- * Type of functions used to compute the contents of a generated file.
- */
-typedef String FileContentsComputer();
-
-/**
- * Mixin class for generating code.
- */
-class CodeGenerator {
-  _CodeGeneratorState _state;
-
-  /**
-   * Settings that specialize code generation behavior for a given
-   * programming language.
-   */
-  CodeGeneratorSettings codeGeneratorSettings = new CodeGeneratorSettings();
-
-  /**
-   * Measure the width of the current indentation level.
-   */
-  int get indentWidth => _state.nextIndent.length;
-
-  /**
-   * Execute [callback], collecting any code that is output using [write]
-   * or [writeln], and return the result as a string.
-   */
-  String collectCode(void callback(), {bool removeTrailingNewLine: false}) {
-    _CodeGeneratorState oldState = _state;
-    try {
-      _state = new _CodeGeneratorState();
-      callback();
-      var text =
-          _state.buffer.toString().replaceAll(trailingSpacesInLineRegExp, '');
-      if (!removeTrailingNewLine) {
-        return text;
-      } else {
-        return text.replaceAll(trailingWhitespaceRegExp, '');
-      }
-    } finally {
-      _state = oldState;
-    }
-  }
-
-  /**
-   * Generate a doc comment based on the HTML in [docs].
-   *
-   * When generating java code, the output is compatible with Javadoc, which
-   * understands certain HTML constructs.
-   */
-  void docComment(List<dom.Node> docs, {bool removeTrailingNewLine: false}) {
-    if (containsOnlyWhitespace(docs)) return;
-    writeln(codeGeneratorSettings.docCommentStartMarker);
-    int width = codeGeneratorSettings.commentLineLength;
-    bool javadocStyle = codeGeneratorSettings.languageName == 'java';
-    indentBy(codeGeneratorSettings.docCommentLineLeader, () {
-      write(nodesToText(docs, width - _state.indent.length, javadocStyle,
-          removeTrailingNewLine: removeTrailingNewLine));
-    });
-    writeln(codeGeneratorSettings.docCommentEndMarker);
-  }
-
-  /**
-   * Execute [callback], indenting any code it outputs.
-   */
-  void indent(void callback()) {
-    indentSpecial(
-        codeGeneratorSettings.indent, codeGeneratorSettings.indent, callback);
-  }
-
-  /**
-   * Execute [callback], using [additionalIndent] to indent any code it outputs.
-   */
-  void indentBy(String additionalIndent, void callback()) =>
-      indentSpecial(additionalIndent, additionalIndent, callback);
-
-  /**
-   * Execute [callback], using [additionalIndent] to indent any code it outputs.
-   * The first line of output is indented by [firstAdditionalIndent] instead of
-   * [additionalIndent].
-   */
-  void indentSpecial(
-      String firstAdditionalIndent, String additionalIndent, void callback()) {
-    String oldNextIndent = _state.nextIndent;
-    String oldIndent = _state.indent;
-    try {
-      _state.nextIndent += firstAdditionalIndent;
-      _state.indent += additionalIndent;
-      callback();
-    } finally {
-      _state.nextIndent = oldNextIndent;
-      _state.indent = oldIndent;
-    }
-  }
-
-  void lineComment(List<dom.Node> docs) {
-    if (containsOnlyWhitespace(docs)) {
-      return;
-    }
-    write(codeGeneratorSettings.lineCommentLineLeader);
-    int width = codeGeneratorSettings.commentLineLength;
-    indentBy(codeGeneratorSettings.lineCommentLineLeader, () {
-      write(nodesToText(docs, width - _state.indent.length, false));
-    });
-  }
-
-  void outputHeader({bool javaStyle: false}) {
-    String header;
-    if (codeGeneratorSettings.languageName == 'java') {
-      header = '''
-/*
- * Copyright (c) 2014, the Dart project authors.
- *
- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- *
- * This file has been automatically generated.  Please do not edit it manually.
- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
- */''';
-    } else if (codeGeneratorSettings.languageName == 'python') {
-      header = '''
-# 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 file has been automatically generated.  Please do not edit it manually.
-# To regenerate the file, use the script
-# "pkg/analysis_server/tool/spec/generate_files".
-''';
-    } else {
-      header = '''
-// 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 file has been automatically generated.  Please do not edit it manually.
-// To regenerate the file, use the script
-// "pkg/analysis_server/tool/spec/generate_files".
-''';
-    }
-    writeln(header.trim());
-  }
-
-  /**
-   * Output text without ending the current line.
-   */
-  void write(Object obj) {
-    _state.write(obj.toString());
-  }
-
-  /**
-   * Output text, ending the current line.
-   */
-  void writeln([Object obj = '']) {
-    _state.write('$obj\n');
-  }
-}
-
-/**
- * Controls several settings of [CodeGenerator].
- *
- * The default settings are valid for generating Java and Dart code.
- */
-class CodeGeneratorSettings {
-  /**
-   * Name of the language being generated. Lowercase.
-   */
-  String languageName;
-
-  /**
-   * Marker used in line comments.
-   */
-  String lineCommentLineLeader;
-
-  /**
-   * Start marker for doc comments.
-   */
-  String docCommentStartMarker;
-
-  /**
-   * Line leader for body lines in doc comments.
-   */
-  String docCommentLineLeader;
-
-  /**
-   * End marker for doc comments.
-   */
-  String docCommentEndMarker;
-
-  /**
-   * Line length for doc comment lines.
-   */
-  int commentLineLength;
-
-  /**
-   * String used for indenting code.
-   */
-  String indent;
-
-  CodeGeneratorSettings(
-      {this.languageName: 'java',
-      this.lineCommentLineLeader: '// ',
-      this.docCommentStartMarker: '/**',
-      this.docCommentLineLeader: ' * ',
-      this.docCommentEndMarker: ' */',
-      this.commentLineLength: 99,
-      this.indent: '  '});
-}
-
-abstract class GeneratedContent {
-  FileSystemEntity get outputFile;
-  bool check();
-  void generate();
-}
-
-/**
- * Class representing a single output directory (either generated code or
- * generated HTML). No other content should exist in the directory.
- */
-class GeneratedDirectory extends GeneratedContent {
-  /**
-   * The path to the directory that will have the generated content.
-   */
-  final String outputDirPath;
-
-  /**
-   * Callback function that computes the directory contents.
-   */
-  final DirectoryContentsComputer directoryContentsComputer;
-
-  GeneratedDirectory(this.outputDirPath, this.directoryContentsComputer);
-
-  /**
-   * Get a Directory object representing the output directory.
-   */
-  Directory get outputFile =>
-      new Directory(joinAll(posix.split(outputDirPath)));
-
-  /**
-   * Check whether the directory has the correct contents, and return true if it
-   * does.
-   */
-  @override
-  bool check() {
-    Map<String, FileContentsComputer> map = directoryContentsComputer();
-    try {
-      for (String file in map.keys) {
-        FileContentsComputer fileContentsComputer = map[file];
-        String expectedContents = fileContentsComputer();
-        File outputFile =
-            new File(joinAll(posix.split(posix.join(outputDirPath, file))));
-        String actualContents = outputFile.readAsStringSync();
-        // Normalize Windows line endings to Unix line endings so that the
-        // comparison doesn't fail on Windows.
-        actualContents = actualContents.replaceAll('\r\n', '\n');
-        if (expectedContents != actualContents) {
-          return false;
-        }
-      }
-      int nonHiddenFileCount = 0;
-      outputFile
-          .listSync(recursive: false, followLinks: false)
-          .forEach((FileSystemEntity fileSystemEntity) {
-        if (fileSystemEntity is File &&
-            !basename(fileSystemEntity.path).startsWith('.')) {
-          nonHiddenFileCount++;
-        }
-      });
-      if (nonHiddenFileCount != map.length) {
-        // The number of files generated doesn't match the number we expected to
-        // generate.
-        return false;
-      }
-    } catch (e) {
-      // There was a problem reading the file (most likely because it didn't
-      // exist).  Treat that the same as if the file doesn't have the expected
-      // contents.
-      return false;
-    }
-    return true;
-  }
-
-  /**
-   * Replace the directory with the correct contents.  [spec] is the "tool/spec"
-   * directory.  If [spec] is unspecified, it is assumed to be the directory
-   * containing Platform.executable.
-   */
-  @override
-  void generate() {
-    try {
-      // delete the contents of the directory (and the directory itself)
-      outputFile.deleteSync(recursive: true);
-    } catch (e) {
-      // Error caught while trying to delete the directory, this can happen if
-      // it didn't yet exist.
-    }
-    // re-create the empty directory
-    outputFile.createSync(recursive: true);
-
-    // generate all of the files in the directory
-    Map<String, FileContentsComputer> map = directoryContentsComputer();
-    map.forEach((String file, FileContentsComputer fileContentsComputer) {
-      File outputFile = new File(joinAll(posix.split(outputDirPath + file)));
-      outputFile.writeAsStringSync(fileContentsComputer());
-    });
-  }
-}
-
-/**
- * Class representing a single output file (either generated code or generated
- * HTML).
- */
-class GeneratedFile extends GeneratedContent {
-  /**
-   * The output file to which generated output should be written, relative to
-   * the "tool/spec" directory.  This filename uses the posix path separator
-   * ('/') regardless of the OS.
-   */
-  final String outputPath;
-
-  /**
-   * Callback function which computes the file.
-   */
-  final FileContentsComputer computeContents;
-
-  GeneratedFile(this.outputPath, this.computeContents);
-
-  /**
-   * Get a File object representing the output file.
-   */
-  File get outputFile => new File(joinAll(posix.split(outputPath)));
-
-  /**
-   * Check whether the file has the correct contents, and return true if it
-   * does.
-   */
-  @override
-  bool check() {
-    String expectedContents = computeContents();
-    try {
-      String actualContents = outputFile.readAsStringSync();
-      // Normalize Windows line endings to Unix line endings so that the
-      // comparison doesn't fail on Windows.
-      actualContents = actualContents.replaceAll('\r\n', '\n');
-      return expectedContents == actualContents;
-    } catch (e) {
-      // There was a problem reading the file (most likely because it didn't
-      // exist).  Treat that the same as if the file doesn't have the expected
-      // contents.
-      return false;
-    }
-  }
-
-  /**
-   * Replace the file with the correct contents.  [spec] is the "tool/spec"
-   * directory.  If [spec] is unspecified, it is assumed to be the directory
-   * containing Platform.executable.
-   */
-  void generate() {
-    outputFile.writeAsStringSync(computeContents());
-  }
-}
-
-/**
- * Mixin class for generating HTML representations of code that are suitable
- * for enclosing inside a <pre> element.
- */
-abstract class HtmlCodeGenerator {
-  _HtmlCodeGeneratorState _state;
-
-  /**
-   * Add the given [node] to the HTML output.
-   */
-  void add(dom.Node node) {
-    _state.add(node);
-  }
-
-  /**
-   * Add the given [nodes] to the HTML output.
-   */
-  void addAll(Iterable<dom.Node> nodes) {
-    for (dom.Node node in nodes) {
-      _state.add(node);
-    }
-  }
-
-  /**
-   * Execute [callback], collecting any code that is output using [write],
-   * [writeln], [add], or [addAll], and return the result as a list of DOM
-   * nodes.
-   */
-  List<dom.Node> collectHtml(void callback()) {
-    _HtmlCodeGeneratorState oldState = _state;
-    try {
-      _state = new _HtmlCodeGeneratorState();
-      if (callback != null) {
-        callback();
-      }
-      return _state.buffer;
-    } finally {
-      _state = oldState;
-    }
-  }
-
-  /**
-   * Execute [callback], wrapping its output in an element with the given
-   * [name] and [attributes].
-   */
-  void element(String name, Map<String, String> attributes, [void callback()]) {
-    add(makeElement(name, attributes, collectHtml(callback)));
-  }
-
-  /**
-   * Execute [callback], indenting any code it outputs by two spaces.
-   */
-  void indent(void callback()) {
-    String oldIndent = _state.indent;
-    try {
-      _state.indent += '  ';
-      callback();
-    } finally {
-      _state.indent = oldIndent;
-    }
-  }
-
-  /**
-   * Output text without ending the current line.
-   */
-  void write(Object obj) {
-    _state.write(obj.toString());
-  }
-
-  /**
-   * Output text, ending the current line.
-   */
-  void writeln([Object obj = '']) {
-    _state.write('$obj\n');
-  }
-}
-
-/**
- * State used by [CodeGenerator].
- */
-class _CodeGeneratorState {
-  StringBuffer buffer = new StringBuffer();
-  String nextIndent = '';
-  String indent = '';
-  bool indentNeeded = true;
-
-  void write(String text) {
-    List<String> lines = text.split('\n');
-    for (int i = 0; i < lines.length; i++) {
-      if (i == lines.length - 1 && lines[i].isEmpty) {
-        break;
-      }
-      if (indentNeeded) {
-        buffer.write(nextIndent);
-        nextIndent = indent;
-      }
-      indentNeeded = false;
-      buffer.write(lines[i]);
-      if (i != lines.length - 1) {
-        buffer.writeln();
-        indentNeeded = true;
-      }
-    }
-  }
-}
-
-/**
- * State used by [HtmlCodeGenerator].
- */
-class _HtmlCodeGeneratorState {
-  List<dom.Node> buffer = <dom.Node>[];
-  String indent = '';
-  bool indentNeeded = true;
-
-  void add(dom.Node node) {
-    if (node is dom.Text) {
-      write(node.text);
-    } else {
-      buffer.add(node);
-    }
-  }
-
-  void write(String text) {
-    if (text.isEmpty) {
-      return;
-    }
-    if (indentNeeded) {
-      buffer.add(new dom.Text(indent));
-    }
-    List<String> lines = text.split('\n');
-    if (lines.last.isEmpty) {
-      lines.removeLast();
-      buffer.add(new dom.Text(lines.join('\n$indent') + '\n'));
-      indentNeeded = true;
-    } else {
-      buffer.add(new dom.Text(lines.join('\n$indent')));
-      indentNeeded = false;
-    }
-  }
-}
diff --git a/pkg/analysis_server/tool/spec/from_html.dart b/pkg/analysis_server/tool/spec/from_html.dart
index 1ae9425..2ff2fe8 100644
--- a/pkg/analysis_server/tool/spec/from_html.dart
+++ b/pkg/analysis_server/tool/spec/from_html.dart
@@ -9,11 +9,12 @@
 
 import 'dart:io';
 
+import 'package:analyzer/src/codegen/html.dart';
 import 'package:html/dom.dart' as dom;
 import 'package:html/parser.dart' as parser;
+import 'package:path/path.dart';
 
 import 'api.dart';
-import 'html_tools.dart';
 
 const List<String> specialElements = const [
   'domain',
@@ -137,8 +138,10 @@
 Domain domainFromHtml(dom.Element html) {
   checkName(html, 'domain');
   String name = html.attributes['name'];
-  String context = name != null ? name : 'domain';
-  checkAttributes(html, ['name'], context);
+  String context = name ?? 'domain';
+  bool experimental = html.attributes['experimental'] == 'true';
+  checkAttributes(html, ['name'], context,
+      optionalAttributes: ['experimental']);
   List<Request> requests = <Request>[];
   List<Notification> notifications = <Notification>[];
   recurse(html, context, {
@@ -149,7 +152,8 @@
       notifications.add(notificationFromHtml(child, context));
     }
   });
-  return new Domain(name, requests, notifications, html);
+  return new Domain(name, requests, notifications, html,
+      experimental: experimental);
 }
 
 dom.Element getAncestor(dom.Element html, String name, String context) {
@@ -287,10 +291,11 @@
 }
 
 /**
- * Read the API description from the file 'spec_input.html'.
+ * Read the API description from the file 'spec_input.html'.  [pkgPath] is the
+ * path to the current package.
  */
-Api readApi() {
-  File htmlFile = new File('spec_input.html');
+Api readApi(String pkgPath) {
+  File htmlFile = new File(join(pkgPath, 'tool', 'spec', 'spec_input.html'));
   String htmlContents = htmlFile.readAsStringSync();
   dom.Document document = parser.parse(htmlContents);
   dom.Element htmlElement = document.children
@@ -418,9 +423,10 @@
   checkName(html, 'type');
   String name = html.attributes['name'];
   String context = name != null ? name : 'type';
-  checkAttributes(html, ['name'], context);
+  checkAttributes(html, ['name'], context, optionalAttributes: ['experimental']);
   TypeDecl type = processContentsAsType(html, context);
-  return new TypeDefinition(name, type, html);
+  bool experimental = html.attributes['experimental'] == 'true';
+  return new TypeDefinition(name, type, html, experimental: experimental);
 }
 
 /**
@@ -511,14 +517,15 @@
  * Create a [TypeObject] from an HTML description.
  */
 TypeObject typeObjectFromHtml(dom.Element html, String context) {
-  checkAttributes(html, [], context);
+  checkAttributes(html, [], context,  optionalAttributes: ['experimental']);
   List<TypeObjectField> fields = <TypeObjectField>[];
   recurse(html, context, {
     'field': (dom.Element child) {
       fields.add(typeObjectFieldFromHtml(child, context));
     }
   });
-  return new TypeObject(fields, html);
+  bool experimental = html.attributes['experimental'] == 'true';
+  return new TypeObject(fields, html, experimental: experimental);
 }
 
 /**
diff --git a/pkg/analysis_server/tool/spec/generate_all.dart b/pkg/analysis_server/tool/spec/generate_all.dart
index 00489bd..74d4307 100644
--- a/pkg/analysis_server/tool/spec/generate_all.dart
+++ b/pkg/analysis_server/tool/spec/generate_all.dart
@@ -6,6 +6,7 @@
 
 import 'dart:io';
 
+import 'package:analyzer/src/codegen/tools.dart';
 import 'package:path/path.dart';
 
 import 'codegen_analysis_server.dart' as codegen_analysis_server;
@@ -13,10 +14,18 @@
 import 'codegen_inttest_methods.dart' as codegen_inttest_methods;
 import 'codegen_java_types.dart' as codegen_java_types;
 import 'codegen_matchers.dart' as codegen_matchers;
-import 'codegen_tools.dart';
 import 'to_html.dart' as to_html;
 
 /**
+ * Generate all targets
+ */
+main() {
+  String script = Platform.script.toFilePath(windows: Platform.isWindows);
+  String pkgPath = normalize(join(dirname(script), '..', '..'));
+  GeneratedContent.generateAll(pkgPath, allTargets);
+}
+
+/**
  * Get a list of all generated targets.
  */
 List<GeneratedContent> get allTargets {
@@ -29,14 +38,3 @@
   targets.add(to_html.target);
   return targets;
 }
-
-/**
- * Generate all targets
- */
-main() {
-  String script = Platform.script.toFilePath(windows: Platform.isWindows);
-  Directory.current = new Directory(dirname(script));
-  for (GeneratedContent generatedContent in allTargets) {
-    generatedContent.generate();
-  }
-}
diff --git a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
index 83223c6..43a520f 100644
--- a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
+++ b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
@@ -273,6 +273,13 @@
   public void completion_getSuggestions(String file, int offset, GetSuggestionsConsumer consumer);
 
   /**
+   * {@code diagnostic.getDiagnostics}
+   *
+   * Return server diagnostics.
+   */
+  public void diagnostic_getDiagnostics(GetDiagnosticsConsumer consumer);
+
+  /**
    * {@code edit.format}
    *
    * Format the contents of a single file. The currently selected region of text is passed in so that
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AddContentOverlay.java b/pkg/analysis_server/tool/spec/generated/java/types/AddContentOverlay.java
index 9d9c428..74249ca 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AddContentOverlay.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AddContentOverlay.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisError.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisError.java
index baf27c0..9020207 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisError.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisError.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorFixes.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorFixes.java
index 6a53f63..0837dac 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorFixes.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorFixes.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorSeverity.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorSeverity.java
index 6396fc2..e07df40 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorSeverity.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorSeverity.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorType.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorType.java
index d4ea8d7..db6fe76 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorType.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorType.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisOptions.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisOptions.java
index afdde92..6f99a38 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisOptions.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisOptions.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisService.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisService.java
index 02bd9f6..407a650 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisService.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisStatus.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisStatus.java
index d738660..1a0cb7f 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisStatus.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisStatus.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ChangeContentOverlay.java b/pkg/analysis_server/tool/spec/generated/java/types/ChangeContentOverlay.java
index 469e3dc..e7b4062 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ChangeContentOverlay.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ChangeContentOverlay.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestion.java b/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestion.java
index a69eee1..4cffa50 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestion.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestion.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestionKind.java b/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestionKind.java
index 71f8761..3cebeab 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestionKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestionKind.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ContextData.java b/pkg/analysis_server/tool/spec/generated/java/types/ContextData.java
new file mode 100644
index 0000000..ab4020c
--- /dev/null
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ContextData.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2015, the Dart project authors.
+ *
+ * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ *
+ * This file has been automatically generated.  Please do not edit it manually.
+ * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
+ */
+package org.dartlang.analysis.server.protocol;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import com.google.common.collect.Lists;
+import com.google.dart.server.utilities.general.JsonUtilities;
+import com.google.dart.server.utilities.general.ObjectUtilities;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import java.util.ArrayList;
+import java.util.Iterator;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * Information about an analysis context.
+ *
+ * @coverage dart.server.generated.types
+ */
+@SuppressWarnings("unused")
+public class ContextData {
+
+  public static final ContextData[] EMPTY_ARRAY = new ContextData[0];
+
+  public static final List<ContextData> EMPTY_LIST = Lists.newArrayList();
+
+  /**
+   * The name of the context.
+   */
+  private final String name;
+
+  /**
+   * Explicitly analyzed files.
+   */
+  private final int explicitFileCount;
+
+  /**
+   * Implicitly analyzed files.
+   */
+  private final int implicitFileCount;
+
+  /**
+   * The number of work items in the queue.
+   */
+  private final int workItemQueueLength;
+
+  /**
+   * Exceptions associated with cache entries.
+   */
+  private final List<String> cacheEntryExceptions;
+
+  /**
+   * Constructor for {@link ContextData}.
+   */
+  public ContextData(String name, int explicitFileCount, int implicitFileCount, int workItemQueueLength, List<String> cacheEntryExceptions) {
+    this.name = name;
+    this.explicitFileCount = explicitFileCount;
+    this.implicitFileCount = implicitFileCount;
+    this.workItemQueueLength = workItemQueueLength;
+    this.cacheEntryExceptions = cacheEntryExceptions;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj instanceof ContextData) {
+      ContextData other = (ContextData) obj;
+      return
+        ObjectUtilities.equals(other.name, name) &&
+        other.explicitFileCount == explicitFileCount &&
+        other.implicitFileCount == implicitFileCount &&
+        other.workItemQueueLength == workItemQueueLength &&
+        ObjectUtilities.equals(other.cacheEntryExceptions, cacheEntryExceptions);
+    }
+    return false;
+  }
+
+  public static ContextData fromJson(JsonObject jsonObject) {
+    String name = jsonObject.get("name").getAsString();
+    int explicitFileCount = jsonObject.get("explicitFileCount").getAsInt();
+    int implicitFileCount = jsonObject.get("implicitFileCount").getAsInt();
+    int workItemQueueLength = jsonObject.get("workItemQueueLength").getAsInt();
+    List<String> cacheEntryExceptions = JsonUtilities.decodeStringList(jsonObject.get("cacheEntryExceptions").getAsJsonArray());
+    return new ContextData(name, explicitFileCount, implicitFileCount, workItemQueueLength, cacheEntryExceptions);
+  }
+
+  public static List<ContextData> fromJsonArray(JsonArray jsonArray) {
+    if (jsonArray == null) {
+      return EMPTY_LIST;
+    }
+    ArrayList<ContextData> list = new ArrayList<ContextData>(jsonArray.size());
+    Iterator<JsonElement> iterator = jsonArray.iterator();
+    while (iterator.hasNext()) {
+      list.add(fromJson(iterator.next().getAsJsonObject()));
+    }
+    return list;
+  }
+
+  /**
+   * Exceptions associated with cache entries.
+   */
+  public List<String> getCacheEntryExceptions() {
+    return cacheEntryExceptions;
+  }
+
+  /**
+   * Explicitly analyzed files.
+   */
+  public int getExplicitFileCount() {
+    return explicitFileCount;
+  }
+
+  /**
+   * Implicitly analyzed files.
+   */
+  public int getImplicitFileCount() {
+    return implicitFileCount;
+  }
+
+  /**
+   * The name of the context.
+   */
+  public String getName() {
+    return name;
+  }
+
+  /**
+   * The number of work items in the queue.
+   */
+  public int getWorkItemQueueLength() {
+    return workItemQueueLength;
+  }
+
+  @Override
+  public int hashCode() {
+    HashCodeBuilder builder = new HashCodeBuilder();
+    builder.append(name);
+    builder.append(explicitFileCount);
+    builder.append(implicitFileCount);
+    builder.append(workItemQueueLength);
+    builder.append(cacheEntryExceptions);
+    return builder.toHashCode();
+  }
+
+  public JsonObject toJson() {
+    JsonObject jsonObject = new JsonObject();
+    jsonObject.addProperty("name", name);
+    jsonObject.addProperty("explicitFileCount", explicitFileCount);
+    jsonObject.addProperty("implicitFileCount", implicitFileCount);
+    jsonObject.addProperty("workItemQueueLength", workItemQueueLength);
+    JsonArray jsonArrayCacheEntryExceptions = new JsonArray();
+    for (String elt : cacheEntryExceptions) {
+      jsonArrayCacheEntryExceptions.add(new JsonPrimitive(elt));
+    }
+    jsonObject.add("cacheEntryExceptions", jsonArrayCacheEntryExceptions);
+    return jsonObject;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder builder = new StringBuilder();
+    builder.append("[");
+    builder.append("name=");
+    builder.append(name + ", ");
+    builder.append("explicitFileCount=");
+    builder.append(explicitFileCount + ", ");
+    builder.append("implicitFileCount=");
+    builder.append(implicitFileCount + ", ");
+    builder.append("workItemQueueLength=");
+    builder.append(workItemQueueLength + ", ");
+    builder.append("cacheEntryExceptions=");
+    builder.append(StringUtils.join(cacheEntryExceptions, ", "));
+    builder.append("]");
+    return builder.toString();
+  }
+
+}
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/Element.java b/pkg/analysis_server/tool/spec/generated/java/types/Element.java
index 51115ec..579ef3f 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/Element.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/Element.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ElementKind.java b/pkg/analysis_server/tool/spec/generated/java/types/ElementKind.java
index b84c921..14783c3 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ElementKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ElementKind.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ExecutableFile.java b/pkg/analysis_server/tool/spec/generated/java/types/ExecutableFile.java
index aee28ae..52f0c95 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ExecutableFile.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ExecutableFile.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ExecutableKind.java b/pkg/analysis_server/tool/spec/generated/java/types/ExecutableKind.java
index 3b3f1b8..407f368 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ExecutableKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ExecutableKind.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ExecutionService.java b/pkg/analysis_server/tool/spec/generated/java/types/ExecutionService.java
index 362368b..0e1b005 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ExecutionService.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ExecutionService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableFeedback.java b/pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableFeedback.java
index e00506d..8058954 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableFeedback.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableFeedback.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
@@ -96,8 +96,8 @@
   }
 
   public static ExtractLocalVariableFeedback fromJson(JsonObject jsonObject) {
-    int[] coveringExpressionOffsets = JsonUtilities.decodeIntArray(jsonObject.get("coveringExpressionOffsets").getAsJsonArray());
-    int[] coveringExpressionLengths = JsonUtilities.decodeIntArray(jsonObject.get("coveringExpressionLengths").getAsJsonArray());
+    int[] coveringExpressionOffsets = jsonObject.get("coveringExpressionOffsets") == null ? null : JsonUtilities.decodeIntArray(jsonObject.get("coveringExpressionOffsets").getAsJsonArray());
+    int[] coveringExpressionLengths = jsonObject.get("coveringExpressionLengths") == null ? null : JsonUtilities.decodeIntArray(jsonObject.get("coveringExpressionLengths").getAsJsonArray());
     List<String> names = JsonUtilities.decodeStringList(jsonObject.get("names").getAsJsonArray());
     int[] offsets = JsonUtilities.decodeIntArray(jsonObject.get("offsets").getAsJsonArray());
     int[] lengths = JsonUtilities.decodeIntArray(jsonObject.get("lengths").getAsJsonArray());
@@ -168,16 +168,20 @@
 
   public JsonObject toJson() {
     JsonObject jsonObject = new JsonObject();
-    JsonArray jsonArrayCoveringExpressionOffsets = new JsonArray();
-    for (int elt : coveringExpressionOffsets) {
-      jsonArrayCoveringExpressionOffsets.add(new JsonPrimitive(elt));
+    if (coveringExpressionOffsets != null) {
+      JsonArray jsonArrayCoveringExpressionOffsets = new JsonArray();
+      for (int elt : coveringExpressionOffsets) {
+        jsonArrayCoveringExpressionOffsets.add(new JsonPrimitive(elt));
+      }
+      jsonObject.add("coveringExpressionOffsets", jsonArrayCoveringExpressionOffsets);
     }
-    jsonObject.add("coveringExpressionOffsets", jsonArrayCoveringExpressionOffsets);
-    JsonArray jsonArrayCoveringExpressionLengths = new JsonArray();
-    for (int elt : coveringExpressionLengths) {
-      jsonArrayCoveringExpressionLengths.add(new JsonPrimitive(elt));
+    if (coveringExpressionLengths != null) {
+      JsonArray jsonArrayCoveringExpressionLengths = new JsonArray();
+      for (int elt : coveringExpressionLengths) {
+        jsonArrayCoveringExpressionLengths.add(new JsonPrimitive(elt));
+      }
+      jsonObject.add("coveringExpressionLengths", jsonArrayCoveringExpressionLengths);
     }
-    jsonObject.add("coveringExpressionLengths", jsonArrayCoveringExpressionLengths);
     JsonArray jsonArrayNames = new JsonArray();
     for (String elt : names) {
       jsonArrayNames.add(new JsonPrimitive(elt));
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableOptions.java b/pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableOptions.java
index 4413dde..c0b9756 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableOptions.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableOptions.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodFeedback.java b/pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodFeedback.java
index f6acccc..6bb32fe 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodFeedback.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodFeedback.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodOptions.java b/pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodOptions.java
index d6b509e..1e71e43 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodOptions.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodOptions.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/FileKind.java b/pkg/analysis_server/tool/spec/generated/java/types/FileKind.java
index d9ba7bb..8275310 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/FileKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/FileKind.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/FoldingKind.java b/pkg/analysis_server/tool/spec/generated/java/types/FoldingKind.java
index 4e72f1b..4a281de 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/FoldingKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/FoldingKind.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/FoldingRegion.java b/pkg/analysis_server/tool/spec/generated/java/types/FoldingRegion.java
index 3e63a4e..ebad0e7 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/FoldingRegion.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/FoldingRegion.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/GeneralAnalysisService.java b/pkg/analysis_server/tool/spec/generated/java/types/GeneralAnalysisService.java
index a1f0071..80975fa 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/GeneralAnalysisService.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/GeneralAnalysisService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegion.java b/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegion.java
index 7a8e83c..ebbd410 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegion.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegion.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java b/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java
index 9eace11..15d1373 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/HoverInformation.java b/pkg/analysis_server/tool/spec/generated/java/types/HoverInformation.java
index c360b6a..79d233e 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/HoverInformation.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/HoverInformation.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ImplementedClass.java b/pkg/analysis_server/tool/spec/generated/java/types/ImplementedClass.java
index dbe7096..5c08f6b 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ImplementedClass.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ImplementedClass.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ImplementedMember.java b/pkg/analysis_server/tool/spec/generated/java/types/ImplementedMember.java
index 941d1a8..a18d6a4 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ImplementedMember.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ImplementedMember.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/InlineLocalVariableFeedback.java b/pkg/analysis_server/tool/spec/generated/java/types/InlineLocalVariableFeedback.java
index 89c3bff..65e4a86 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/InlineLocalVariableFeedback.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/InlineLocalVariableFeedback.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/InlineMethodFeedback.java b/pkg/analysis_server/tool/spec/generated/java/types/InlineMethodFeedback.java
index c6842dd..6d80cfa 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/InlineMethodFeedback.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/InlineMethodFeedback.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/InlineMethodOptions.java b/pkg/analysis_server/tool/spec/generated/java/types/InlineMethodOptions.java
index 938c664..c13daa7 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/InlineMethodOptions.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/InlineMethodOptions.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditGroup.java b/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditGroup.java
index 7a495e8..b83f304 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditGroup.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditGroup.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestion.java b/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestion.java
index 4deb527..2537bc5 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestion.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestion.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestionKind.java b/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestionKind.java
index cdcdfa5..be193e0 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestionKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestionKind.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/Location.java b/pkg/analysis_server/tool/spec/generated/java/types/Location.java
index d52b5f7..d9f8ae0 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/Location.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/Location.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/MoveFileOptions.java b/pkg/analysis_server/tool/spec/generated/java/types/MoveFileOptions.java
index d828d0d..4f04962 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/MoveFileOptions.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/MoveFileOptions.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/NavigationRegion.java b/pkg/analysis_server/tool/spec/generated/java/types/NavigationRegion.java
index 8500056..80565a9 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/NavigationRegion.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/NavigationRegion.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/NavigationTarget.java b/pkg/analysis_server/tool/spec/generated/java/types/NavigationTarget.java
index 217d091e..001a7a0 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/NavigationTarget.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/NavigationTarget.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/Occurrences.java b/pkg/analysis_server/tool/spec/generated/java/types/Occurrences.java
index 894fc0a..2f84e55 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/Occurrences.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/Occurrences.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/Outline.java b/pkg/analysis_server/tool/spec/generated/java/types/Outline.java
index 7fd32a1..88eb41b 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/Outline.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/Outline.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/OverriddenMember.java b/pkg/analysis_server/tool/spec/generated/java/types/OverriddenMember.java
index 720722a..6054c55 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/OverriddenMember.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/OverriddenMember.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/OverrideMember.java b/pkg/analysis_server/tool/spec/generated/java/types/OverrideMember.java
index 264185f..6f5936e 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/OverrideMember.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/OverrideMember.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/Position.java b/pkg/analysis_server/tool/spec/generated/java/types/Position.java
index 3eed81f..d9e3636 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/Position.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/Position.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/PubStatus.java b/pkg/analysis_server/tool/spec/generated/java/types/PubStatus.java
index 27e2cfe..9d45a19 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/PubStatus.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/PubStatus.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringFeedback.java b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringFeedback.java
index c619daf..d3cfa25 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringFeedback.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringFeedback.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringKind.java b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringKind.java
index 9c8d0a8..b4eb166 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringKind.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameter.java b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameter.java
index 532ecfb..c3b20c2 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameter.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameterKind.java b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameterKind.java
index 146617d..c71d8bb 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameterKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameterKind.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringOptions.java b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringOptions.java
index 16c4392..67abd4b 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringOptions.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringOptions.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblem.java b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblem.java
index 3b8ec81..1b82e4a 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblem.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblem.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblemSeverity.java b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblemSeverity.java
index 01ef16f..35c8296 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblemSeverity.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblemSeverity.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RemoveContentOverlay.java b/pkg/analysis_server/tool/spec/generated/java/types/RemoveContentOverlay.java
index b442848..c9e14a4 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RemoveContentOverlay.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RemoveContentOverlay.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RenameFeedback.java b/pkg/analysis_server/tool/spec/generated/java/types/RenameFeedback.java
index cd31922..35dacff 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RenameFeedback.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RenameFeedback.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RenameOptions.java b/pkg/analysis_server/tool/spec/generated/java/types/RenameOptions.java
index 5ec34ce..18b80e0 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RenameOptions.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RenameOptions.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RequestError.java b/pkg/analysis_server/tool/spec/generated/java/types/RequestError.java
index 598d83f..34c6b31 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RequestError.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RequestError.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java b/pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java
index 3730a03..b8ba4c0 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/SearchResult.java b/pkg/analysis_server/tool/spec/generated/java/types/SearchResult.java
index 6f44743..299aba0 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/SearchResult.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/SearchResult.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/SearchResultKind.java b/pkg/analysis_server/tool/spec/generated/java/types/SearchResultKind.java
index ddbe0ef..e556272 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/SearchResultKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/SearchResultKind.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ServerService.java b/pkg/analysis_server/tool/spec/generated/java/types/ServerService.java
index 54fb1b3..6846e6e 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ServerService.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ServerService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/SourceChange.java b/pkg/analysis_server/tool/spec/generated/java/types/SourceChange.java
index 45bf4eb..6842e2f 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/SourceChange.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/SourceChange.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/SourceEdit.java b/pkg/analysis_server/tool/spec/generated/java/types/SourceEdit.java
index 50b6306..1d54802 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/SourceEdit.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/SourceEdit.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/SourceFileEdit.java b/pkg/analysis_server/tool/spec/generated/java/types/SourceFileEdit.java
index 5cfa8a1..18fab9b 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/SourceFileEdit.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/SourceFileEdit.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/TypeHierarchyItem.java b/pkg/analysis_server/tool/spec/generated/java/types/TypeHierarchyItem.java
index bfb0acc..b6420a2 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/TypeHierarchyItem.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/TypeHierarchyItem.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/html_tools.dart b/pkg/analysis_server/tool/spec/html_tools.dart
deleted file mode 100644
index d46419f..0000000
--- a/pkg/analysis_server/tool/spec/html_tools.dart
+++ /dev/null
@@ -1,137 +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.
-
-/**
- * Tools for HTML manipulation.
- */
-library html.tools;
-
-import 'package:html/dom.dart' as dom;
-
-/**
- * Make a deep copy of the given HTML nodes.
- */
-List<dom.Node> cloneHtmlNodes(List<dom.Node> nodes) =>
-    nodes.map((dom.Node node) => node.clone(true)).toList();
-
-/**
- * Return true if the given iterable contains only whitespace text nodes.
- */
-bool containsOnlyWhitespace(Iterable<dom.Node> nodes) {
-  for (dom.Node node in nodes) {
-    if (!isWhitespaceNode(node)) {
-      return false;
-    }
-  }
-  return true;
-}
-
-/**
- * Get the text contents of the element, ignoring all markup.
- */
-String innerText(dom.Element parent) {
-  StringBuffer buffer = new StringBuffer();
-  void recurse(dom.Element parent) {
-    for (dom.Node child in parent.nodes) {
-      if (child is dom.Text) {
-        buffer.write(child.text);
-      } else if (child is dom.Element) {
-        recurse(child);
-      }
-    }
-  }
-  recurse(parent);
-  return buffer.toString();
-}
-
-/**
- * Return true if the given node is a text node containing only whitespace, or
- * a comment.
- */
-bool isWhitespaceNode(dom.Node node) {
-  if (node is dom.Element) {
-    return false;
-  } else if (node is dom.Text) {
-    return node.text.trim().isEmpty;
-  }
-  // Treat all other types of nodes (e.g. comments) as whitespace.
-  return true;
-}
-
-/**
- * Create an HTML element with the given name, attributes, and child nodes.
- */
-dom.Element makeElement(
-    String name, Map<dynamic, String> attributes, List<dom.Node> children) {
-  dom.Element result = new dom.Element.tag(name);
-  result.attributes.addAll(attributes);
-  for (dom.Node child in children) {
-    result.append(child);
-  }
-  return result;
-}
-
-/**
- * Mixin class for generating HTML.
- */
-class HtmlGenerator {
-  List<dom.Node> _html;
-
-  /**
-   * Add the given [node] to the HTML output.
-   */
-  void add(dom.Node node) {
-    _html.add(node);
-  }
-
-  /**
-   * Add the given [nodes] to the HTML output.
-   */
-  void addAll(Iterable<dom.Node> nodes) {
-    for (dom.Node node in nodes) {
-      add(node);
-    }
-  }
-
-  /**
-   * Execute [callback], collecting any code that is output using [write],
-   * [writeln], [add], [addAll] or [element], and return the result as a list
-   * of HTML nodes.
-   */
-  List<dom.Node> collectHtml(void callback()) {
-    List<dom.Node> oldHtml = _html;
-    try {
-      _html = <dom.Node>[];
-      if (callback != null) {
-        callback();
-      }
-      return _html;
-    } finally {
-      _html = oldHtml;
-    }
-  }
-
-  /**
-   * Execute [callback], wrapping its output in an element with the given
-   * [name] and [attributes].
-   */
-  void element(String name, Map<dynamic, String> attributes,
-      [void callback()]) {
-    add(makeElement(name, attributes, collectHtml(callback)));
-  }
-
-  /**
-   * Output text without ending the current line.
-   */
-  void write(String text) {
-    _html.add(new dom.Text(text));
-  }
-
-  /**
-   * Output text, ending the current line.
-   */
-  void writeln([Object obj = '']) {
-    write('$obj\n');
-  }
-}
diff --git a/pkg/analysis_server/tool/spec/implied_types.dart b/pkg/analysis_server/tool/spec/implied_types.dart
index 8f25296..21987fd 100644
--- a/pkg/analysis_server/tool/spec/implied_types.dart
+++ b/pkg/analysis_server/tool/spec/implied_types.dart
@@ -7,8 +7,9 @@
  */
 library html.tools;
 
+import 'package:analyzer/src/codegen/tools.dart';
+
 import 'api.dart';
-import 'codegen_tools.dart';
 
 Map<String, ImpliedType> computeImpliedTypes(Api api) {
   _ImpliedTypesVisitor visitor = new _ImpliedTypesVisitor(api);
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index 8c349e3..d519a21 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -1959,6 +1959,25 @@
         </params>
       </notification>
     </domain>
+    <domain name="diagnostic" experimental="true">
+      <p>
+        The diagnostic domain contains experimental server diagnostics APIs. Note
+        that as an experimental API, docs are not generated for this domain and it
+        is subject subject to change without notice.
+        Because this experimental domain is not part of the analysis server's API,
+        the version number of the API will not be updated when changes are made.
+        Caveat emptor!
+      </p>
+      <request method="getDiagnostics">
+        <p>Return server diagnostics.</p>
+        <result>
+          <field name="contexts">
+            <list><ref>ContextData</ref></list>
+            <p>The list of analysis contexts.</p>
+          </field>
+        </result>
+      </request>
+    </domain>
     <types>
       <h2 class="domain"><a name="types">Types</a></h2>
       <p>
@@ -2441,6 +2460,43 @@
           <value><code>PARAMETER</code></value>
         </enum>
       </type>
+      <type name="ContextData" experimental="true">
+        <p>
+          Information about an analysis context.
+        </p>
+        <object>
+          <field name="name">
+            <ref>String</ref>
+            <p>
+              The name of the context.
+            </p>
+          </field>
+          <field name="explicitFileCount">
+            <ref>int</ref>
+            <p>
+              Explicitly analyzed files.
+            </p>
+          </field>
+          <field name="implicitFileCount">
+            <ref>int</ref>
+            <p>
+              Implicitly analyzed files.
+            </p>
+          </field>
+          <field name="workItemQueueLength">
+            <ref>int</ref>
+            <p>
+              The number of work items in the queue.
+            </p>
+          </field>
+          <field name="cacheEntryExceptions">
+            <list><ref>String</ref></list>
+            <p>
+              Exceptions associated with cache entries.
+            </p>
+          </field>
+        </object>
+      </type>
       <type name="Element">
         <p>
           Information about an element (something that can be declared
@@ -4035,14 +4091,14 @@
           complete expression.
         </p>
         <feedback>
-          <field name="coveringExpressionOffsets">
+          <field name="coveringExpressionOffsets" optional="true">
             <list><ref>int</ref></list>
             <p>
               The offsets of the expressions that cover the specified
               selection, from the down most to the up most.
             </p>
           </field>
-          <field name="coveringExpressionLengths">
+          <field name="coveringExpressionLengths" optional="true">
             <list><ref>int</ref></list>
             <p>
               The lengths of the expressions that cover the specified
diff --git a/pkg/analysis_server/tool/spec/text_formatter.dart b/pkg/analysis_server/tool/spec/text_formatter.dart
deleted file mode 100644
index a4eb82c..0000000
--- a/pkg/analysis_server/tool/spec/text_formatter.dart
+++ /dev/null
@@ -1,246 +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.
-
-/**
- * Code for converting HTML into text, for use in doc comments.
- */
-library text.formatter;
-
-import 'package:html/dom.dart' as dom;
-
-import 'codegen_tools.dart';
-
-final RegExp whitespace = new RegExp(r'\s');
-
-/**
- * Convert the HTML in [desc] into text, word wrapping at width [width].
- *
- * If [javadocStyle] is true, then the output is compatable with Javadoc,
- * which understands certain HTML constructs.
- */
-String nodesToText(List<dom.Node> desc, int width, bool javadocStyle,
-    {bool removeTrailingNewLine: false}) {
-  _TextFormatter formatter = new _TextFormatter(width, javadocStyle);
-  return formatter.collectCode(() {
-    formatter.addAll(desc);
-    formatter.lineBreak(false);
-  }, removeTrailingNewLine: removeTrailingNewLine);
-}
-
-/**
- * Engine that transforms HTML to text.  The input HTML is processed one
- * character at a time, gathering characters into words and words into lines.
- */
-class _TextFormatter extends CodeGenerator {
-  /**
-   * Word-wrapping width.
-   */
-  final int width;
-
-  /**
-   * The word currently being gathered.
-   */
-  String word = '';
-
-  /**
-   * The line currently being gathered.
-   */
-  String line = '';
-
-  /**
-   * True if a blank line should be inserted before the next word.
-   */
-  bool verticalSpaceNeeded = false;
-
-  /**
-   * True if no text has been output yet.  This suppresses blank lines.
-   */
-  bool atStart = true;
-
-  /**
-   * True if we are processing a <pre> element, thus whitespace should be
-   * preserved.
-   */
-  bool preserveSpaces = false;
-
-  /**
-   * True if the output should be Javadoc compatible.
-   */
-  final bool javadocStyle;
-
-  _TextFormatter(this.width, this.javadocStyle);
-
-  /**
-   * Process an HTML node.
-   */
-  void add(dom.Node node) {
-    if (node is dom.Text) {
-      for (String char in node.text.split('')) {
-        if (preserveSpaces) {
-          wordBreak();
-          write(escape(char));
-        } else if (whitespace.hasMatch(char)) {
-          wordBreak();
-        } else {
-          resolveVerticalSpace();
-          word += escape(char);
-        }
-      }
-    } else if (node is dom.Element) {
-      switch (node.localName) {
-        case 'br':
-          lineBreak(false);
-          break;
-        case 'dl':
-        case 'dt':
-        case 'h1':
-        case 'h2':
-        case 'h3':
-        case 'h4':
-        case 'p':
-          lineBreak(true);
-          addAll(node.nodes);
-          lineBreak(true);
-          break;
-        case 'div':
-          lineBreak(false);
-          if (node.classes.contains('hangingIndent')) {
-            resolveVerticalSpace();
-            indentSpecial('', '        ', () {
-              addAll(node.nodes);
-              lineBreak(false);
-            });
-          } else {
-            addAll(node.nodes);
-            lineBreak(false);
-          }
-          break;
-        case 'ul':
-          lineBreak(false);
-          addAll(node.nodes);
-          lineBreak(false);
-          break;
-        case 'li':
-          lineBreak(false);
-          resolveVerticalSpace();
-          indentSpecial('- ', '  ', () {
-            addAll(node.nodes);
-            lineBreak(false);
-          });
-          break;
-        case 'dd':
-          lineBreak(true);
-          indent(() {
-            addAll(node.nodes);
-            lineBreak(true);
-          });
-          break;
-        case 'pre':
-          lineBreak(false);
-          resolveVerticalSpace();
-          if (javadocStyle) {
-            writeln('<pre>');
-          }
-          bool oldPreserveSpaces = preserveSpaces;
-          try {
-            preserveSpaces = true;
-            addAll(node.nodes);
-          } finally {
-            preserveSpaces = oldPreserveSpaces;
-          }
-          writeln();
-          if (javadocStyle) {
-            writeln('</pre>');
-          }
-          lineBreak(false);
-          break;
-        case 'a':
-        case 'b':
-        case 'body':
-        case 'html':
-        case 'i':
-        case 'span':
-        case 'tt':
-          addAll(node.nodes);
-          break;
-        case 'head':
-          break;
-        default:
-          throw new Exception('Unexpected HTML element: ${node.localName}');
-      }
-    } else {
-      throw new Exception('Unexpected HTML: $node');
-    }
-  }
-
-  /**
-   * Process a list of HTML nodes.
-   */
-  void addAll(List<dom.Node> nodes) {
-    for (dom.Node node in nodes) {
-      add(node);
-    }
-  }
-
-  /**
-   * Escape the given character for HTML.
-   */
-  String escape(String char) {
-    if (javadocStyle) {
-      switch (char) {
-        case '<':
-          return '&lt;';
-        case '>':
-          return '&gt;';
-        case '&':
-          return '&amp;';
-      }
-    }
-    return char;
-  }
-
-  /**
-   * Terminate the current word and/or line, if either is in progress.
-   */
-  void lineBreak(bool gap) {
-    wordBreak();
-    if (line.isNotEmpty) {
-      writeln(line);
-      line = '';
-    }
-    if (gap && !atStart) {
-      verticalSpaceNeeded = true;
-    }
-  }
-
-  /**
-   * Insert vertical space if necessary.
-   */
-  void resolveVerticalSpace() {
-    if (verticalSpaceNeeded) {
-      writeln();
-      verticalSpaceNeeded = false;
-    }
-  }
-
-  /**
-   * Terminate the current word, if a word is in progress.
-   */
-  void wordBreak() {
-    if (word.isNotEmpty) {
-      atStart = false;
-      if (line.isNotEmpty) {
-        if (indentWidth + line.length + 1 + word.length <= width) {
-          line += ' $word';
-        } else {
-          writeln(line);
-          line = word;
-        }
-      } else {
-        line = word;
-      }
-      word = '';
-    }
-  }
-}
diff --git a/pkg/analysis_server/tool/spec/to_html.dart b/pkg/analysis_server/tool/spec/to_html.dart
index 2164c9f..2ccf00e 100644
--- a/pkg/analysis_server/tool/spec/to_html.dart
+++ b/pkg/analysis_server/tool/spec/to_html.dart
@@ -11,12 +11,12 @@
 
 import 'dart:convert';
 
+import 'package:analyzer/src/codegen/html.dart';
+import 'package:analyzer/src/codegen/tools.dart';
 import 'package:html/dom.dart' as dom;
 
 import 'api.dart';
-import 'codegen_tools.dart';
 import 'from_html.dart';
-import 'html_tools.dart';
 
 /**
  * Embedded stylesheet
@@ -81,8 +81,9 @@
 }
 '''.trim();
 
-final GeneratedFile target = new GeneratedFile('../../doc/api.html', () {
-  ToHtmlVisitor visitor = new ToHtmlVisitor(readApi());
+final GeneratedFile target =
+    new GeneratedFile('doc/api.html', (String pkgPath) {
+  ToHtmlVisitor visitor = new ToHtmlVisitor(readApi(pkgPath));
   dom.Document document = new dom.Document();
   document.append(new dom.DocumentType('html', null, null));
   for (dom.Node node in visitor.collectHtml(visitor.visitApi)) {
@@ -92,13 +93,6 @@
 });
 
 /**
- * Translate spec_input.html into api.html.
- */
-main() {
-  target.generate();
-}
-
-/**
  * Visitor that records the mapping from HTML elements to various kinds of API
  * nodes.
  */
@@ -204,6 +198,106 @@
     }
   }
 
+  void generateDomainIndex(Domain domain) {
+    h4(() {
+      write(domain.name);
+      write(' (');
+      link('domain_${domain.name}', () => write('\u2191'));
+      write(')');
+    });
+    if (domain.requests.length > 0) {
+      element('div', {'class': 'subindex'}, () {
+        generateRequestsIndex(domain.requests);
+        if (domain.notifications.length > 0) {
+          generateNotificationsIndex(domain.notifications);
+        }
+      });
+    } else if (domain.notifications.length > 0) {
+      element('div', {'class': 'subindex'}, () {
+        generateNotificationsIndex(domain.notifications);
+      });
+    }
+  }
+
+  void generateIndex() {
+    h3(() => write('Domains'));
+    for (var domain in api.domains) {
+      if (domain.experimental ||
+          (domain.requests.length == 0 && domain.notifications == 0)) {
+        continue;
+      }
+      generateDomainIndex(domain);
+    }
+
+    generateTypesIndex(definedTypes);
+    generateRefactoringsIndex(api.refactorings);
+  }
+
+  void generateNotificationsIndex(Iterable<Notification> notifications) {
+    h5(() => write("Notifications"));
+    element('div', {'class': 'subindex'}, () {
+      element('ul', {}, () {
+        for (var notification in notifications) {
+          element(
+              'li',
+              {},
+              () => link('notification_${notification.longEvent}',
+                  () => write(notification.event)));
+        }
+      });
+    });
+  }
+
+  void generateRefactoringsIndex(Iterable<Refactoring> refactorings) {
+    h3(() {
+      write("Refactorings");
+      write(' (');
+      link('refactorings', () => write('\u2191'));
+      write(')');
+    });
+    // TODO: Individual refactorings are not yet hyperlinked.
+    element('div', {'class': 'subindex'}, () {
+      element('ul', {}, () {
+        for (var refactoring in refactorings) {
+          element(
+              'li',
+              {},
+              () => link('refactoring_${refactoring.kind}',
+                  () => write(refactoring.kind)));
+        }
+      });
+    });
+  }
+
+  void generateRequestsIndex(Iterable<Request> requests) {
+    h5(() => write("Requests"));
+    element('ul', {}, () {
+      for (var request in requests) {
+        element(
+            'li',
+            {},
+            () => link(
+                'request_${request.longMethod}', () => write(request.method)));
+      }
+    });
+  }
+
+  void generateTypesIndex(Set<String> types) {
+    h3(() {
+      write("Types");
+      write(' (');
+      link('types', () => write('\u2191'));
+      write(')');
+    });
+    element('div', {'class': 'subindex'}, () {
+      element('ul', {}, () {
+        for (var type in types) {
+          element('li', {}, () => link('type_$type', () => write(type)));
+        }
+      });
+    });
+  }
+
   void javadocParams(TypeObject typeObject) {
     if (typeObject != null) {
       for (TypeObjectField field in typeObject.fields) {
@@ -294,7 +388,9 @@
 
   @override
   void visitApi() {
-    definedTypes = api.types.keys.toSet();
+    Iterable<TypeDefinition> apiTypes =
+        api.types.where((TypeDefinition td) => !td.experimental);
+    definedTypes = apiTypes.map((TypeDefinition td) => td.name).toSet();
 
     html(() {
       translateHtml(api.html);
@@ -303,6 +399,9 @@
 
   @override
   void visitDomain(Domain domain) {
+    if (domain.experimental) {
+      return;
+    }
     h2('domain', () {
       anchor('domain_${domain.name}', () {
         write('Domain: ${domain.name}');
@@ -394,6 +493,9 @@
 
   @override
   void visitTypeDefinition(TypeDefinition typeDefinition) {
+    if (typeDefinition.experimental) {
+      return;
+    }
     dt('typeDefinition', () {
       anchor('type_${typeDefinition.name}', () {
         write('${typeDefinition.name}: ');
@@ -493,103 +595,6 @@
       super.visitTypes(types);
     });
   }
-
-  void generateIndex() {
-    h3(() => write('Domains'));
-    for (var domain in api.domains) {
-      if (domain.requests.length == 0 && domain.notifications == 0) continue;
-      generateDomainIndex(domain);
-    }
-
-    generateTypesIndex(definedTypes);
-    generateRefactoringsIndex(api.refactorings);
-  }
-
-  void generateDomainIndex(Domain domain) {
-    h4(() {
-      write(domain.name);
-      write(' (');
-      link('domain_${domain.name}', () => write('\u2191'));
-      write(')');
-    });
-    if (domain.requests.length > 0) {
-      element('div', {'class': 'subindex'}, () {
-        generateRequestsIndex(domain.requests);
-        if (domain.notifications.length > 0) {
-          generateNotificationsIndex(domain.notifications);
-        }
-      });
-    } else if (domain.notifications.length > 0) {
-      element('div', {'class': 'subindex'}, () {
-        generateNotificationsIndex(domain.notifications);
-      });
-    }
-  }
-
-  void generateRequestsIndex(Iterable<Request> requests) {
-    h5(() => write("Requests"));
-    element('ul', {}, () {
-      for (var request in requests) {
-        element(
-            'li',
-            {},
-            () => link(
-                'request_${request.longMethod}', () => write(request.method)));
-      }
-    });
-  }
-
-  void generateNotificationsIndex(Iterable<Notification> notifications) {
-    h5(() => write("Notifications"));
-    element('div', {'class': 'subindex'}, () {
-      element('ul', {}, () {
-        for (var notification in notifications) {
-          element(
-              'li',
-              {},
-              () => link('notification_${notification.longEvent}',
-                  () => write(notification.event)));
-        }
-      });
-    });
-  }
-
-  void generateTypesIndex(Set<String> types) {
-    h3(() {
-      write("Types");
-      write(' (');
-      link('types', () => write('\u2191'));
-      write(')');
-    });
-    element('div', {'class': 'subindex'}, () {
-      element('ul', {}, () {
-        for (var type in types) {
-          element('li', {}, () => link('type_$type', () => write(type)));
-        }
-      });
-    });
-  }
-
-  void generateRefactoringsIndex(Iterable<Refactoring> refactorings) {
-    h3(() {
-      write("Refactorings");
-      write(' (');
-      link('refactorings', () => write('\u2191'));
-      write(')');
-    });
-    // TODO: Individual refactorings are not yet hyperlinked.
-    element('div', {'class': 'subindex'}, () {
-      element('ul', {}, () {
-        for (var refactoring in refactorings) {
-          element(
-              'li',
-              {},
-              () => link('refactoring_${refactoring.kind}',
-                  () => write(refactoring.kind)));
-        }
-      });
-    });
-  }
 }
 
 /**
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 4f4165d..d0af2b9 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 0.26.2
+* Add code generation utilities for use in both analyzer and analysis server.
+
+## 0.26.1+17
+* (Internal) Introduced context configuration logic (`configureContext()` extracted from server).
+
 ## 0.26.1+16
 * (Internal) Options validation plugin API update.
 
diff --git a/pkg/analyzer/lib/file_system/file_system.dart b/pkg/analyzer/lib/file_system/file_system.dart
index 7d3ed95..21e8d05 100644
--- a/pkg/analyzer/lib/file_system/file_system.dart
+++ b/pkg/analyzer/lib/file_system/file_system.dart
@@ -7,6 +7,7 @@
 import 'dart:async';
 
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/util/absolute_path.dart';
 import 'package:path/path.dart';
 import 'package:watcher/watcher.dart';
 
@@ -134,6 +135,11 @@
  */
 abstract class ResourceProvider {
   /**
+   * Get the absolute path context used by this resource provider.
+   */
+  AbsolutePathContext get absolutePathContext;
+
+  /**
    * Get the path context used by this resource provider.
    */
   Context get pathContext;
diff --git a/pkg/analyzer/lib/file_system/memory_file_system.dart b/pkg/analyzer/lib/file_system/memory_file_system.dart
index 058f9eb..c276397 100644
--- a/pkg/analyzer/lib/file_system/memory_file_system.dart
+++ b/pkg/analyzer/lib/file_system/memory_file_system.dart
@@ -10,6 +10,7 @@
 
 import 'package:analyzer/src/generated/engine.dart' show TimestampedData;
 import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/util/absolute_path.dart';
 import 'package:path/path.dart';
 import 'package:watcher/watcher.dart';
 
@@ -28,6 +29,9 @@
       new HashMap<String, List<StreamController<WatchEvent>>>();
   int nextStamp = 0;
 
+  final AbsolutePathContext absolutePathContext =
+      new AbsolutePathContext(posix.separator);
+
   @override
   Context get pathContext => posix;
 
@@ -44,7 +48,7 @@
 
   /**
    * Delete the folder with the given path
-   * and recurively delete nested files and folders.
+   * and recursively delete nested files and folders.
    */
   void deleteFolder(String path) {
     _checkFolderAtPath(path);
diff --git a/pkg/analyzer/lib/file_system/physical_file_system.dart b/pkg/analyzer/lib/file_system/physical_file_system.dart
index 303d175..94aa766 100644
--- a/pkg/analyzer/lib/file_system/physical_file_system.dart
+++ b/pkg/analyzer/lib/file_system/physical_file_system.dart
@@ -10,6 +10,7 @@
 
 import 'package:analyzer/src/generated/java_io.dart';
 import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/util/absolute_path.dart';
 import 'package:path/path.dart';
 import 'package:watcher/watcher.dart';
 
@@ -31,6 +32,9 @@
    */
   static final String SERVER_DIR = ".dartServer";
 
+  final AbsolutePathContext absolutePathContext =
+      new AbsolutePathContext(io.Platform.pathSeparator);
+
   PhysicalResourceProvider(String fileReadMode(String s)) {
     if (fileReadMode != null) {
       FileBasedSource.fileReadMode = fileReadMode;
@@ -129,12 +133,12 @@
 
   @override
   String canonicalizePath(String relPath) {
-    return normalize(join(_entry.absolute.path, relPath));
+    return normalize(join(path, relPath));
   }
 
   @override
   bool contains(String path) {
-    return isWithin(this.path, path);
+    return absolutePathContext.isWithin(this.path, path);
   }
 
   @override
@@ -188,6 +192,9 @@
 
   _PhysicalResource(this._entry);
 
+  AbsolutePathContext get absolutePathContext =>
+      PhysicalResourceProvider.INSTANCE.absolutePathContext;
+
   @override
   bool get exists => _entry.existsSync();
 
@@ -196,7 +203,7 @@
 
   @override
   Folder get parent {
-    String parentPath = dirname(path);
+    String parentPath = absolutePathContext.dirname(path);
     if (parentPath == path) {
       return null;
     }
@@ -207,7 +214,7 @@
   String get path => _entry.absolute.path;
 
   @override
-  String get shortName => basename(path);
+  String get shortName => absolutePathContext.basename(path);
 
   @override
   bool operator ==(other) {
diff --git a/pkg/analyzer/lib/instrumentation/file_instrumentation.dart b/pkg/analyzer/lib/instrumentation/file_instrumentation.dart
index ba23b68..7269115 100644
--- a/pkg/analyzer/lib/instrumentation/file_instrumentation.dart
+++ b/pkg/analyzer/lib/instrumentation/file_instrumentation.dart
@@ -4,6 +4,7 @@
 
 library file_instrumentation;
 
+import 'dart:async';
 import 'dart:io';
 
 import 'package:analyzer/instrumentation/instrumentation.dart';
@@ -30,8 +31,8 @@
   }
 
   @override
-  void shutdown() {
-    _sink.close();
+  Future shutdown() async {
+    await _sink.close();
     _sink = null;
   }
 }
diff --git a/pkg/analyzer/lib/instrumentation/instrumentation.dart b/pkg/analyzer/lib/instrumentation/instrumentation.dart
index 18772de..8b36303 100644
--- a/pkg/analyzer/lib/instrumentation/instrumentation.dart
+++ b/pkg/analyzer/lib/instrumentation/instrumentation.dart
@@ -4,6 +4,7 @@
 
 library instrumentation;
 
+import 'dart:async';
 import 'dart:convert';
 
 import 'package:analyzer/task/model.dart';
@@ -43,7 +44,7 @@
    * 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();
+  Future shutdown();
 }
 
 /**
@@ -83,7 +84,7 @@
   int _subprocessCounter = 0;
 
   /**
-   * Initialize a newly created instrumentation service to comunicate with the
+   * Initialize a newly created instrumentation service to communicate with the
    * given [instrumentationServer].
    */
   InstrumentationService(this._instrumentationServer);
@@ -216,7 +217,7 @@
 
   /**
    * Log the result of executing a subprocess.  [subprocessId] should be the
-   * unique IDreturned by [logSubprocessStart].
+   * unique ID returned by [logSubprocessStart].
    */
   void logSubprocessResult(
       int subprocessId, int exitCode, String stdout, String stderr) {
@@ -290,9 +291,9 @@
    * 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() {
+  Future shutdown() async {
     if (_instrumentationServer != null) {
-      _instrumentationServer.shutdown();
+      await _instrumentationServer.shutdown();
       _instrumentationServer = null;
     }
   }
@@ -373,9 +374,9 @@
   }
 
   @override
-  void shutdown() {
+  Future shutdown() async {
     for (InstrumentationServer server in _servers) {
-      server.shutdown();
+      await server.shutdown();
     }
   }
 }
diff --git a/pkg/analyzer/lib/source/analysis_options_provider.dart b/pkg/analyzer/lib/source/analysis_options_provider.dart
index 29062a2..64c8c8b 100644
--- a/pkg/analyzer/lib/source/analysis_options_provider.dart
+++ b/pkg/analyzer/lib/source/analysis_options_provider.dart
@@ -6,6 +6,7 @@
 
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/util/yaml.dart';
 import 'package:source_span/source_span.dart';
 import 'package:yaml/yaml.dart';
 
@@ -33,7 +34,16 @@
     if (optionsSource == null) {
       return options;
     }
-    YamlNode doc = loadYamlNode(optionsSource);
+
+    YamlNode doc;
+    try {
+      doc = loadYamlNode(optionsSource);
+    } on YamlException catch (e) {
+      throw new OptionsFormatException(e.message, e.span);
+    } catch (e) {
+      throw new OptionsFormatException('Unable to parse YAML document.');
+    }
+
     // Empty options.
     if (doc is YamlScalar && doc.value == null) {
       return options;
@@ -44,19 +54,45 @@
           doc.span);
     }
     if (doc is YamlMap) {
-      doc.forEach((k, v) {
-        if (k is! String) {
+      (doc as YamlMap).nodes.forEach((k, v) {
+        var key;
+        if (k is YamlScalar) {
+          key = k.value;
+        }
+        if (key is! String) {
           throw new OptionsFormatException(
               'Bad options file format (expected String scope key, '
               'got ${k.runtimeType})',
               k != null ? k.span : doc.span);
         }
-        options[k] = v;
+        if (v != null && v is! YamlNode) {
+          throw new OptionsFormatException(
+              'Bad options file format (expected Node value, '
+                  'got ${v.runtimeType}: `${v.toString()}`)',
+              doc.span);
+        }
+        options[key] = v;
       });
     }
     return options;
   }
 
+  /// Merge the given options contents where the values in [defaults] may be
+  /// overridden by [overrides].
+  ///
+  /// Some notes about merge semantics:
+  ///
+  ///   * lists are merged (without duplicates).
+  ///   * lists of scalar values can be promoted to simple maps when merged with
+  ///     maps of strings to booleans (e.g., ['opt1', 'opt2'] becomes
+  ///     {'opt1': true, 'opt2': true}.
+  ///   * maps are merged recursively.
+  ///   * if map values cannot be merged, the overriding value is taken.
+  ///
+  Map<String, YamlNode> merge(
+          Map<String, YamlNode> defaults, Map<String, YamlNode> overrides) =>
+      new Merger().merge(defaults, overrides);
+
   /// Read the contents of [file] as a string.
   /// Returns null if file does not exist.
   String _readAnalysisOptionsFile(File file) {
diff --git a/pkg/analyzer/lib/source/embedder.dart b/pkg/analyzer/lib/source/embedder.dart
new file mode 100644
index 0000000..2695989
--- /dev/null
+++ b/pkg/analyzer/lib/source/embedder.dart
@@ -0,0 +1,233 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library source.embedder;
+
+import 'dart:core' hide Resource;
+import 'dart:collection' show HashMap;
+
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/generated/java_io.dart' show JavaFile;
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/source_io.dart' show FileBasedSource;
+import 'package:path/path.dart' as pathos;
+import 'package:yaml/yaml.dart';
+
+/// Given a packageMap, check in each package's lib directory for the
+/// existence of an `_embedder.yaml` file. If the file contains a top level
+/// YamlMap, it will be added to the [embedderYamls] map.
+class EmbedderYamlLocator {
+  static const String EMBEDDER_FILE_NAME = '_embedder.yaml';
+
+  // Map from package's library directory to the parsed
+  // YamlMap.
+  final Map<Folder, YamlMap> embedderYamls = new HashMap<Folder, YamlMap>();
+
+  EmbedderYamlLocator(Map<String, List<Folder>> packageMap) {
+    if (packageMap != null) {
+      refresh(packageMap);
+    }
+  }
+
+  void refresh(Map<String, List<Folder>> packageMap) {
+    // Clear existing.
+    embedderYamls.clear();
+    if (packageMap == null) {
+      return;
+    }
+    packageMap.forEach(_processPackage);
+  }
+
+  /// Programatically add an _embedder.yaml mapping.
+  void addEmbedderYaml(Folder libDir, String embedderYaml) {
+    _processEmbedderYaml(libDir, embedderYaml);
+  }
+
+  /// Given a package [name] and a list of folders ([libDirs]),
+  /// add any found `_embedder.yaml` files.
+  void _processPackage(String name, List<Folder> libDirs) {
+    for (Folder libDir in libDirs) {
+      String embedderYaml = _readEmbedderYaml(libDir);
+      if (embedderYaml != null) {
+        _processEmbedderYaml(libDir, embedderYaml);
+      }
+    }
+  }
+
+  /// Given the yaml for an embedder ([embedderYaml]) and a folder
+  /// ([libDir]), setup the uri mapping.
+  void _processEmbedderYaml(Folder libDir, String embedderYaml) {
+    YamlNode yaml;
+    try {
+      yaml = loadYaml(embedderYaml);
+    } catch (_) {
+      // TODO(pquitslund): Notify developer that something is wrong with the
+      // _embedder.yaml file in libDir.
+      return;
+    }
+    if (yaml == null) {
+      // TODO(pquitslund): Notify developer that something is wrong with the
+      // _embedder.yaml file in libDir.
+      return;
+    }
+    if (yaml is! YamlMap) {
+      // TODO(pquitslund): Notify developer that something is wrong with the
+      // _embedder.yaml file in libDir.
+      return;
+    }
+    embedderYamls[libDir] = yaml;
+  }
+
+
+  /// Read the contents of [libDir]/[EMBEDDER_FILE_NAME] as a string.
+  /// Returns null if the file doesn't exist.
+  String _readEmbedderYaml(Folder libDir) {
+    File file = libDir.getChild(EMBEDDER_FILE_NAME);
+    try {
+      return file.readAsStringSync();
+    } on FileSystemException {
+      // File can't be read.
+      return null;
+    }
+  }
+}
+
+/// Given the [embedderYamls] from [EmbedderYamlLocator] check each one for the
+/// top level key 'embedder_libs'. Under the 'embedder_libs' key are key value
+/// pairs. Each key is a 'dart:' library uri and each value is a path
+/// (relative to the directory containing `_embedder.yaml`) to a dart script
+/// for the given library. For example:
+///
+/// embedder_libs:
+///   'dart:io': '../../sdk/io/io.dart'
+///
+/// If a key doesn't begin with `dart:` it is ignored.
+///
+class EmbedderUriResolver extends UriResolver {
+  static const String DART_COLON_PREFIX = 'dart:';
+
+  final Map<String, String> _urlMappings = <String, String>{};
+
+  /// Construct a [EmbedderUriResolver] from a package map
+  /// (see [PackageMapProvider]).
+  EmbedderUriResolver(Map<Folder, YamlMap> embedderYamls) {
+    if (embedderYamls == null) {
+      return;
+    }
+    embedderYamls.forEach(_processEmbedderYaml);
+  }
+
+  void _processEmbedderYaml(Folder libDir, YamlMap map) {
+    YamlNode embedder_libs = map['embedder_libs'];
+    if (embedder_libs == null) {
+      return;
+    }
+    if (embedder_libs is! YamlMap) {
+      return;
+    }
+    (embedder_libs as YamlMap).forEach((k, v) =>
+        _processEmbedderLibs(k, v, libDir));
+  }
+
+  /// Install the mapping from [name] to [libDir]/[file].
+  void _processEmbedderLibs(String name, String file, Folder libDir) {
+    if (!name.startsWith(DART_COLON_PREFIX)) {
+      // SDK libraries must begin with 'dart:'.
+      // TODO(pquitslund): Notify developer that something is wrong with the
+      // _embedder.yaml file in libDir.
+      return;
+    }
+    String key = name;
+    String value = libDir.canonicalizePath(file);
+    _urlMappings[key] = value;
+  }
+
+  /// Number of embedder libraries.
+  int get length => _urlMappings.length;
+
+  /// Return the path mapping for [libName] or null if there is none.
+  String operator [](String libName) => _urlMappings[libName];
+
+  @override
+  Source resolveAbsolute(Uri importUri, [Uri actualUri]) {
+    String libraryName = _libraryName(importUri);
+    String partPath = _partPath(importUri);
+    // Lookup library name in mappings.
+    String mapping = _urlMappings[libraryName];
+    if (mapping == null) {
+      // Not found.
+      return null;
+    }
+    // This mapping points to the main entry file of the dart: library.
+    Uri libraryEntry = new Uri.file(mapping);
+    if (!libraryEntry.isAbsolute) {
+      // We expect an absolute path.
+      return null;
+    }
+
+    if (partPath != null) {
+      return _resolvePart(libraryEntry, partPath, importUri);
+    } else {
+      return _resolveEntry(libraryEntry, importUri);
+    }
+  }
+
+  @override
+  Uri restoreAbsolute(Source source) {
+    String extensionName = _findExtensionNameFor(source.fullName);
+    if (extensionName != null) {
+      return Uri.parse(extensionName);
+    }
+    // TODO(johnmccutchan): Handle restoring parts.
+    return null;
+  }
+
+  /// Return the extension name for [fullName] or `null`.
+  String _findExtensionNameFor(String fullName) {
+    String result;
+    _urlMappings.forEach((extensionName, pathMapping) {
+      if (pathMapping == fullName) {
+        result = extensionName;
+      }
+    });
+    return result;
+  }
+
+  /// Return the library name of [importUri].
+  String _libraryName(Uri importUri) {
+    String uri = importUri.toString();
+    int index = uri.indexOf('/');
+    if (index >= 0) {
+      return uri.substring(0, index);
+    }
+    return uri;
+  }
+
+  /// Return the part path of [importUri].
+  String _partPath(Uri importUri) {
+    String uri = importUri.toString();
+    int index = uri.indexOf('/');
+    if (index >= 0) {
+      return uri.substring(index + 1);
+    }
+    return null;
+  }
+
+  /// Resolve an import of an sdk extension.
+  Source _resolveEntry(Uri libraryEntry, Uri importUri) {
+    // Library entry.
+    JavaFile javaFile = new JavaFile.fromUri(libraryEntry);
+    return new FileBasedSource(javaFile, importUri);
+  }
+
+  /// Resolve a 'part' statement inside an sdk extension.
+  Source _resolvePart(Uri libraryEntry, String partPath, Uri importUri) {
+    // Library part.
+    String directory = pathos.dirname(libraryEntry.path);
+    Uri partUri = new Uri.file(pathos.join(directory, partPath));
+    assert(partUri.isAbsolute);
+    JavaFile javaFile = new JavaFile.fromUri(partUri);
+    return new FileBasedSource(javaFile, importUri);
+  }
+}
diff --git a/pkg/analyzer/lib/source/path_filter.dart b/pkg/analyzer/lib/source/path_filter.dart
index 40e81a6..7eeada2 100644
--- a/pkg/analyzer/lib/source/path_filter.dart
+++ b/pkg/analyzer/lib/source/path_filter.dart
@@ -4,10 +4,10 @@
 
 library source.path_filter;
 
-import 'package:glob/glob.dart' as glob;
+import 'package:analyzer/src/util/glob.dart';
 import 'package:path/path.dart' as path;
 
-/// Filter paths against a set of [ignorePatterns] relative to a [root]
+/// Filter paths against a set of [_ignorePatterns] relative to a [root]
 /// directory. Paths outside of [root] are also ignored.
 class PathFilter {
   /// The path context to use when manipulating paths.
@@ -17,7 +17,7 @@
   final String root;
 
   /// List of ignore patterns that paths are tested against.
-  final List<glob.Glob> _ignorePatterns = new List<glob.Glob>();
+  final List<Glob> _ignorePatterns = new List<Glob>();
 
   /// Construct a new path filter rooted at [root] with [ignorePatterns].
   /// If [pathContext] is not specified, then the system path context is used.
@@ -39,11 +39,20 @@
     _ignorePatterns.clear();
     if (ignorePatterns != null) {
       for (var ignorePattern in ignorePatterns) {
-        _ignorePatterns.add(new glob.Glob(ignorePattern));
+        _ignorePatterns.add(new Glob(pathContext.separator, ignorePattern));
       }
     }
   }
 
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    for (Glob pattern in _ignorePatterns) {
+      sb.write('$pattern ');
+    }
+    sb.writeln('');
+    return sb.toString();
+  }
+
   /// Returns the absolute path of [path], relative to [root].
   String _canonicalize(String path) =>
       pathContext.normalize(pathContext.join(root, path));
@@ -54,7 +63,7 @@
   /// Returns true if [path] matches any ignore patterns.
   bool _match(String path) {
     path = _relative(path);
-    for (var glob in _ignorePatterns) {
+    for (Glob glob in _ignorePatterns) {
       if (glob.matches(path)) {
         return true;
       }
@@ -64,13 +73,4 @@
 
   /// Returns the relative portion of [path] from [root].
   String _relative(String path) => pathContext.relative(path, from: root);
-
-  String toString() {
-    StringBuffer sb = new StringBuffer();
-    for (var pattern in _ignorePatterns) {
-      sb.write('$pattern ');
-    }
-    sb.writeln('');
-    return sb.toString();
-  }
 }
diff --git a/pkg/analyzer/lib/src/codegen/tools.dart b/pkg/analyzer/lib/src/codegen/tools.dart
index 3b2115d..87c9edf 100644
--- a/pkg/analyzer/lib/src/codegen/tools.dart
+++ b/pkg/analyzer/lib/src/codegen/tools.dart
@@ -15,8 +15,8 @@
 import 'html.dart';
 import 'text_formatter.dart';
 
-final RegExp trailingWhitespaceRegExp = new RegExp(r'[\n ]+$');
 final RegExp trailingSpacesInLineRegExp = new RegExp(r' +$', multiLine: true);
+final RegExp trailingWhitespaceRegExp = new RegExp(r'[\n ]+$');
 
 /**
  * Join the given strings using camelCase.  If [doCapitalize] is true, the first
@@ -43,13 +43,16 @@
 
 /**
  * Type of functions used to compute the contents of a set of generated files.
+ * [pkgPath] is the path to the current package.
  */
-typedef Map<String, FileContentsComputer> DirectoryContentsComputer();
+typedef Map<String, FileContentsComputer> DirectoryContentsComputer(
+    String pkgPath);
 
 /**
  * Type of functions used to compute the contents of a generated file.
+ * [pkgPath] is the path to the current package.
  */
-typedef String FileContentsComputer();
+typedef String FileContentsComputer(String pkgPath);
 
 /**
  * Mixin class for generating code.
@@ -156,7 +159,7 @@
     if (codeGeneratorSettings.languageName == 'java') {
       header = '''
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
@@ -261,10 +264,75 @@
       this.indent: '  '});
 }
 
+/**
+ * Abstract base class representing behaviors common to generated files and
+ * generated directories.
+ */
 abstract class GeneratedContent {
-  FileSystemEntity get outputFile;
-  bool check();
-  void generate();
+  /**
+   * Check whether the [output] has the correct contents, and return true if it
+   * does.  [pkgPath] is the path to the current package.
+   */
+  bool check(String pkgPath);
+
+  /**
+   * Replace the [output] with the correct contents.  [pkgPath] is the path to
+   * the current package.
+   */
+  void generate(String pkgPath);
+
+  /**
+   * Get a [FileSystemEntity] representing the output file or directory.
+   * [pkgPath] is the path to the current package.
+   */
+  FileSystemEntity output(String pkgPath);
+
+  /**
+   * Check that all of the [targets] are up to date.  If they are not, print
+   * out a message instructing the user to regenerate them, and exit with a
+   * nonzero error code.
+   *
+   * [pkgPath] is the path to the current package.  [generatorRelPath] is the
+   * path to a .dart script the user may use to regenerate the targets.
+   *
+   * To avoid mistakes when run on Windows, [generatorRelPath] always uses
+   * POSIX directory separators.
+   */
+  static void checkAll(String pkgPath, String generatorRelPath,
+      Iterable<GeneratedContent> targets) {
+    bool generateNeeded = false;
+    for (GeneratedContent target in targets) {
+      if (!target.check(pkgPath)) {
+        print(
+            '${target.output(pkgPath).absolute} does not have expected contents.');
+        generateNeeded = true;
+      }
+    }
+    if (generateNeeded) {
+      print('Please regenerate using:');
+      String executable = Platform.executable;
+      String packageRoot = '';
+      if (Platform.packageRoot.isNotEmpty) {
+        packageRoot = ' --package-root=${Platform.packageRoot}';
+      }
+      String generateScript =
+          join(pkgPath, joinAll(posix.split(generatorRelPath)));
+      print('  $executable$packageRoot $generateScript');
+      exit(1);
+    } else {
+      print('All generated files up to date.');
+    }
+  }
+
+  /**
+   * Regenerate all of the [targets].  [pkgPath] is the path to the current
+   * package.
+   */
+  static void generateAll(String pkgPath, Iterable<GeneratedContent> targets) {
+    for (GeneratedContent target in targets) {
+      target.generate(pkgPath);
+    }
+  }
 }
 
 /**
@@ -284,25 +352,15 @@
 
   GeneratedDirectory(this.outputDirPath, this.directoryContentsComputer);
 
-  /**
-   * Get a Directory object representing the output directory.
-   */
-  Directory get outputFile =>
-      new Directory(joinAll(posix.split(outputDirPath)));
-
-  /**
-   * Check whether the directory has the correct contents, and return true if it
-   * does.
-   */
   @override
-  bool check() {
-    Map<String, FileContentsComputer> map = directoryContentsComputer();
+  bool check(String pkgPath) {
+    Directory outputDirectory = output(pkgPath);
+    Map<String, FileContentsComputer> map = directoryContentsComputer(pkgPath);
     try {
       for (String file in map.keys) {
         FileContentsComputer fileContentsComputer = map[file];
-        String expectedContents = fileContentsComputer();
-        File outputFile =
-            new File(joinAll(posix.split(posix.join(outputDirPath, file))));
+        String expectedContents = fileContentsComputer(pkgPath);
+        File outputFile = new File(posix.join(outputDirectory.path, file));
         String actualContents = outputFile.readAsStringSync();
         // Normalize Windows line endings to Unix line endings so that the
         // comparison doesn't fail on Windows.
@@ -312,7 +370,7 @@
         }
       }
       int nonHiddenFileCount = 0;
-      outputFile
+      outputDirectory
           .listSync(recursive: false, followLinks: false)
           .forEach((FileSystemEntity fileSystemEntity) {
         if (fileSystemEntity is File &&
@@ -334,30 +392,30 @@
     return true;
   }
 
-  /**
-   * Replace the directory with the correct contents.  [spec] is the "tool/spec"
-   * directory.  If [spec] is unspecified, it is assumed to be the directory
-   * containing Platform.executable.
-   */
   @override
-  void generate() {
+  void generate(String pkgPath) {
+    Directory outputDirectory = output(pkgPath);
     try {
       // delete the contents of the directory (and the directory itself)
-      outputFile.deleteSync(recursive: true);
+      outputDirectory.deleteSync(recursive: true);
     } catch (e) {
       // Error caught while trying to delete the directory, this can happen if
       // it didn't yet exist.
     }
     // re-create the empty directory
-    outputFile.createSync(recursive: true);
+    outputDirectory.createSync(recursive: true);
 
     // generate all of the files in the directory
-    Map<String, FileContentsComputer> map = directoryContentsComputer();
+    Map<String, FileContentsComputer> map = directoryContentsComputer(pkgPath);
     map.forEach((String file, FileContentsComputer fileContentsComputer) {
-      File outputFile = new File(joinAll(posix.split(outputDirPath + file)));
-      outputFile.writeAsStringSync(fileContentsComputer());
+      File outputFile = new File(posix.join(outputDirectory.path, file));
+      outputFile.writeAsStringSync(fileContentsComputer(pkgPath));
     });
   }
+
+  @override
+  Directory output(String pkgPath) =>
+      new Directory(join(pkgPath, joinAll(posix.split(outputDirPath))));
 }
 
 /**
@@ -379,18 +437,10 @@
 
   GeneratedFile(this.outputPath, this.computeContents);
 
-  /**
-   * Get a File object representing the output file.
-   */
-  File get outputFile => new File(joinAll(posix.split(outputPath)));
-
-  /**
-   * Check whether the file has the correct contents, and return true if it
-   * does.
-   */
   @override
-  bool check() {
-    String expectedContents = computeContents();
+  bool check(String pkgPath) {
+    File outputFile = output(pkgPath);
+    String expectedContents = computeContents(pkgPath);
     try {
       String actualContents = outputFile.readAsStringSync();
       // Normalize Windows line endings to Unix line endings so that the
@@ -405,14 +455,14 @@
     }
   }
 
-  /**
-   * Replace the file with the correct contents.  [spec] is the "tool/spec"
-   * directory.  If [spec] is unspecified, it is assumed to be the directory
-   * containing Platform.executable.
-   */
-  void generate() {
-    outputFile.writeAsStringSync(computeContents());
+  @override
+  void generate(String pkgPath) {
+    output(pkgPath).writeAsStringSync(computeContents(pkgPath));
   }
+
+  @override
+  File output(String pkgPath) =>
+      new File(join(pkgPath, joinAll(posix.split(outputPath))));
 }
 
 /**
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index 4f2c08d..9b2fa81 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -9,6 +9,7 @@
 
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/plugin/task.dart';
+import 'package:analyzer/source/embedder.dart';
 import 'package:analyzer/src/cancelable_future.dart';
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/generated/ast.dart';
@@ -81,6 +82,9 @@
    */
   AnalysisOptionsImpl _options = new AnalysisOptionsImpl();
 
+  /// The embedder yaml locator for this context.
+  EmbedderYamlLocator _embedderYamlLocator = new EmbedderYamlLocator(null);
+
   /**
    * A flag indicating whether this context is disposed.
    */
@@ -252,6 +256,9 @@
   AnalysisOptions get analysisOptions => _options;
 
   @override
+  EmbedderYamlLocator get embedderYamlLocator => _embedderYamlLocator;
+
+  @override
   void set analysisOptions(AnalysisOptions options) {
     bool needsRecompute = this._options.analyzeFunctionBodiesPredicate !=
             options.analyzeFunctionBodiesPredicate ||
@@ -265,6 +272,7 @@
         this._options.strongMode != options.strongMode ||
         this._options.enableStrictCallChecks !=
             options.enableStrictCallChecks ||
+        this._options.enableGenericMethods != options.enableGenericMethods ||
         this._options.enableSuperMixins != options.enableSuperMixins;
     int cacheSize = options.cacheSize;
     if (this._options.cacheSize != cacheSize) {
@@ -275,6 +283,7 @@
     this._options.generateImplicitErrors = options.generateImplicitErrors;
     this._options.generateSdkErrors = options.generateSdkErrors;
     this._options.dart2jsHint = options.dart2jsHint;
+    this._options.enableGenericMethods = options.enableGenericMethods;
     this._options.enableStrictCallChecks = options.enableStrictCallChecks;
     this._options.enableSuperMixins = options.enableSuperMixins;
     this._options.hint = options.hint;
@@ -520,15 +529,14 @@
   }
 
   @override
-  void applyChanges(ChangeSet changeSet) {
+  ApplyChangesStatus applyChanges(ChangeSet changeSet) {
     if (changeSet.isEmpty) {
-      return;
+      return new ApplyChangesStatus(false);
     }
     //
     // First, compute the list of sources that have been removed.
     //
-    List<Source> removedSources =
-        new List<Source>.from(changeSet.removedSources);
+    List<Source> removedSources = changeSet.removedSources.toList();
     for (SourceContainer container in changeSet.removedContainers) {
       _addSourcesInContainer(removedSources, container);
     }
@@ -538,13 +546,13 @@
     for (Source source in changeSet.addedSources) {
       _sourceAvailable(source);
     }
-    for (Source source in changeSet.changedSources) {
-      if (_contentCache.getContents(source) != null) {
-        // This source is overridden in the content cache, so the change will
-        // have no effect. Just ignore it to avoid wasting time doing
-        // re-analysis.
-        continue;
-      }
+    // Exclude sources that are overridden in the content cache, so the change
+    // will have no effect. Just ignore it to avoid wasting time doing
+    // re-analysis.
+    List<Source> changedSources = changeSet.changedSources
+        .where((s) => _contentCache.getContents(s) == null)
+        .toList();
+    for (Source source in changedSources) {
       _sourceChanged(source);
     }
     changeSet.changedContents.forEach((Source key, String value) {
@@ -563,9 +571,14 @@
     }
     for (WorkManager workManager in workManagers) {
       workManager.applyChange(
-          changeSet.addedSources, changeSet.changedSources, removedSources);
+          changeSet.addedSources, changedSources, removedSources);
     }
     _onSourcesChangedController.add(new SourcesChangedEvent(changeSet));
+    return new ApplyChangesStatus(changeSet.addedSources.isNotEmpty ||
+        changeSet.changedContents.isNotEmpty ||
+        changeSet.deletedSources.isNotEmpty ||
+        changedSources.isNotEmpty ||
+        removedSources.isNotEmpty);
   }
 
   @override
@@ -765,7 +778,8 @@
   }
 
   @override
-  Object getConfigurationData(ResultDescriptor key) => _configurationData[key];
+  Object getConfigurationData(ResultDescriptor key) =>
+      _configurationData[key] ?? key?.defaultValue;
 
   @override
   TimestampedData<String> getContents(Source source) {
@@ -1024,10 +1038,14 @@
   }
 
   /**
-   * Invalidate analysis cache.
+   * Invalidate analysis cache and notify work managers that they have work
+   * to do.
    */
   void invalidateCachedResults() {
     _cache = createCacheFromSourceFactory(_sourceFactory);
+    for (WorkManager workManager in workManagers) {
+      workManager.onAnalysisOptionsChanged();
+    }
   }
 
   @override
@@ -1764,6 +1782,7 @@
     if (entry == null) {
       _createCacheEntry(source, true);
     } else {
+      entry.explicitlyAdded = true;
       entry.modificationTime = getModificationStamp(source);
       entry.setState(CONTENT, CacheState.INVALID);
     }
diff --git a/pkg/analyzer/lib/src/generated/constant.dart b/pkg/analyzer/lib/src/generated/constant.dart
index aca4af5..2412506 100644
--- a/pkg/analyzer/lib/src/generated/constant.dart
+++ b/pkg/analyzer/lib/src/generated/constant.dart
@@ -15,9 +15,10 @@
 import 'engine.dart' show AnalysisEngine, RecordingErrorListener;
 import 'error.dart';
 import 'java_core.dart';
-import 'resolver.dart' show TypeProvider, TypeSystem, TypeSystemImpl;
+import 'resolver.dart' show TypeProvider;
 import 'scanner.dart' show Token, TokenType;
 import 'source.dart' show Source;
+import 'type_system.dart' show TypeSystem, TypeSystemImpl;
 import 'utilities_collection.dart';
 import 'utilities_dart.dart' show ParameterKind;
 
diff --git a/pkg/analyzer/lib/src/generated/element.dart b/pkg/analyzer/lib/src/generated/element.dart
index 7085b8d..7793d0d 100644
--- a/pkg/analyzer/lib/src/generated/element.dart
+++ b/pkg/analyzer/lib/src/generated/element.dart
@@ -128,7 +128,8 @@
 /**
  * An element that represents a class.
  */
-abstract class ClassElement implements TypeDefiningElement {
+abstract class ClassElement
+    implements TypeDefiningElement, TypeParameterizedElement {
   /**
    * An empty list of class elements.
    */
@@ -269,12 +270,6 @@
   InterfaceType get type;
 
   /**
-   * Return a list containing all of the type parameters declared for this
-   * class.
-   */
-  List<TypeParameterElement> get typeParameters;
-
-  /**
    * Return the unnamed constructor declared in this class, or `null` if this
    * class does not declare an unnamed constructor but does declare named
    * constructors. The returned constructor will be synthetic if this class does
@@ -1142,11 +1137,8 @@
         }
         implicitConstructor.parameters = implicitParameters;
       }
-      FunctionTypeImpl constructorType =
-          new FunctionTypeImpl(implicitConstructor);
-      constructorType.typeArguments = type.typeArguments;
-      implicitConstructor.type = constructorType;
       implicitConstructor.enclosingElement = this;
+      implicitConstructor.type = new FunctionTypeImpl(implicitConstructor);
       return implicitConstructor;
     }).toList();
   }
@@ -3582,7 +3574,7 @@
  * An element representing an executable object, including functions, methods,
  * constructors, getters, and setters.
  */
-abstract class ExecutableElement implements Element {
+abstract class ExecutableElement implements TypeParameterizedElement {
   /**
    * An empty list of executable elements.
    */
@@ -3676,12 +3668,6 @@
    * Return the type of function defined by this executable element.
    */
   FunctionType get type;
-
-  /**
-   * Return a list containing all of the type parameters defined for this
-   * executable element.
-   */
-  List<TypeParameterElement> get typeParameters;
 }
 
 /**
@@ -4528,6 +4514,15 @@
     _visibleRangeOffset = offset;
     _visibleRangeLength = length;
   }
+
+  /**
+   * Set the parameters defined by this type alias to the given [parameters]
+   * without becoming the parent of the parameters. This should only be used by
+   * the [TypeResolverVisitor] when creating a synthetic type alias.
+   */
+  void shareParameters(List<ParameterElement> parameters) {
+    this._parameters = parameters;
+  }
 }
 
 /**
@@ -4658,7 +4653,8 @@
 /**
  * A function type alias (`typedef`).
  */
-abstract class FunctionTypeAliasElement implements TypeDefiningElement {
+abstract class FunctionTypeAliasElement
+    implements TypeDefiningElement, TypeParameterizedElement {
   /**
    * An empty array of type alias elements.
    */
@@ -4685,11 +4681,6 @@
   FunctionType get type;
 
   /**
-   * Return a list containing all of the type parameters defined for this type.
-   */
-  List<TypeParameterElement> get typeParameters;
-
-  /**
    * Return the resolved function type alias node that declares this element.
    *
    * This method is expensive, because resolved AST might be evicted from cache,
@@ -4838,24 +4829,6 @@
     return null;
   }
 
-  /**
-   * Set the parameters defined by this type alias to the given [parameters]
-   * without becoming the parent of the parameters. This should only be used by
-   * the [TypeResolverVisitor] when creating a synthetic type alias.
-   */
-  void shareParameters(List<ParameterElement> parameters) {
-    this._parameters = parameters;
-  }
-
-  /**
-   * Set the type parameters defined for this type to the given [typeParameters]
-   * without becoming the parent of the parameters. This should only be used by
-   * the [TypeResolverVisitor] when creating a synthetic type alias.
-   */
-  void shareTypeParameters(List<TypeParameterElement> typeParameters) {
-    this._typeParameters = typeParameters;
-  }
-
   @override
   void visitChildren(ElementVisitor visitor) {
     super.visitChildren(visitor);
@@ -4869,9 +4842,9 @@
  */
 class FunctionTypeImpl extends TypeImpl implements FunctionType {
   /**
-   * A list containing the actual types of the type arguments.
+   * The list of [typeArguments].
    */
-  List<DartType> typeArguments = DartType.EMPTY_LIST;
+  List<DartType> _typeArguments = DartType.EMPTY_LIST;
 
   /**
    * The set of typedefs which should not be expanded when exploring this type,
@@ -4881,19 +4854,19 @@
 
   /**
    * Initialize a newly created function type to be declared by the given
-   * [element].
+   * [element], and also initialize [typeArguments] to match the
+   * [typeParameters], which permits later substitution.
    */
-  FunctionTypeImpl(ExecutableElement element, [this.prunedTypedefs])
-      : super(element, null);
+  FunctionTypeImpl(ExecutableElement element,
+      [List<FunctionTypeAliasElement> prunedTypedefs])
+      : this._(element, null, prunedTypedefs, null);
 
   /**
    * Initialize a newly created function type to be declared by the given
    * [element].
    */
   @deprecated // Use new FunctionTypeImpl(element)
-  FunctionTypeImpl.con1(ExecutableElement element)
-      : prunedTypedefs = null,
-        super(element, null);
+  FunctionTypeImpl.con1(ExecutableElement element) : this(element);
 
   /**
    * Initialize a newly created function type to be declared by the given
@@ -4901,22 +4874,38 @@
    */
   @deprecated // Use new FunctionTypeImpl.forTypedef(element)
   FunctionTypeImpl.con2(FunctionTypeAliasElement element)
-      : prunedTypedefs = null,
-        super(element, element == null ? null : element.name);
+      : this.forTypedef(element);
 
   /**
    * Initialize a newly created function type to be declared by the given
    * [element].
    */
   FunctionTypeImpl.forTypedef(FunctionTypeAliasElement element,
-      [this.prunedTypedefs])
-      : super(element, element == null ? null : element.name);
+      [List<FunctionTypeAliasElement> prunedTypedefs])
+      : this._(element, element?.name, prunedTypedefs, null);
 
   /**
    * Private constructor.
    */
-  FunctionTypeImpl._(Element element, String name, this.prunedTypedefs)
-      : super(element, name);
+  FunctionTypeImpl._(Element element, String name, this.prunedTypedefs,
+      List<DartType> typeArguments)
+      : super(element, name) {
+    if (typeArguments != null) {
+      _typeArguments = typeArguments;
+    } else {
+      List<TypeParameterElement> typeParameters = this.typeParameters;
+      // TODO(jmesserly): reuse TypeParameterTypeImpl.getTypes once we can
+      // make it generic, which will allow it to return List<DartType> instead
+      // of List<TypeParameterType>.
+      if (typeParameters.isEmpty) {
+        _typeArguments = DartType.EMPTY_LIST;
+      } else {
+        _typeArguments = new List<DartType>.from(
+            typeParameters.map((t) => t.type),
+            growable: false);
+      }
+    }
+  }
 
   /**
    * Return the base parameter elements of this function element.
@@ -5168,18 +5157,23 @@
         TypeParameterTypeImpl.getTypes(typeParameters), newPrune);
   }
 
+  /**
+   * A list containing the actual types of the type arguments.
+   */
+  List<DartType> get typeArguments => _typeArguments;
+
   @override
   List<TypeParameterElement> get typeParameters {
-    Element element = this.element;
-    if (element is FunctionTypeAliasElement) {
-      return element.typeParameters;
+    // Combine the generic type arguments from all enclosing contexts.
+    // For example, this could be a generic method in a class, or a local
+    // function within another function.
+    List<TypeParameterElement> typeParams = <TypeParameterElement>[];
+    for (Element e = element; e != null; e = e.enclosingElement) {
+      if (e is TypeParameterizedElement) {
+        typeParams.addAll(e.typeParameters);
+      }
     }
-    ClassElement definingClass =
-        element.getAncestor((element) => element is ClassElement);
-    if (definingClass != null) {
-      return definingClass.typeParameters;
-    }
-    return TypeParameterElement.EMPTY_LIST;
+    return typeParams;
   }
 
   @override
@@ -5505,10 +5499,10 @@
       // alias, and function type aliases are always expanded by starting with
       // base types.
       assert(this.prunedTypedefs == null);
-      FunctionTypeImpl result = new FunctionTypeImpl._(element, name, prune);
-      result.typeArguments =
-          typeArguments.map((TypeImpl t) => t.pruned(prune)).toList();
-      return result;
+      List<DartType> typeArgs = typeArguments
+          .map((TypeImpl t) => t.pruned(prune))
+          .toList(growable: false);
+      return new FunctionTypeImpl._(element, name, prune, typeArgs);
     }
   }
 
@@ -5516,7 +5510,7 @@
   DartType substitute2(
       List<DartType> argumentTypes, List<DartType> parameterTypes,
       [List<FunctionTypeAliasElement> prune]) {
-    // Pruned types should only ever result from peforming type variable
+    // Pruned types should only ever result from performing type variable
     // substitution, and it doesn't make sense to substitute again after
     // substituting once.
     assert(this.prunedTypedefs == null);
@@ -5532,13 +5526,9 @@
     if (argumentTypes.length == 0) {
       return this.pruned(prune);
     }
-    FunctionTypeImpl newType = (element is ExecutableElement)
-        ? new FunctionTypeImpl(element, prune)
-        : new FunctionTypeImpl.forTypedef(
-            element as FunctionTypeAliasElement, prune);
-    newType.typeArguments =
+    List<DartType> typeArgs =
         TypeImpl.substitute(typeArguments, argumentTypes, parameterTypes);
-    return newType;
+    return new FunctionTypeImpl._(element, name, prune, typeArgs);
   }
 
   @override
@@ -6235,6 +6225,62 @@
       String name, LibraryElement library);
 
   /**
+   * Look up the member with the given [name] in this type and all extended
+   * and mixed in classes, and by default including [thisType]. If the search
+   * fails, this will then search interfaces.
+   *
+   * Return the element representing the member that was found, or `null` if
+   * there is no getter with the given name.
+   *
+   * The [library] determines if a private member name is visible, and does not
+   * need to be supplied for public names.
+   */
+  PropertyAccessorElement lookUpInheritedGetter(String name,
+      {LibraryElement library, bool thisType: true});
+
+  /**
+   * Look up the member with the given [name] in this type and all extended
+   * and mixed in classes, starting from this type. If the search fails,
+   * search interfaces.
+   *
+   * Return the element representing the member that was found, or `null` if
+   * there is no getter with the given name.
+   *
+   * The [library] determines if a private member name is visible, and does not
+   * need to be supplied for public names.
+   */
+  ExecutableElement lookUpInheritedGetterOrMethod(String name,
+      {LibraryElement library});
+
+  /**
+   * Look up the member with the given [name] in this type and all extended
+   * and mixed in classes, and by default including [thisType]. If the search
+   * fails, this will then search interfaces.
+   *
+   * Return the element representing the member that was found, or `null` if
+   * there is no getter with the given name.
+   *
+   * The [library] determines if a private member name is visible, and does not
+   * need to be supplied for public names.
+   */
+  MethodElement lookUpInheritedMethod(String name,
+      {LibraryElement library, bool thisType: true});
+
+  /**
+   * Look up the member with the given [name] in this type and all extended
+   * and mixed in classes, and by default including [thisType]. If the search
+   * fails, this will then search interfaces.
+   *
+   * Return the element representing the member that was found, or `null` if
+   * there is no getter with the given name.
+   *
+   * The [library] determines if a private member name is visible, and does not
+   * need to be supplied for public names.
+   */
+  PropertyAccessorElement lookUpInheritedSetter(String name,
+      {LibraryElement library, bool thisType: true});
+
+  /**
    * Return the element representing the method that results from looking up the
    * method with the given [name] in this class with respect to the given
    * [library], or `null` if the look up fails. The behavior of this method is
@@ -6842,6 +6888,71 @@
   }
 
   @override
+  PropertyAccessorElement lookUpInheritedGetter(String name,
+      {LibraryElement library, bool thisType: true}) {
+    PropertyAccessorElement result;
+    if (thisType) {
+      result = lookUpGetter(name, library);
+    } else {
+      result = lookUpGetterInSuperclass(name, library);
+    }
+    if (result != null) {
+      return result;
+    }
+    return _lookUpMemberInInterfaces(this, false, library,
+        new HashSet<ClassElement>(), (InterfaceType t) => t.getGetter(name));
+  }
+
+  @override
+  ExecutableElement lookUpInheritedGetterOrMethod(String name,
+      {LibraryElement library}) {
+    ExecutableElement result =
+        lookUpGetter(name, library) ?? lookUpMethod(name, library);
+
+    if (result != null) {
+      return result;
+    }
+    return _lookUpMemberInInterfaces(
+        this,
+        false,
+        library,
+        new HashSet<ClassElement>(),
+        (InterfaceType t) => t.getGetter(name) ?? t.getMethod(name));
+  }
+
+  @override
+  MethodElement lookUpInheritedMethod(String name,
+      {LibraryElement library, bool thisType: true}) {
+    MethodElement result;
+    if (thisType) {
+      result = lookUpMethod(name, library);
+    } else {
+      result = lookUpMethodInSuperclass(name, library);
+    }
+    if (result != null) {
+      return result;
+    }
+    return _lookUpMemberInInterfaces(this, false, library,
+        new HashSet<ClassElement>(), (InterfaceType t) => t.getMethod(name));
+  }
+
+  @override
+  PropertyAccessorElement lookUpInheritedSetter(String name,
+      {LibraryElement library, bool thisType: true}) {
+    PropertyAccessorElement result;
+    if (thisType) {
+      result = lookUpSetter(name, library);
+    } else {
+      result = lookUpSetterInSuperclass(name, library);
+    }
+    if (result != null) {
+      return result;
+    }
+    return _lookUpMemberInInterfaces(this, false, library,
+        new HashSet<ClassElement>(), (t) => t.getSetter(name));
+  }
+
+  @override
   MethodElement lookUpMethod(String methodName, LibraryElement library) {
     MethodElement element = getMethod(methodName);
     if (element != null && element.isAccessibleIn(library)) {
@@ -7115,6 +7226,58 @@
     result.retainAll(second);
     return new List.from(result);
   }
+
+  /**
+   * Look up the getter with the given [name] in the interfaces
+   * implemented by the given [targetType], either directly or indirectly.
+   * Return the element representing the getter that was found, or `null` if
+   * there is no getter with the given name. The flag [includeTargetType] should
+   * be `true` if the search should include the target type. The
+   * [visitedInterfaces] is a set containing all of the interfaces that have
+   * been examined, used to prevent infinite recursion and to optimize the
+   * search.
+   */
+  static ExecutableElement _lookUpMemberInInterfaces(
+      InterfaceType targetType,
+      bool includeTargetType,
+      LibraryElement library,
+      HashSet<ClassElement> visitedInterfaces,
+      ExecutableElement getMember(InterfaceType type)) {
+    // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the
+    // specification (titled "Inheritance and Overriding" under "Interfaces")
+    // describes a much more complex scheme for finding the inherited member.
+    // We need to follow that scheme. The code below should cover the 80% case.
+    ClassElement targetClass = targetType.element;
+    if (!visitedInterfaces.add(targetClass)) {
+      return null;
+    }
+    if (includeTargetType) {
+      ExecutableElement member = getMember(targetType);
+      if (member != null && member.isAccessibleIn(library)) {
+        return member;
+      }
+    }
+    for (InterfaceType interfaceType in targetType.interfaces) {
+      ExecutableElement member = _lookUpMemberInInterfaces(
+          interfaceType, true, library, visitedInterfaces, getMember);
+      if (member != null) {
+        return member;
+      }
+    }
+    for (InterfaceType mixinType in targetType.mixins.reversed) {
+      ExecutableElement member = _lookUpMemberInInterfaces(
+          mixinType, true, library, visitedInterfaces, getMember);
+      if (member != null) {
+        return member;
+      }
+    }
+    InterfaceType superclass = targetType.superclass;
+    if (superclass == null) {
+      return null;
+    }
+    return _lookUpMemberInInterfaces(
+        superclass, true, library, visitedInterfaces, getMember);
+  }
 }
 
 /**
@@ -7517,57 +7680,6 @@
     this._imports = imports;
   }
 
-  /** Given an update to this library which may have added or deleted edges
-   * in the import/export graph originating from this node only, remove any
-   * cached library cycles in the element model which may have been invalidated.
-   */
-  void invalidateLibraryCycles() {
-    if (_libraryCycle == null) {
-      // We have already invalidated this node, or we have never computed
-      // library cycle information for it.  In the former case, we're done. In
-      // the latter case, this node cannot be reachable from any node for which
-      // we have computed library cycle information.  Therefore, any edges added
-      // or deleted in the update causing this invalidation can only be edges to
-      // nodes which either have no library cycle information (and hence do not
-      // need invalidation), or which do not reach this node by any path.
-      // In either case, no further invalidation is needed.
-      return;
-    }
-    // If we have pre-computed library cycle information, then we must
-    // invalidate the information both on this element, and on certain
-    // other elements.  Edges originating at this node may have been
-    // added or deleted.  A deleted edge that points outside of this cycle
-    // cannot change the cycle information for anything outside of this cycle,
-    // and so it is sufficient to delete the cached library information on this
-    // cycle.  An added edge which points to another node within the cycle
-    // only invalidates the cycle.  An added edge which points to a node earlier
-    // in the topological sort of cycles induces no invalidation (since there
-    // are by definition no back edges from earlier cycles in the topological
-    // order, and hence no possible cycle can have been introduced.  The only
-    // remaining case is that we have added an edge to a node which is later
-    // in the topological sort of cycles.  This can induce cycles, since it
-    // represents a new back edge.  It would be sufficient to invalidate the
-    // cycle information for all nodes that are between the target and the
-    // node in the topological order.  For simplicity, we simply invalidate
-    // all nodes which are reachable from the the source node.
-    // Note that in the invalidation phase, we do not cut off when we encounter
-    // a node with no library cycle information, since we do not know whether
-    // we are in the case where invalidation has already been performed, or we
-    // are in the case where library cycles have simply never been computed from
-    // a newly reachable node.
-    Set<LibraryElementImpl> active = new HashSet();
-    void invalidate(LibraryElementImpl library) {
-      if (!active.add(library)) return;
-      if (library._libraryCycle != null) {
-        library._libraryCycle.forEach(invalidate);
-        library._libraryCycle = null;
-      }
-      library.exportedLibraries.forEach(invalidate);
-      library.importedLibraries.forEach(invalidate);
-    }
-    invalidate(this);
-  }
-
   @override
   bool get isBrowserApplication =>
       entryPoint != null && isOrImportsBrowserLibrary;
@@ -7805,6 +7917,57 @@
     return null;
   }
 
+  /** Given an update to this library which may have added or deleted edges
+   * in the import/export graph originating from this node only, remove any
+   * cached library cycles in the element model which may have been invalidated.
+   */
+  void invalidateLibraryCycles() {
+    if (_libraryCycle == null) {
+      // We have already invalidated this node, or we have never computed
+      // library cycle information for it.  In the former case, we're done. In
+      // the latter case, this node cannot be reachable from any node for which
+      // we have computed library cycle information.  Therefore, any edges added
+      // or deleted in the update causing this invalidation can only be edges to
+      // nodes which either have no library cycle information (and hence do not
+      // need invalidation), or which do not reach this node by any path.
+      // In either case, no further invalidation is needed.
+      return;
+    }
+    // If we have pre-computed library cycle information, then we must
+    // invalidate the information both on this element, and on certain
+    // other elements.  Edges originating at this node may have been
+    // added or deleted.  A deleted edge that points outside of this cycle
+    // cannot change the cycle information for anything outside of this cycle,
+    // and so it is sufficient to delete the cached library information on this
+    // cycle.  An added edge which points to another node within the cycle
+    // only invalidates the cycle.  An added edge which points to a node earlier
+    // in the topological sort of cycles induces no invalidation (since there
+    // are by definition no back edges from earlier cycles in the topological
+    // order, and hence no possible cycle can have been introduced.  The only
+    // remaining case is that we have added an edge to a node which is later
+    // in the topological sort of cycles.  This can induce cycles, since it
+    // represents a new back edge.  It would be sufficient to invalidate the
+    // cycle information for all nodes that are between the target and the
+    // node in the topological order.  For simplicity, we simply invalidate
+    // all nodes which are reachable from the the source node.
+    // Note that in the invalidation phase, we do not cut off when we encounter
+    // a node with no library cycle information, since we do not know whether
+    // we are in the case where invalidation has already been performed, or we
+    // are in the case where library cycles have simply never been computed from
+    // a newly reachable node.
+    Set<LibraryElementImpl> active = new HashSet();
+    void invalidate(LibraryElementImpl library) {
+      if (!active.add(library)) return;
+      if (library._libraryCycle != null) {
+        library._libraryCycle.forEach(invalidate);
+        library._libraryCycle = null;
+      }
+      library.exportedLibraries.forEach(invalidate);
+      library.importedLibraries.forEach(invalidate);
+    }
+    invalidate(this);
+  }
+
   @override
   bool isUpToDate(int timeStamp) {
     Set<LibraryElement> visitedLibraries = new Set();
@@ -8180,6 +8343,7 @@
    * Return the list of types that results from replacing the type parameters in
    * the given [types] with the type arguments associated with this member.
    */
+  @deprecated
   List<InterfaceType> substituteFor2(List<InterfaceType> types) {
     int count = types.length;
     List<InterfaceType> substitutedTypes = new List<InterfaceType>(count);
@@ -10364,6 +10528,20 @@
 }
 
 /**
+ * An element that has type parameters.
+ *
+ * For example, a class or a typedef. This also includes functions and methods
+ * if support for generic methods is enabled.
+ */
+abstract class TypeParameterizedElement implements Element {
+  /**
+   * Return a list containing all of the type parameters declared for this
+   * class.
+   */
+  List<TypeParameterElement> get typeParameters;
+}
+
+/**
  * The type introduced by a type parameter.
  */
 abstract class TypeParameterType implements DartType {
@@ -10745,9 +10923,6 @@
     setModifier(Modifier.CONST, isConst);
   }
 
-  @override
-  DartObject get constantValue => null;
-
   /**
    * If this element represents a constant variable, and it has an initializer,
    * a copy of the initializer for the constant.  Otherwise `null`.
@@ -10759,6 +10934,9 @@
    */
   Expression get constantInitializer => null;
 
+  @override
+  DartObject get constantValue => null;
+
   /**
    * Return the result of evaluating this variable's initializer as a
    * compile-time constant expression, or `null` if this variable is not a
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index ffe623b..a715f9a 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -729,6 +729,19 @@
 //          resolveArgumentsToParameters(node.getArgumentList(), invokedFunction);
           return null;
         }
+        ClassElementImpl typeReference = getTypeReference(target);
+        if (typeReference != null) {
+          ConstructorElement constructor =
+              typeReference.getNamedConstructor(methodName.name);
+          if (constructor != null) {
+            _recordUndefinedNode(
+                typeReference,
+                StaticTypeWarningCode.UNDEFINED_METHOD_WITH_CONSTRUCTOR,
+                methodName,
+                [methodName.name, typeReference.name]);
+            return null;
+          }
+        }
         targetTypeName = targetType == null ? null : targetType.displayName;
         ErrorCode proxyErrorCode = (generatedWithTypePropagation
             ? HintCode.UNDEFINED_METHOD
@@ -979,6 +992,10 @@
     if (node.inDeclarationContext()) {
       return null;
     }
+    if (node.staticElement is LocalVariableElement ||
+        node.staticElement is ParameterElement) {
+      return null;
+    }
     AstNode parent = node.parent;
     if (parent is FieldFormalParameter) {
       return null;
@@ -1573,76 +1590,13 @@
       Expression target, DartType type, String getterName) {
     type = _resolveTypeParameter(type);
     if (type is InterfaceType) {
-      InterfaceType interfaceType = type;
-      PropertyAccessorElement accessor;
-      if (target is SuperExpression) {
-        accessor = interfaceType.lookUpGetterInSuperclass(
-            getterName, _definingLibrary);
-      } else {
-        accessor = interfaceType.lookUpGetter(getterName, _definingLibrary);
-      }
-      if (accessor != null) {
-        return accessor;
-      }
-      return _lookUpGetterInInterfaces(
-          interfaceType, false, getterName, new HashSet<ClassElement>());
+      return type.lookUpInheritedGetter(getterName,
+          library: _definingLibrary, thisType: target is! SuperExpression);
     }
     return null;
   }
 
   /**
-   * Look up the getter with the given [getterName] in the interfaces
-   * implemented by the given [targetType], either directly or indirectly.
-   * Return the element representing the getter that was found, or `null` if
-   * there is no getter with the given name. The flag [includeTargetType] should
-   * be `true` if the search should include the target type. The
-   * [visitedInterfaces] is a set containing all of the interfaces that have
-   * been examined, used to prevent infinite recursion and to optimize the
-   * search.
-   */
-  PropertyAccessorElement _lookUpGetterInInterfaces(
-      InterfaceType targetType,
-      bool includeTargetType,
-      String getterName,
-      HashSet<ClassElement> visitedInterfaces) {
-    // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the
-    // specification (titled "Inheritance and Overriding" under "Interfaces")
-    // describes a much more complex scheme for finding the inherited member.
-    // We need to follow that scheme. The code below should cover the 80% case.
-    ClassElement targetClass = targetType.element;
-    if (visitedInterfaces.contains(targetClass)) {
-      return null;
-    }
-    visitedInterfaces.add(targetClass);
-    if (includeTargetType) {
-      PropertyAccessorElement getter = targetType.getGetter(getterName);
-      if (getter != null && getter.isAccessibleIn(_definingLibrary)) {
-        return getter;
-      }
-    }
-    for (InterfaceType interfaceType in targetType.interfaces) {
-      PropertyAccessorElement getter = _lookUpGetterInInterfaces(
-          interfaceType, true, getterName, visitedInterfaces);
-      if (getter != null) {
-        return getter;
-      }
-    }
-    for (InterfaceType mixinType in targetType.mixins.reversed) {
-      PropertyAccessorElement getter = _lookUpGetterInInterfaces(
-          mixinType, true, getterName, visitedInterfaces);
-      if (getter != null) {
-        return getter;
-      }
-    }
-    InterfaceType superclass = targetType.superclass;
-    if (superclass == null) {
-      return null;
-    }
-    return _lookUpGetterInInterfaces(
-        superclass, true, getterName, visitedInterfaces);
-  }
-
-  /**
    * Look up the method or getter with the given [memberName] in the given
    * [type]. Return the element representing the method or getter that was
    * found, or `null` if there is no method or getter with the given name.
@@ -1650,79 +1604,13 @@
   ExecutableElement _lookupGetterOrMethod(DartType type, String memberName) {
     type = _resolveTypeParameter(type);
     if (type is InterfaceType) {
-      InterfaceType interfaceType = type;
-      ExecutableElement member =
-          interfaceType.lookUpMethod(memberName, _definingLibrary);
-      if (member != null) {
-        return member;
-      }
-      member = interfaceType.lookUpGetter(memberName, _definingLibrary);
-      if (member != null) {
-        return member;
-      }
-      return _lookUpGetterOrMethodInInterfaces(
-          interfaceType, false, memberName, new HashSet<ClassElement>());
+      return type.lookUpInheritedGetterOrMethod(memberName,
+          library: _definingLibrary);
     }
     return null;
   }
 
   /**
-   * Look up the method or getter with the given [memberName] in the interfaces
-   * implemented by the given [targetType], either directly or indirectly.
-   * Return the element representing the method or getter that was found, or
-   * `null` if there is no method or getter with the given name. The flag
-   * [includeTargetType] should be `true` if the search should include the
-   * target type. The [visitedInterfaces] is a set containing all of the
-   * interfaces that have been examined, used to prevent infinite recursion and
-   * to optimize the search.
-   */
-  ExecutableElement _lookUpGetterOrMethodInInterfaces(
-      InterfaceType targetType,
-      bool includeTargetType,
-      String memberName,
-      HashSet<ClassElement> visitedInterfaces) {
-    // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the
-    // specification (titled "Inheritance and Overriding" under "Interfaces")
-    // describes a much more complex scheme for finding the inherited member.
-    // We need to follow that scheme. The code below should cover the 80% case.
-    ClassElement targetClass = targetType.element;
-    if (visitedInterfaces.contains(targetClass)) {
-      return null;
-    }
-    visitedInterfaces.add(targetClass);
-    if (includeTargetType) {
-      ExecutableElement member = targetType.getMethod(memberName);
-      if (member != null) {
-        return member;
-      }
-      member = targetType.getGetter(memberName);
-      if (member != null) {
-        return member;
-      }
-    }
-    for (InterfaceType interfaceType in targetType.interfaces) {
-      ExecutableElement member = _lookUpGetterOrMethodInInterfaces(
-          interfaceType, true, memberName, visitedInterfaces);
-      if (member != null) {
-        return member;
-      }
-    }
-    for (InterfaceType mixinType in targetType.mixins.reversed) {
-      ExecutableElement member = _lookUpGetterOrMethodInInterfaces(
-          mixinType, true, memberName, visitedInterfaces);
-      if (member != null) {
-        return member;
-      }
-    }
-    InterfaceType superclass = targetType.superclass;
-    if (superclass == null) {
-      return null;
-    }
-    return _lookUpGetterOrMethodInInterfaces(
-        superclass, true, memberName, visitedInterfaces);
-  }
-
-  /**
    * Look up the method with the given [methodName] in the given [type]. Return
    * the element representing the method that was found, or `null` if there is
    * no method with the given name. The [target] is the target of the
@@ -1732,76 +1620,13 @@
       Expression target, DartType type, String methodName) {
     type = _resolveTypeParameter(type);
     if (type is InterfaceType) {
-      InterfaceType interfaceType = type;
-      MethodElement method;
-      if (target is SuperExpression) {
-        method = interfaceType.lookUpMethodInSuperclass(
-            methodName, _definingLibrary);
-      } else {
-        method = interfaceType.lookUpMethod(methodName, _definingLibrary);
-      }
-      if (method != null) {
-        return method;
-      }
-      return _lookUpMethodInInterfaces(
-          interfaceType, false, methodName, new HashSet<ClassElement>());
+      return type.lookUpInheritedMethod(methodName,
+          library: _definingLibrary, thisType: target is! SuperExpression);
     }
     return null;
   }
 
   /**
-   * Look up the method with the given [methodName] in the interfaces
-   * implemented by the given [targetType], either directly or indirectly.
-   * Return the element representing the method that was found, or `null` if
-   * there is no method with the given name. The flag [includeTargetType] should
-   * be `true` if the search should include the target type. The
-   * [visitedInterfaces] is a set containing all of the interfaces that have
-   * been examined, used to prevent infinite recursion and to optimize the
-   * search.
-   */
-  MethodElement _lookUpMethodInInterfaces(
-      InterfaceType targetType,
-      bool includeTargetType,
-      String methodName,
-      HashSet<ClassElement> visitedInterfaces) {
-    // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the
-    // specification (titled "Inheritance and Overriding" under "Interfaces")
-    // describes a much more complex scheme for finding the inherited member.
-    // We need to follow that scheme. The code below should cover the 80% case.
-    ClassElement targetClass = targetType.element;
-    if (visitedInterfaces.contains(targetClass)) {
-      return null;
-    }
-    visitedInterfaces.add(targetClass);
-    if (includeTargetType) {
-      MethodElement method = targetType.getMethod(methodName);
-      if (method != null && method.isAccessibleIn(_definingLibrary)) {
-        return method;
-      }
-    }
-    for (InterfaceType interfaceType in targetType.interfaces) {
-      MethodElement method = _lookUpMethodInInterfaces(
-          interfaceType, true, methodName, visitedInterfaces);
-      if (method != null) {
-        return method;
-      }
-    }
-    for (InterfaceType mixinType in targetType.mixins.reversed) {
-      MethodElement method = _lookUpMethodInInterfaces(
-          mixinType, true, methodName, visitedInterfaces);
-      if (method != null) {
-        return method;
-      }
-    }
-    InterfaceType superclass = targetType.superclass;
-    if (superclass == null) {
-      return null;
-    }
-    return _lookUpMethodInInterfaces(
-        superclass, true, methodName, visitedInterfaces);
-  }
-
-  /**
    * Look up the setter with the given [setterName] in the given [type]. Return
    * the element representing the setter that was found, or `null` if there is
    * no setter with the given name. The [target] is the target of the
@@ -1811,77 +1636,13 @@
       Expression target, DartType type, String setterName) {
     type = _resolveTypeParameter(type);
     if (type is InterfaceType) {
-      InterfaceType interfaceType = type;
-      PropertyAccessorElement accessor;
-      if (target is SuperExpression) {
-        accessor = interfaceType.lookUpSetterInSuperclass(
-            setterName, _definingLibrary);
-      } else {
-        accessor = interfaceType.lookUpSetter(setterName, _definingLibrary);
-      }
-      if (accessor != null) {
-        return accessor;
-      }
-      return _lookUpSetterInInterfaces(
-          interfaceType, false, setterName, new HashSet<ClassElement>());
+      return type.lookUpInheritedSetter(setterName,
+          library: _definingLibrary, thisType: target is! SuperExpression);
     }
     return null;
   }
 
   /**
-   * Look up the setter with the given [setterName] in the interfaces
-   * implemented by the given [targetType], either directly or indirectly.
-   * Return the element representing the setter that was found, or `null` if
-   * there is no setter with the given name. The [targetType] is the type in
-   * which the setter might be defined. The flag [includeTargetType] should be
-   * `true` if the search should include the target type. The
-   * [visitedInterfaces] is a set containing all of the interfaces that have
-   * been examined, used to prevent infinite recursion and to optimize the
-   * search.
-   */
-  PropertyAccessorElement _lookUpSetterInInterfaces(
-      InterfaceType targetType,
-      bool includeTargetType,
-      String setterName,
-      HashSet<ClassElement> visitedInterfaces) {
-    // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the
-    // specification (titled "Inheritance and Overriding" under "Interfaces")
-    // describes a much more complex scheme for finding the inherited member.
-    // We need to follow that scheme. The code below should cover the 80% case.
-    ClassElement targetClass = targetType.element;
-    if (visitedInterfaces.contains(targetClass)) {
-      return null;
-    }
-    visitedInterfaces.add(targetClass);
-    if (includeTargetType) {
-      PropertyAccessorElement setter = targetType.getSetter(setterName);
-      if (setter != null && setter.isAccessibleIn(_definingLibrary)) {
-        return setter;
-      }
-    }
-    for (InterfaceType interfaceType in targetType.interfaces) {
-      PropertyAccessorElement setter = _lookUpSetterInInterfaces(
-          interfaceType, true, setterName, visitedInterfaces);
-      if (setter != null) {
-        return setter;
-      }
-    }
-    for (InterfaceType mixinType in targetType.mixins.reversed) {
-      PropertyAccessorElement setter = _lookUpSetterInInterfaces(
-          mixinType, true, setterName, visitedInterfaces);
-      if (setter != null) {
-        return setter;
-      }
-    }
-    InterfaceType superclass = targetType.superclass;
-    if (superclass == null) {
-      return null;
-    }
-    return _lookUpSetterInInterfaces(
-        superclass, true, setterName, visitedInterfaces);
-  }
-
-  /**
    * Given some class [element], this method uses [_subtypeManager] to find the
    * set of all subtypes; the subtypes are then searched for a member (method,
    * getter, or setter), that has the given [memberName]. The flag [asMethod]
@@ -2122,6 +1883,13 @@
       _resolver.reportErrorForNode(
           CompileTimeErrorCode.INVALID_ANNOTATION, annotation);
     }
+    // no arguments
+    if (annotation.arguments != null) {
+      _resolver.reportErrorForNode(
+          CompileTimeErrorCode.ANNOTATION_WITH_NON_CLASS,
+          annotation.name,
+          [annotation.name]);
+    }
     // OK
     return;
   }
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 5822a61..597d381 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -8,6 +8,7 @@
 import 'dart:collection';
 import 'dart:math' as math;
 
+import 'package:analyzer/source/embedder.dart';
 import 'package:analyzer/src/cancelable_future.dart';
 import 'package:analyzer/src/context/cache.dart' as cache;
 import 'package:analyzer/src/context/context.dart' as newContext;
@@ -452,7 +453,7 @@
    * analysis results that have been invalidated by these changes will be
    * removed.
    */
-  void applyChanges(ChangeSet changeSet);
+  ApplyChangesStatus applyChanges(ChangeSet changeSet);
 
   /**
    * Return the documentation comment for the given [element] as it appears in
@@ -591,8 +592,8 @@
       Source unitSource, Source librarySource);
 
   /**
-   * Return configuration data associated with the given key or `null` if no
-   * state has been associated with the given [key].
+   * Return configuration data associated with the given key or the [key]'s
+   * default value if no state has been associated.
    *
    * See [setConfigurationData].
    */
@@ -964,6 +965,9 @@
    */
   AnalysisOptionsImpl _options = new AnalysisOptionsImpl();
 
+  /// The embedder yaml locator for this context.
+  EmbedderYamlLocator _embedderYamlLocator = new EmbedderYamlLocator(null);
+
   /**
    * A flag indicating whether errors related to implicitly analyzed sources
    * should be generated and reported.
@@ -1156,6 +1160,9 @@
   AnalysisOptions get analysisOptions => _options;
 
   @override
+  EmbedderYamlLocator get embedderYamlLocator => _embedderYamlLocator;
+
+  @override
   void set analysisOptions(AnalysisOptions options) {
     bool needsRecompute = this._options.analyzeFunctionBodiesPredicate !=
             options.analyzeFunctionBodiesPredicate ||
@@ -1616,9 +1623,9 @@
   }
 
   @override
-  void applyChanges(ChangeSet changeSet) {
+  ApplyChangesStatus applyChanges(ChangeSet changeSet) {
     if (changeSet.isEmpty) {
-      return;
+      return new ApplyChangesStatus(false);
     }
     //
     // First, compute the list of sources that have been removed.
@@ -1658,6 +1665,7 @@
       _sourceRemoved(source);
     }
     _onSourcesChangedController.add(new SourcesChangedEvent(changeSet));
+    return new ApplyChangesStatus(true);
   }
 
   @override
@@ -6469,6 +6477,7 @@
     cacheSize = options.cacheSize;
     dart2jsHint = options.dart2jsHint;
     enableStrictCallChecks = options.enableStrictCallChecks;
+    enableGenericMethods = options.enableGenericMethods;
     enableSuperMixins = options.enableSuperMixins;
     generateImplicitErrors = options.generateImplicitErrors;
     generateSdkErrors = options.generateSdkErrors;
@@ -6490,6 +6499,7 @@
     cacheSize = options.cacheSize;
     dart2jsHint = options.dart2jsHint;
     enableStrictCallChecks = options.enableStrictCallChecks;
+    enableGenericMethods = options.enableGenericMethods;
     enableSuperMixins = options.enableSuperMixins;
     generateImplicitErrors = options.generateImplicitErrors;
     generateSdkErrors = options.generateSdkErrors;
@@ -6800,6 +6810,18 @@
 }
 
 /**
+ * The result of applying a [ChangeSet] to a [AnalysisContext].
+ */
+class ApplyChangesStatus {
+  /**
+   * Is `true` if the given [ChangeSet] caused any changes in the context.
+   */
+  final bool hasChanges;
+
+  ApplyChangesStatus(this.hasChanges);
+}
+
+/**
  * A `CachedResult` is a single analysis result that is stored in a
  * [SourceEntry].
  */
@@ -9427,6 +9449,9 @@
    */
   dynamic get privateAnalysisCachePartition;
 
+  /// Get the [EmbedderYamlLocator] for this context.
+  EmbedderYamlLocator get embedderYamlLocator;
+  
   /**
    * A factory to override how [ResolverVisitor] is created.
    */
diff --git a/pkg/analyzer/lib/src/generated/error.dart b/pkg/analyzer/lib/src/generated/error.dart
index af45572..f547807 100644
--- a/pkg/analyzer/lib/src/generated/error.dart
+++ b/pkg/analyzer/lib/src/generated/error.dart
@@ -6,13 +6,30 @@
 
 import 'dart:collection';
 
+import 'package:analyzer/src/generated/ast.dart' show AstNode;
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
+import 'package:analyzer/src/generated/scanner.dart'
+    show ScannerErrorCode, Token;
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/model.dart';
+import 'package:analyzer/task/model.dart';
 import 'package:source_span/source_span.dart';
 
-import 'ast.dart' show AstNode;
-import 'element.dart';
-import 'java_core.dart';
-import 'scanner.dart' show Token;
-import 'source.dart';
+/**
+ * The descriptor used to associate error filters with analysis contexts in
+ * configuration data.
+ */
+final ListResultDescriptor<List<ErrorFilter>> CONFIGURED_ERROR_FILTERS =
+    new ListResultDescriptorImpl('configured.errors', const <ErrorFilter>[]);
+
+/**
+ * A predicate used to potentially filter an [error].
+ *
+ * Returns `true` if this error should be filtered from analysis results.
+ */
+typedef bool ErrorFilter(AnalysisError error);
 
 /**
  * An error discovered during the analysis of some Dart code.
@@ -334,15 +351,53 @@
 class AnalysisOptionsWarningCode extends ErrorCode {
   /**
    * An error code indicating that a plugin is being configured with an
-   * unsupported option.
+   * unsupported option and legal options are provided.
    *
    * Parameters:
    * 0: the plugin name
    * 1: the unsupported option key
+   * 2: legal values
    */
-  static const AnalysisOptionsWarningCode UNSUPPORTED_OPTION =
-      const AnalysisOptionsWarningCode('UNSUPPORTED_OPTION_ERROR',
-          "The option '{1}' is not supported by {0}");
+  static const AnalysisOptionsWarningCode UNSUPPORTED_OPTION_WITH_LEGAL_VALUES =
+      const AnalysisOptionsWarningCode('UNSUPPORTED_OPTION_WITH_LEGAL_VALUES',
+          "The option '{1}' is not supported by {0}, supported values are {2}");
+
+  /**
+   * An error code indicating that a plugin is being configured with an
+   * unsupported option where there is just one legal value.
+   *
+   * Parameters:
+   * 0: the plugin name
+   * 1: the unsupported option key
+   * 2: the legal value
+   */
+  static const AnalysisOptionsWarningCode UNSUPPORTED_OPTION_WITH_LEGAL_VALUE =
+      const AnalysisOptionsWarningCode('UNSUPPORTED_OPTION_WITH_LEGAL_VALUE',
+          "The option '{1}' is not supported by {0}, did you mean {2}?");
+
+  /**
+   * An error code indicating that an option entry is being configured with an
+   * unsupported value.
+   *
+   * Parameters:
+   * 0: the option name
+   * 1: the unsupported value
+   * 2: legal values
+   */
+  static const AnalysisOptionsWarningCode UNSUPPORTED_VALUE =
+      const AnalysisOptionsWarningCode('UNSUPPORTED_VALUE',
+          "The value '{1}' is not supported by {0}, legal values are {2}");
+
+  /**
+   * An error code indicating that an unrecognized error code is being used to
+   * specify an error filter.
+   *
+   * Parameters:
+   * 0: the unrecognized error code
+   */
+  static const AnalysisOptionsWarningCode UNRECOGNIZED_ERROR_CODE =
+      const AnalysisOptionsWarningCode(
+          'UNRECOGNIZED_ERROR_CODE', "'{0}' is not a recognized error code");
 
   /**
    * Initialize a newly created warning code to have the given [name].
@@ -542,6 +597,26 @@
           "The name '{0}' is defined in the libraries '{1}' and '{2}'");
 
   /**
+   * 15 Metadata: The constant expression given in an annotation is type checked
+   * and evaluated in the scope surrounding the declaration being annotated.
+   *
+   * 12.11.2 Const: It is a compile-time error if <i>T</i> is not a class
+   * accessible in the current scope, optionally followed by type arguments.
+   *
+   * 12.11.2 Const: If <i>e</i> is of the form <i>const T.id(a<sub>1</sub>,
+   * &hellip;, a<sub>n</sub>, x<sub>n+1</sub>: a<sub>n+1</sub>, &hellip;
+   * x<sub>n+k</sub>: a<sub>n+k</sub>)</i> it is a compile-time error if
+   * <i>T</i> is not a class accessible in the current scope, optionally
+   * followed by type arguments.
+   *
+   * Parameters:
+   * 0: the name of the non-type element
+   */
+  static const CompileTimeErrorCode ANNOTATION_WITH_NON_CLASS =
+      const CompileTimeErrorCode(
+          'ANNOTATION_WITH_NON_CLASS', "The name '{0}' is not a class");
+
+  /**
    * 12.33 Argument Definition Test: It is a compile time error if <i>v</i> does
    * not denote a formal parameter.
    *
@@ -2421,62 +2496,6 @@
 }
 
 /**
- * An error listener that can be enabled or disabled while executing a function.
- */
-class DisablableErrorListener implements AnalysisErrorListener {
-  /**
-   * The listener to which errors will be reported if this listener is enabled.
-   */
-  final AnalysisErrorListener baseListener;
-
-  /**
-   * A flag indicating whether this listener is currently enabled.
-   */
-  bool enabled = true;
-
-  /**
-   * Initialize a newly created listener to report errors to the given
-   * [baseListener].
-   */
-  DisablableErrorListener(this.baseListener);
-
-  /**
-   * Disable the processing of errors while evaluating the given [function].
-   * Return the value returned by the function.
-   */
-  dynamic disableWhile(dynamic function()) {
-    bool wasEnabled = enabled;
-    try {
-      enabled = false;
-      return function();
-    } finally {
-      enabled = wasEnabled;
-    }
-  }
-
-  /**
-   * Disable the processing of errors while evaluating the given [function].
-   * Return the value returned by the function.
-   */
-  dynamic enableWhile(dynamic function()) {
-    bool wasEnabled = enabled;
-    try {
-      enabled = true;
-      return function();
-    } finally {
-      enabled = wasEnabled;
-    }
-  }
-
-  @override
-  void onError(AnalysisError error) {
-    if (enabled) {
-      baseListener.onError(error);
-    }
-  }
-}
-
-/**
  * An error code associated with an [AnalysisError].
  *
  * Generally, we want to provide messages that consist of three sentences. From
@@ -2489,6 +2508,535 @@
  */
 abstract class ErrorCode {
   /**
+   * Engine error code values.
+   */
+  static const List<ErrorCode> values = const [
+    //
+    // Manually generated.  FWIW, this get's you most of the way there:
+    //
+    // > grep 'static const .*Code' (error.dart|parser|scanner.dart)
+    //     | awk '{print $3"."$4","}'
+    //
+    // error.dart:
+    //
+    AnalysisOptionsErrorCode.PARSE_ERROR,
+    AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE,
+    AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES,
+    CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
+    CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
+    CheckedModeCompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE,
+    CheckedModeCompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,
+    CheckedModeCompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE,
+    CheckedModeCompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE,
+    CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH,
+    CompileTimeErrorCode.ACCESS_PRIVATE_ENUM_FIELD,
+    CompileTimeErrorCode.AMBIGUOUS_EXPORT,
+    CompileTimeErrorCode.ANNOTATION_WITH_NON_CLASS,
+    CompileTimeErrorCode.ARGUMENT_DEFINITION_TEST_NON_PARAMETER,
+    CompileTimeErrorCode.ASYNC_FOR_IN_WRONG_CONTEXT,
+    CompileTimeErrorCode.AWAIT_IN_WRONG_CONTEXT,
+    CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE,
+    CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME,
+    CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME,
+    CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME,
+    CompileTimeErrorCode.CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS,
+    CompileTimeErrorCode.COMPILE_TIME_CONSTANT_RAISES_EXCEPTION,
+    CompileTimeErrorCode.CONFLICTING_GETTER_AND_METHOD,
+    CompileTimeErrorCode.CONFLICTING_METHOD_AND_GETTER,
+    CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD,
+    CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD,
+    CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS,
+    CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER,
+    CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION,
+    CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST,
+    CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN,
+    CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER,
+    CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD,
+    CompileTimeErrorCode.CONST_DEFERRED_CLASS,
+    CompileTimeErrorCode.CONST_FORMAL_PARAMETER,
+    CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE,
+    CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE_FROM_DEFERRED_LIBRARY,
+    CompileTimeErrorCode.CONST_INSTANCE_FIELD,
+    CompileTimeErrorCode.CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS,
+    CompileTimeErrorCode.CONST_NOT_INITIALIZED,
+    CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL,
+    CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING,
+    CompileTimeErrorCode.CONST_EVAL_TYPE_INT,
+    CompileTimeErrorCode.CONST_EVAL_TYPE_NUM,
+    CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
+    CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE,
+    CompileTimeErrorCode.CONST_WITH_INVALID_TYPE_PARAMETERS,
+    CompileTimeErrorCode.CONST_WITH_NON_CONST,
+    CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT,
+    CompileTimeErrorCode.CONST_WITH_NON_TYPE,
+    CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS,
+    CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR,
+    CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT,
+    CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS,
+    CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER,
+    CompileTimeErrorCode.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR,
+    CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT,
+    CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME,
+    CompileTimeErrorCode.DUPLICATE_DEFINITION,
+    CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE,
+    CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT,
+    CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY,
+    CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY,
+    CompileTimeErrorCode.EXTENDS_ENUM,
+    CompileTimeErrorCode.EXTENDS_NON_CLASS,
+    CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS,
+    CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS,
+    CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS,
+    CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS,
+    CompileTimeErrorCode.FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER,
+    CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES,
+    CompileTimeErrorCode.FIELD_INITIALIZER_FACTORY_CONSTRUCTOR,
+    CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR,
+    CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR,
+    CompileTimeErrorCode.GETTER_AND_METHOD_WITH_SAME_NAME,
+    CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS,
+    CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS,
+    CompileTimeErrorCode.IMPLEMENTS_DYNAMIC,
+    CompileTimeErrorCode.IMPLEMENTS_ENUM,
+    CompileTimeErrorCode.IMPLEMENTS_NON_CLASS,
+    CompileTimeErrorCode.IMPLEMENTS_REPEATED,
+    CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS,
+    CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER,
+    CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY,
+    CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY,
+    CompileTimeErrorCode.INCONSISTENT_CASE_EXPRESSION_TYPES,
+    CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD,
+    CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD,
+    CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD,
+    CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD,
+    CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY,
+    CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC,
+    CompileTimeErrorCode.INSTANTIATE_ENUM,
+    CompileTimeErrorCode.INVALID_ANNOTATION,
+    CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY,
+    CompileTimeErrorCode.INVALID_IDENTIFIER_IN_ASYNC,
+    CompileTimeErrorCode.INVALID_MODIFIER_ON_CONSTRUCTOR,
+    CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER,
+    CompileTimeErrorCode.INVALID_CONSTANT,
+    CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME,
+    CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLASS,
+    CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS,
+    CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST,
+    CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP,
+    CompileTimeErrorCode.INVALID_URI,
+    CompileTimeErrorCode.LABEL_IN_OUTER_SCOPE,
+    CompileTimeErrorCode.LABEL_UNDEFINED,
+    CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME,
+    CompileTimeErrorCode.METHOD_AND_GETTER_WITH_SAME_NAME,
+    CompileTimeErrorCode.MISSING_CONST_IN_LIST_LITERAL,
+    CompileTimeErrorCode.MISSING_CONST_IN_MAP_LITERAL,
+    CompileTimeErrorCode.MISSING_ENUM_CONSTANT_IN_SWITCH,
+    CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR,
+    CompileTimeErrorCode.MIXIN_DEFERRED_CLASS,
+    CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS,
+    CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT,
+    CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS,
+    CompileTimeErrorCode.MIXIN_OF_ENUM,
+    CompileTimeErrorCode.MIXIN_OF_NON_CLASS,
+    CompileTimeErrorCode.MIXIN_REFERENCES_SUPER,
+    CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS,
+    CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS,
+    CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS,
+    CompileTimeErrorCode.NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS,
+    CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT,
+    CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT,
+    CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT,
+    CompileTimeErrorCode.NON_CONSTANT_CASE_EXPRESSION,
+    CompileTimeErrorCode.NON_CONSTANT_CASE_EXPRESSION_FROM_DEFERRED_LIBRARY,
+    CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE,
+    CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE_FROM_DEFERRED_LIBRARY,
+    CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT,
+    CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY,
+    CompileTimeErrorCode.NON_CONSTANT_MAP_KEY,
+    CompileTimeErrorCode.NON_CONSTANT_MAP_KEY_FROM_DEFERRED_LIBRARY,
+    CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE,
+    CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY,
+    CompileTimeErrorCode.NON_CONSTANT_ANNOTATION_CONSTRUCTOR,
+    CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER,
+    CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY,
+    CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS,
+    CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR,
+    CompileTimeErrorCode.OBJECT_CANNOT_EXTEND_ANOTHER_CLASS,
+    CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR,
+    CompileTimeErrorCode.PART_OF_NON_PART,
+    CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER,
+    CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
+    CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER,
+    CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT,
+    CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT,
+    CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
+    CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
+    CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS,
+    CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS,
+    CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH,
+    CompileTimeErrorCode.REDIRECT_TO_MISSING_CONSTRUCTOR,
+    CompileTimeErrorCode.REDIRECT_TO_NON_CLASS,
+    CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR,
+    CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR,
+    CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR,
+    CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION,
+    CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH,
+    CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR,
+    CompileTimeErrorCode.RETURN_IN_GENERATOR,
+    CompileTimeErrorCode.SHARED_DEFERRED_PREFIX,
+    CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT,
+    CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR,
+    CompileTimeErrorCode.SUPER_INITIALIZER_IN_OBJECT,
+    CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
+    CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF,
+    CompileTimeErrorCode.UNDEFINED_CLASS,
+    CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER,
+    CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT,
+    CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER,
+    CompileTimeErrorCode.URI_DOES_NOT_EXIST,
+    CompileTimeErrorCode.URI_WITH_INTERPOLATION,
+    CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR,
+    CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS,
+    CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER,
+    CompileTimeErrorCode.YIELD_EACH_IN_NON_GENERATOR,
+    CompileTimeErrorCode.YIELD_IN_NON_GENERATOR,
+    HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
+    HintCode.DEAD_CODE,
+    HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH,
+    HintCode.DEAD_CODE_ON_CATCH_SUBTYPE,
+    HintCode.DEPRECATED_MEMBER_USE,
+    HintCode.DUPLICATE_IMPORT,
+    HintCode.DIVISION_OPTIMIZATION,
+    HintCode.IS_DOUBLE,
+    HintCode.IS_INT,
+    HintCode.IS_NOT_DOUBLE,
+    HintCode.IS_NOT_INT,
+    HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION,
+    HintCode.INVALID_ASSIGNMENT,
+    HintCode.MISSING_RETURN,
+    HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER,
+    HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD,
+    HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER,
+    HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE,
+    HintCode.TYPE_CHECK_IS_NOT_NULL,
+    HintCode.TYPE_CHECK_IS_NULL,
+    HintCode.UNDEFINED_GETTER,
+    HintCode.UNDEFINED_METHOD,
+    HintCode.UNDEFINED_OPERATOR,
+    HintCode.UNDEFINED_SETTER,
+    HintCode.UNNECESSARY_CAST,
+    HintCode.UNNECESSARY_TYPE_CHECK_FALSE,
+    HintCode.UNNECESSARY_TYPE_CHECK_TRUE,
+    HintCode.UNUSED_ELEMENT,
+    HintCode.UNUSED_FIELD,
+    HintCode.UNUSED_IMPORT,
+    HintCode.UNUSED_CATCH_CLAUSE,
+    HintCode.UNUSED_CATCH_STACK,
+    HintCode.UNUSED_LOCAL_VARIABLE,
+    HintCode.USE_OF_VOID_RESULT,
+    HintCode.FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE,
+    HintCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE,
+    HintCode.NULL_AWARE_IN_CONDITION,
+    HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT,
+    HtmlErrorCode.PARSE_ERROR,
+    HtmlWarningCode.INVALID_URI,
+    HtmlWarningCode.URI_DOES_NOT_EXIST,
+    StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS,
+    StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS,
+    StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE,
+    StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE,
+    StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE,
+    StaticTypeWarningCode.INACCESSIBLE_SETTER,
+    StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE,
+    StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER,
+    StaticTypeWarningCode.INVALID_ASSIGNMENT,
+    StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION,
+    StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION,
+    StaticTypeWarningCode.NON_BOOL_CONDITION,
+    StaticTypeWarningCode.NON_BOOL_EXPRESSION,
+    StaticTypeWarningCode.NON_BOOL_NEGATION_EXPRESSION,
+    StaticTypeWarningCode.NON_BOOL_OPERAND,
+    StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT,
+    StaticTypeWarningCode.RETURN_OF_INVALID_TYPE,
+    StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
+    StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND,
+    StaticTypeWarningCode.UNDEFINED_ENUM_CONSTANT,
+    StaticTypeWarningCode.UNDEFINED_FUNCTION,
+    StaticTypeWarningCode.UNDEFINED_GETTER,
+    StaticTypeWarningCode.UNDEFINED_METHOD,
+    StaticTypeWarningCode.UNDEFINED_OPERATOR,
+    StaticTypeWarningCode.UNDEFINED_SETTER,
+    StaticTypeWarningCode.UNDEFINED_SUPER_GETTER,
+    StaticTypeWarningCode.UNDEFINED_SUPER_METHOD,
+    StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR,
+    StaticTypeWarningCode.UNDEFINED_SUPER_SETTER,
+    StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER,
+    StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS,
+    StaticTypeWarningCode.YIELD_OF_INVALID_TYPE,
+    StaticWarningCode.AMBIGUOUS_IMPORT,
+    StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
+    StaticWarningCode.ASSIGNMENT_TO_CONST,
+    StaticWarningCode.ASSIGNMENT_TO_FINAL,
+    StaticWarningCode.ASSIGNMENT_TO_FINAL_NO_SETTER,
+    StaticWarningCode.ASSIGNMENT_TO_FUNCTION,
+    StaticWarningCode.ASSIGNMENT_TO_METHOD,
+    StaticWarningCode.ASSIGNMENT_TO_TYPE,
+    StaticWarningCode.CASE_BLOCK_NOT_TERMINATED,
+    StaticWarningCode.CAST_TO_NON_TYPE,
+    StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER,
+    StaticWarningCode.CONFLICTING_DART_IMPORT,
+    StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER,
+    StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER,
+    StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER2,
+    StaticWarningCode.CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER,
+    StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER,
+    StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER,
+    StaticWarningCode.CONST_WITH_ABSTRACT_CLASS,
+    StaticWarningCode.EQUAL_KEYS_IN_MAP,
+    StaticWarningCode.EXPORT_DUPLICATED_LIBRARY_NAMED,
+    StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS,
+    StaticWarningCode.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION,
+    StaticWarningCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR,
+    StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE,
+    StaticWarningCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE,
+    StaticWarningCode.FINAL_NOT_INITIALIZED,
+    StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_1,
+    StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_2,
+    StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_3_PLUS,
+    StaticWarningCode.FUNCTION_WITHOUT_CALL,
+    StaticWarningCode.IMPORT_DUPLICATED_LIBRARY_NAMED,
+    StaticWarningCode.IMPORT_OF_NON_LIBRARY,
+    StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD,
+    StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC,
+    StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE,
+    StaticWarningCode.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE,
+    StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE,
+    StaticWarningCode.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE,
+    StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE,
+    StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED,
+    StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
+    StaticWarningCode.INVALID_OVERRIDE_NAMED,
+    StaticWarningCode.INVALID_OVERRIDE_POSITIONAL,
+    StaticWarningCode.INVALID_OVERRIDE_REQUIRED,
+    StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE,
+    StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,
+    StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE,
+    StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE,
+    StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES,
+    StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE,
+    StaticWarningCode.MIXED_RETURN_TYPES,
+    StaticWarningCode.NEW_WITH_ABSTRACT_CLASS,
+    StaticWarningCode.NEW_WITH_INVALID_TYPE_PARAMETERS,
+    StaticWarningCode.NEW_WITH_NON_TYPE,
+    StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR,
+    StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT,
+    StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS,
+    StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR,
+    StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE,
+    StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE,
+    StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO,
+    StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE,
+    StaticWarningCode.NON_VOID_RETURN_FOR_OPERATOR,
+    StaticWarningCode.NON_VOID_RETURN_FOR_SETTER,
+    StaticWarningCode.NOT_A_TYPE,
+    StaticWarningCode.NOT_ENOUGH_REQUIRED_ARGUMENTS,
+    StaticWarningCode.PART_OF_DIFFERENT_LIBRARY,
+    StaticWarningCode.REDIRECT_TO_INVALID_FUNCTION_TYPE,
+    StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE,
+    StaticWarningCode.REDIRECT_TO_MISSING_CONSTRUCTOR,
+    StaticWarningCode.REDIRECT_TO_NON_CLASS,
+    StaticWarningCode.RETURN_WITHOUT_VALUE,
+    StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER,
+    StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE,
+    StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS,
+    StaticWarningCode.TYPE_TEST_WITH_NON_TYPE,
+    StaticWarningCode.TYPE_TEST_WITH_UNDEFINED_NAME,
+    StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC,
+    StaticWarningCode.UNDEFINED_CLASS,
+    StaticWarningCode.UNDEFINED_CLASS_BOOLEAN,
+    StaticWarningCode.UNDEFINED_GETTER,
+    StaticWarningCode.UNDEFINED_IDENTIFIER,
+    StaticWarningCode.UNDEFINED_NAMED_PARAMETER,
+    StaticWarningCode.UNDEFINED_SETTER,
+    StaticWarningCode.UNDEFINED_STATIC_METHOD_OR_GETTER,
+    StaticWarningCode.UNDEFINED_SUPER_GETTER,
+    StaticWarningCode.UNDEFINED_SUPER_SETTER,
+    StaticWarningCode.VOID_RETURN_FOR_GETTER,
+    TodoCode.TODO,
+
+    //
+    // parser.dart:
+    //
+    ParserErrorCode.ABSTRACT_CLASS_MEMBER,
+    ParserErrorCode.ABSTRACT_ENUM,
+    ParserErrorCode.ABSTRACT_STATIC_METHOD,
+    ParserErrorCode.ABSTRACT_TOP_LEVEL_FUNCTION,
+    ParserErrorCode.ABSTRACT_TOP_LEVEL_VARIABLE,
+    ParserErrorCode.ABSTRACT_TYPEDEF,
+    ParserErrorCode.ANNOTATION_ON_ENUM_CONSTANT,
+    ParserErrorCode.ASSERT_DOES_NOT_TAKE_ASSIGNMENT,
+    ParserErrorCode.ASSERT_DOES_NOT_TAKE_CASCADE,
+    ParserErrorCode.ASSERT_DOES_NOT_TAKE_THROW,
+    ParserErrorCode.ASSERT_DOES_NOT_TAKE_RETHROW,
+    ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER,
+    ParserErrorCode.BREAK_OUTSIDE_OF_LOOP,
+    ParserErrorCode.CLASS_IN_CLASS,
+    ParserErrorCode.COLON_IN_PLACE_OF_IN,
+    ParserErrorCode.CONST_AND_FINAL,
+    ParserErrorCode.CONST_AND_VAR,
+    ParserErrorCode.CONST_CLASS,
+    ParserErrorCode.CONST_CONSTRUCTOR_WITH_BODY,
+    ParserErrorCode.CONST_ENUM,
+    ParserErrorCode.CONST_FACTORY,
+    ParserErrorCode.CONST_METHOD,
+    ParserErrorCode.CONST_TYPEDEF,
+    ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE,
+    ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP,
+    ParserErrorCode.CONTINUE_WITHOUT_LABEL_IN_CASE,
+    ParserErrorCode.DEPRECATED_CLASS_TYPE_ALIAS,
+    ParserErrorCode.DIRECTIVE_AFTER_DECLARATION,
+    ParserErrorCode.DUPLICATE_LABEL_IN_SWITCH_STATEMENT,
+    ParserErrorCode.DUPLICATED_MODIFIER,
+    ParserErrorCode.EMPTY_ENUM_BODY,
+    ParserErrorCode.ENUM_IN_CLASS,
+    ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND,
+    ParserErrorCode.EXPECTED_CASE_OR_DEFAULT,
+    ParserErrorCode.EXPECTED_CLASS_MEMBER,
+    ParserErrorCode.EXPECTED_EXECUTABLE,
+    ParserErrorCode.EXPECTED_LIST_OR_MAP_LITERAL,
+    ParserErrorCode.EXPECTED_STRING_LITERAL,
+    ParserErrorCode.EXPECTED_TOKEN,
+    ParserErrorCode.EXPECTED_TYPE_NAME,
+    ParserErrorCode.EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE,
+    ParserErrorCode.EXTERNAL_AFTER_CONST,
+    ParserErrorCode.EXTERNAL_AFTER_FACTORY,
+    ParserErrorCode.EXTERNAL_AFTER_STATIC,
+    ParserErrorCode.EXTERNAL_CLASS,
+    ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY,
+    ParserErrorCode.EXTERNAL_ENUM,
+    ParserErrorCode.EXTERNAL_FIELD,
+    ParserErrorCode.EXTERNAL_GETTER_WITH_BODY,
+    ParserErrorCode.EXTERNAL_METHOD_WITH_BODY,
+    ParserErrorCode.EXTERNAL_OPERATOR_WITH_BODY,
+    ParserErrorCode.EXTERNAL_SETTER_WITH_BODY,
+    ParserErrorCode.EXTERNAL_TYPEDEF,
+    ParserErrorCode.FACTORY_TOP_LEVEL_DECLARATION,
+    ParserErrorCode.FACTORY_WITH_INITIALIZERS,
+    ParserErrorCode.FACTORY_WITHOUT_BODY,
+    ParserErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR,
+    ParserErrorCode.FINAL_AND_VAR,
+    ParserErrorCode.FINAL_CLASS,
+    ParserErrorCode.FINAL_CONSTRUCTOR,
+    ParserErrorCode.FINAL_ENUM,
+    ParserErrorCode.FINAL_METHOD,
+    ParserErrorCode.FINAL_TYPEDEF,
+    ParserErrorCode.FUNCTION_TYPED_PARAMETER_VAR,
+    ParserErrorCode.GETTER_IN_FUNCTION,
+    ParserErrorCode.GETTER_WITH_PARAMETERS,
+    ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE,
+    ParserErrorCode.IMPLEMENTS_BEFORE_EXTENDS,
+    ParserErrorCode.IMPLEMENTS_BEFORE_WITH,
+    ParserErrorCode.IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE,
+    ParserErrorCode.INITIALIZED_VARIABLE_IN_FOR_EACH,
+    ParserErrorCode.INVALID_AWAIT_IN_FOR,
+    ParserErrorCode.INVALID_CODE_POINT,
+    ParserErrorCode.INVALID_COMMENT_REFERENCE,
+    ParserErrorCode.INVALID_HEX_ESCAPE,
+    ParserErrorCode.INVALID_OPERATOR,
+    ParserErrorCode.INVALID_OPERATOR_FOR_SUPER,
+    ParserErrorCode.INVALID_STAR_AFTER_ASYNC,
+    ParserErrorCode.INVALID_SYNC,
+    ParserErrorCode.INVALID_UNICODE_ESCAPE,
+    ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST,
+    ParserErrorCode.LOCAL_FUNCTION_DECLARATION_MODIFIER,
+    ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR,
+    ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER,
+    ParserErrorCode.MISSING_CATCH_OR_FINALLY,
+    ParserErrorCode.MISSING_CLASS_BODY,
+    ParserErrorCode.MISSING_CLOSING_PARENTHESIS,
+    ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE,
+    ParserErrorCode.MISSING_ENUM_BODY,
+    ParserErrorCode.MISSING_EXPRESSION_IN_INITIALIZER,
+    ParserErrorCode.MISSING_EXPRESSION_IN_THROW,
+    ParserErrorCode.MISSING_FUNCTION_BODY,
+    ParserErrorCode.MISSING_FUNCTION_PARAMETERS,
+    ParserErrorCode.MISSING_METHOD_PARAMETERS,
+    ParserErrorCode.MISSING_GET,
+    ParserErrorCode.MISSING_IDENTIFIER,
+    ParserErrorCode.MISSING_INITIALIZER,
+    ParserErrorCode.MISSING_KEYWORD_OPERATOR,
+    ParserErrorCode.MISSING_NAME_IN_LIBRARY_DIRECTIVE,
+    ParserErrorCode.MISSING_NAME_IN_PART_OF_DIRECTIVE,
+    ParserErrorCode.MISSING_PREFIX_IN_DEFERRED_IMPORT,
+    ParserErrorCode.MISSING_STAR_AFTER_SYNC,
+    ParserErrorCode.MISSING_STATEMENT,
+    ParserErrorCode.MISSING_TERMINATOR_FOR_PARAMETER_GROUP,
+    ParserErrorCode.MISSING_TYPEDEF_PARAMETERS,
+    ParserErrorCode.MISSING_VARIABLE_IN_FOR_EACH,
+    ParserErrorCode.MIXED_PARAMETER_GROUPS,
+    ParserErrorCode.MULTIPLE_EXTENDS_CLAUSES,
+    ParserErrorCode.MULTIPLE_IMPLEMENTS_CLAUSES,
+    ParserErrorCode.MULTIPLE_LIBRARY_DIRECTIVES,
+    ParserErrorCode.MULTIPLE_NAMED_PARAMETER_GROUPS,
+    ParserErrorCode.MULTIPLE_PART_OF_DIRECTIVES,
+    ParserErrorCode.MULTIPLE_POSITIONAL_PARAMETER_GROUPS,
+    ParserErrorCode.MULTIPLE_VARIABLES_IN_FOR_EACH,
+    ParserErrorCode.MULTIPLE_WITH_CLAUSES,
+    ParserErrorCode.NAMED_FUNCTION_EXPRESSION,
+    ParserErrorCode.NAMED_PARAMETER_OUTSIDE_GROUP,
+    ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE,
+    ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE,
+    ParserErrorCode.NON_CONSTRUCTOR_FACTORY,
+    ParserErrorCode.NON_IDENTIFIER_LIBRARY_NAME,
+    ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART,
+    ParserErrorCode.NON_STRING_LITERAL_AS_URI,
+    ParserErrorCode.NON_USER_DEFINABLE_OPERATOR,
+    ParserErrorCode.NORMAL_BEFORE_OPTIONAL_PARAMETERS,
+    ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT,
+    ParserErrorCode.POSITIONAL_PARAMETER_OUTSIDE_GROUP,
+    ParserErrorCode.REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR,
+    ParserErrorCode.SETTER_IN_FUNCTION,
+    ParserErrorCode.STATIC_AFTER_CONST,
+    ParserErrorCode.STATIC_AFTER_FINAL,
+    ParserErrorCode.STATIC_AFTER_VAR,
+    ParserErrorCode.STATIC_CONSTRUCTOR,
+    ParserErrorCode.STATIC_GETTER_WITHOUT_BODY,
+    ParserErrorCode.STATIC_OPERATOR,
+    ParserErrorCode.STATIC_SETTER_WITHOUT_BODY,
+    ParserErrorCode.STATIC_TOP_LEVEL_DECLARATION,
+    ParserErrorCode.SWITCH_HAS_CASE_AFTER_DEFAULT_CASE,
+    ParserErrorCode.SWITCH_HAS_MULTIPLE_DEFAULT_CASES,
+    ParserErrorCode.TOP_LEVEL_OPERATOR,
+    ParserErrorCode.TYPEDEF_IN_CLASS,
+    ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP,
+    ParserErrorCode.UNEXPECTED_TOKEN,
+    ParserErrorCode.WITH_BEFORE_EXTENDS,
+    ParserErrorCode.WITH_WITHOUT_EXTENDS,
+    ParserErrorCode.WRONG_SEPARATOR_FOR_NAMED_PARAMETER,
+    ParserErrorCode.WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER,
+    ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP,
+    ParserErrorCode.VAR_AND_TYPE,
+    ParserErrorCode.VAR_AS_TYPE_NAME,
+    ParserErrorCode.VAR_CLASS,
+    ParserErrorCode.VAR_ENUM,
+    ParserErrorCode.VAR_RETURN_TYPE,
+    ParserErrorCode.VAR_TYPEDEF,
+    ParserErrorCode.VOID_PARAMETER,
+    ParserErrorCode.VOID_VARIABLE,
+
+    //
+    // scanner.dart:
+    //
+    ScannerErrorCode.ILLEGAL_CHARACTER,
+    ScannerErrorCode.MISSING_DIGIT,
+    ScannerErrorCode.MISSING_HEX_DIGIT,
+    ScannerErrorCode.MISSING_QUOTE,
+    ScannerErrorCode.UNABLE_GET_CONTENT,
+    ScannerErrorCode.UNTERMINATED_MULTI_LINE_COMMENT,
+    ScannerErrorCode.UNTERMINATED_STRING_LITERAL,
+  ];
+
+  /**
    * An empty list of error codes.
    */
   static const List<ErrorCode> EMPTY_LIST = const <ErrorCode>[];
@@ -2916,6 +3464,15 @@
       "The argument type '{0}' cannot be assigned to the parameter type '{1}'");
 
   /**
+   * When the target expression uses '?.' operator, it can be `null`, so all the
+   * subsequent invocations should also use '?.' operator.
+   */
+  static const HintCode CAN_BE_NULL_AFTER_NULL_AWARE = const HintCode(
+      'CAN_BE_NULL_AFTER_NULL_AWARE',
+      "The expression uses '?.', so can be 'null'",
+      "Replace the '.' with a '?.' in the invocation");
+
+  /**
    * Dead code is code that is never reached, this can happen for instance if a
    * statement follows a return statement.
    */
@@ -3023,6 +3580,15 @@
       "Either add a return statement or change the return type to 'void'");
 
   /**
+   * A condition in a control flow statement could evaluate to `null` because it
+   * uses the null-aware '?.' operator.
+   */
+  static const HintCode NULL_AWARE_IN_CONDITION = const HintCode(
+      'NULL_AWARE_IN_CONDITION',
+      "The value of the '?.' operator can be 'null', which is not appropriate in a condition",
+      "Replace the '?.' with a '.', testing the left-hand side for null if necessary");
+
+  /**
    * A getter with the override annotation does not override an existing getter.
    */
   static const HintCode OVERRIDE_ON_NON_OVERRIDING_GETTER = const HintCode(
@@ -3668,6 +4234,21 @@
           "The method '{0}' is not defined for the class '{1}'");
 
   /**
+   * 12.15.1 Ordinary Invocation: Let <i>T</i> be the static type of <i>o</i>.
+   * It is a static type warning if <i>T</i> does not have an accessible
+   * instance member named <i>m</i>.
+   *
+   * Parameters:
+   * 0: the name of the method that is undefined
+   * 1: the resolved type name that the method lookup is happening on
+   */
+  static const StaticTypeWarningCode UNDEFINED_METHOD_WITH_CONSTRUCTOR =
+      const StaticTypeWarningCode(
+          'UNDEFINED_METHOD_WITH_CONSTRUCTOR',
+          "The method '{0}' is not defined for the class '{1}', but a constructor with that name is defined",
+          "Add 'new' or 'const' to invoke the constuctor, or change the method name.");
+
+  /**
    * 12.18 Assignment: Evaluation of an assignment of the form
    * <i>e<sub>1</sub></i>[<i>e<sub>2</sub></i>] = <i>e<sub>3</sub></i> is
    * equivalent to the evaluation of the expression (a, i, e){a.[]=(i, e);
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index ec9559a..f76ab09 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -6046,6 +6046,12 @@
   }
 
   @override
+  Object visitFunctionElement(FunctionElement element) {
+    _addTypeToCheck(element.returnType);
+    return super.visitFunctionElement(element);
+  }
+
+  @override
   Object visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
     _addTypeToCheck(element.returnType);
     return super.visitFunctionTypeAliasElement(element);
diff --git a/pkg/analyzer/lib/src/generated/java_engine.dart b/pkg/analyzer/lib/src/generated/java_engine.dart
index d0fb62b..8b10e71 100644
--- a/pkg/analyzer/lib/src/generated/java_engine.dart
+++ b/pkg/analyzer/lib/src/generated/java_engine.dart
@@ -121,6 +121,33 @@
 
   static Interner INTERNER = new NullInterner();
 
+  /**
+   * Compute line starts for the given [content].
+   * Lines end with `\r`, `\n` or `\r\n`.
+   */
+  static List<int> computeLineStarts(String content) {
+    List<int> lineStarts = <int>[0];
+    int length = content.length;
+    int unit;
+    for (int index = 0; index < length; index++) {
+      unit = content.codeUnitAt(index);
+      // Special-case \r\n.
+      if (unit == 0x0D /* \r */) {
+        // Peek ahead to detect a following \n.
+        if ((index + 1 < length) && content.codeUnitAt(index + 1) == 0x0A) {
+          // Line start will get registered at next index at the \n.
+        } else {
+          lineStarts.add(index + 1);
+        }
+      }
+      // \n
+      if (unit == 0x0A) {
+        lineStarts.add(index + 1);
+      }
+    }
+    return lineStarts;
+  }
+
   static endsWith3(String str, int c1, int c2, int c3) {
     var length = str.length;
     return length >= 3 &&
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index 76f9dc7..42872c1 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -2123,6 +2123,12 @@
   bool parseGenericMethods = false;
 
   /**
+   * A flag indicating whether to parse generic method comments, of the form
+   * `/*=T*/` and `/*<T>*/`.
+   */
+  bool parseGenericMethodComments = false;
+
+  /**
    * Initialize a newly created parser to parse the content of the given
    * [_source] and to report any errors that are found to the given
    * [_errorListener].
@@ -2514,7 +2520,9 @@
           parseSimpleIdentifier(),
           parseFormalParameterList());
     } else if (_tokenMatches(_peek(), TokenType.OPEN_PAREN)) {
+      TypeName returnType = _parseOptionalTypeNameComment();
       SimpleIdentifier methodName = parseSimpleIdentifier();
+      TypeParameterList typeParameters = _parseGenericCommentTypeParameters();
       FormalParameterList parameters = parseFormalParameterList();
       if (_matches(TokenType.COLON) ||
           modifiers.factoryKeyword != null ||
@@ -2535,9 +2543,9 @@
           commentAndMetadata,
           modifiers.externalKeyword,
           modifiers.staticKeyword,
-          null,
+          returnType,
           methodName,
-          null,
+          typeParameters,
           parameters);
     } else if (_peek()
         .matchesAny([TokenType.EQ, TokenType.COMMA, TokenType.SEMICOLON])) {
@@ -2617,6 +2625,7 @@
       }
     } else if (_tokenMatches(_peek(), TokenType.OPEN_PAREN)) {
       SimpleIdentifier methodName = parseSimpleIdentifier();
+      TypeParameterList typeParameters = _parseGenericCommentTypeParameters();
       FormalParameterList parameters = parseFormalParameterList();
       if (methodName.name == className) {
         _reportErrorForNode(ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE, type);
@@ -2638,7 +2647,7 @@
           modifiers.staticKeyword,
           type,
           methodName,
-          null,
+          typeParameters,
           parameters);
     } else if (parseGenericMethods && _tokenMatches(_peek(), TokenType.LT)) {
       return _parseMethodDeclarationAfterReturnType(commentAndMetadata,
@@ -3135,10 +3144,7 @@
    *         typeParameters? formalParameterList functionExpressionBody
    */
   FunctionExpression parseFunctionExpression() {
-    TypeParameterList typeParameters = null;
-    if (parseGenericMethods && _matches(TokenType.LT)) {
-      typeParameters = parseTypeParameterList();
-    }
+    TypeParameterList typeParameters = _parseGenericMethodTypeParameters();
     FormalParameterList parameters = parseFormalParameterList();
     _validateFormalParameterList(parameters);
     FunctionBody body =
@@ -3265,10 +3271,7 @@
       period = _expect(TokenType.PERIOD);
     }
     SimpleIdentifier identifier = parseSimpleIdentifier();
-    TypeParameterList typeParameters = null;
-    if (parseGenericMethods && _matches(TokenType.LT)) {
-      typeParameters = parseTypeParameterList();
-    }
+    TypeParameterList typeParameters = _parseGenericMethodTypeParameters();
     if (_matches(TokenType.OPEN_PAREN)) {
       FormalParameterList parameters = parseFormalParameterList();
       if (thisKeyword == null) {
@@ -3476,21 +3479,13 @@
    *         qualified typeArguments?
    */
   TypeName parseTypeName() {
-    Identifier typeName;
-    if (_matchesKeyword(Keyword.VAR)) {
-      _reportErrorForCurrentToken(ParserErrorCode.VAR_AS_TYPE_NAME);
-      typeName = new SimpleIdentifier(getAndAdvance());
-    } else if (_matchesIdentifier()) {
-      typeName = parsePrefixedIdentifier();
-    } else {
-      typeName = _createSyntheticIdentifier();
-      _reportErrorForCurrentToken(ParserErrorCode.EXPECTED_TYPE_NAME);
-    }
-    TypeArgumentList typeArguments = null;
-    if (_matches(TokenType.LT)) {
-      typeArguments = parseTypeArgumentList();
-    }
-    return new TypeName(typeName, typeArguments);
+    TypeName realType = _parseTypeName();
+    // If this is followed by a generic method type comment, allow the comment
+    // type to replace the real type name.
+    // TODO(jmesserly): this feels like a big hammer. Can we restrict it to
+    // only work inside generic methods?
+    TypeName typeComment = _parseOptionalTypeNameComment();
+    return typeComment ?? realType;
   }
 
   /**
@@ -3909,6 +3904,46 @@
     return null;
   }
 
+  bool _injectGenericComment(TokenType type, int prefixLen) {
+    if (parseGenericMethodComments) {
+      CommentToken t = _currentToken.precedingComments;
+      for (; t != null; t = t.next) {
+        if (t.type == type) {
+          String comment = t.lexeme.substring(prefixLen, t.lexeme.length - 2);
+          Token list = _scanGenericMethodComment(comment, t.offset + prefixLen);
+          if (list != null) {
+            // Insert the tokens into the stream.
+            _injectTokenList(list);
+            return true;
+          }
+        }
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Matches a generic comment type substitution and injects it into the token
+   * stream. Returns true if a match was injected, otherwise false.
+   *
+   * These comments are of the form `/*=T*/`, in other words, a [TypeName]
+   * inside a slash-star comment, preceded by equals sign.
+   */
+  bool _injectGenericCommentTypeAssign() {
+    return _injectGenericComment(TokenType.GENERIC_METHOD_TYPE_ASSIGN, 3);
+  }
+
+  /**
+   * Matches a generic comment type parameters and injects them into the token
+   * stream. Returns true if a match was injected, otherwise false.
+   *
+   * These comments are of the form `/*<K, V>*/`, in other words, a
+   * [TypeParameterList] or [TypeArgumentList] inside a slash-star comment.
+   */
+  bool _injectGenericCommentTypeList() {
+    return _injectGenericComment(TokenType.GENERIC_METHOD_TYPE_LIST, 2);
+  }
+
   /**
    * Inject the given [token] into the token stream immediately before the
    * current token.
@@ -3920,6 +3955,19 @@
     return token;
   }
 
+  void _injectTokenList(Token firstToken) {
+    // Scanner creates a cyclic EOF token.
+    Token lastToken = firstToken;
+    while (lastToken.next.type != TokenType.EOF) {
+      lastToken = lastToken.next;
+    }
+    // Inject these new tokens into the stream.
+    Token previous = _currentToken.previous;
+    lastToken.setNext(_currentToken);
+    previous.setNext(firstToken);
+    _currentToken = firstToken;
+  }
+
   /**
    * Return `true` if the current token appears to be the beginning of a
    * function declaration.
@@ -4361,10 +4409,7 @@
     bool isOptional = primaryAllowed || expression is SimpleIdentifier;
     while (true) {
       while (_isLikelyParameterList()) {
-        TypeArgumentList typeArguments = null;
-        if (_matches(TokenType.LT)) {
-          typeArguments = parseTypeArgumentList();
-        }
+        TypeArgumentList typeArguments = _parseOptionalTypeArguments();
         ArgumentList argumentList = parseArgumentList();
         if (expression is SimpleIdentifier) {
           expression = new MethodInvocation(null, null,
@@ -4573,10 +4618,7 @@
         (expression != null && functionName == null));
     if (_isLikelyParameterList()) {
       while (_isLikelyParameterList()) {
-        TypeArgumentList typeArguments = null;
-        if (_matches(TokenType.LT)) {
-          typeArguments = parseTypeArgumentList();
-        }
+        TypeArgumentList typeArguments = _parseOptionalTypeArguments();
         if (functionName != null) {
           expression = new MethodInvocation(expression, period, functionName,
               typeArguments, parseArgumentList());
@@ -4604,10 +4646,7 @@
         expression = selector;
         progress = true;
         while (_isLikelyParameterList()) {
-          TypeArgumentList typeArguments = null;
-          if (_matches(TokenType.LT)) {
-            typeArguments = parseTypeArgumentList();
-          }
+          TypeArgumentList typeArguments = _parseOptionalTypeArguments();
           if (expression is PropertyAccess) {
             PropertyAccess propertyAccess = expression as PropertyAccess;
             expression = new MethodInvocation(
@@ -5087,7 +5126,8 @@
           _peek().matchesAny([
             TokenType.OPEN_PAREN,
             TokenType.OPEN_CURLY_BRACKET,
-            TokenType.FUNCTION
+            TokenType.FUNCTION,
+            TokenType.LT
           ])) {
         _validateModifiersForTopLevelFunction(modifiers);
         return _parseFunctionDeclaration(
@@ -5691,16 +5731,27 @@
       keyword = getAndAdvance();
       if (_isTypedIdentifier(_currentToken)) {
         type = parseTypeName();
+      } else {
+        // Support `final/*=T*/ x;`
+        type = _parseOptionalTypeNameComment();
       }
     } else if (_matchesKeyword(Keyword.VAR)) {
       keyword = getAndAdvance();
-    } else {
-      if (_isTypedIdentifier(_currentToken)) {
-        type = parseReturnType();
-      } else if (!optional) {
-        _reportErrorForCurrentToken(
-            ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE);
+      // Support `var/*=T*/ x;`
+      type = _parseOptionalTypeNameComment();
+      if (type != null) {
+        // Clear the keyword to prevent an error.
+        keyword = null;
       }
+    } else if (_isTypedIdentifier(_currentToken)) {
+      type = parseReturnType();
+    } else if (!optional) {
+      _reportErrorForCurrentToken(
+          ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE);
+    } else {
+      // Support parameters such as `(/*=K*/ key, /*=V*/ value)`
+      // This is not supported if the type is required.
+      type = _parseOptionalTypeNameComment();
     }
     return new FinalConstVarOrType(keyword, type);
   }
@@ -6025,10 +6076,7 @@
       keyword = getAndAdvance();
     }
     SimpleIdentifier name = parseSimpleIdentifier();
-    TypeParameterList typeParameters = null;
-    if (parseGenericMethods && _matches(TokenType.LT)) {
-      typeParameters = parseTypeParameterList();
-    }
+    TypeParameterList typeParameters = _parseGenericMethodTypeParameters();
     FormalParameterList parameters = null;
     if (!isGetter) {
       if (_matches(TokenType.OPEN_PAREN)) {
@@ -6182,6 +6230,37 @@
   }
 
   /**
+   * Parses generic type parameters from a comment.
+   *
+   * Normally this is handled by [_parseGenericMethodTypeParameters], but if the
+   * code already handles the normal generic type parameters, the comment
+   * matcher can be called directly. For example, we may have already tried
+   * matching `<` (less than sign) in a method declaration, and be currently
+   * on the `(` (open paren) because we didn't find it. In that case, this
+   * function will parse the preceding comment such as `/*<T, R>*/`.
+   */
+  TypeParameterList _parseGenericCommentTypeParameters() {
+    if (_injectGenericCommentTypeList()) {
+      return parseTypeParameterList();
+    }
+    return null;
+  }
+
+  /**
+   * Parse the generic method or function's type parameters.
+   *
+   * For backwards compatibility this can optionally use comments.
+   * See [parseGenericMethodComments].
+   */
+  TypeParameterList _parseGenericMethodTypeParameters() {
+    if (parseGenericMethods && _matches(TokenType.LT) ||
+        _injectGenericCommentTypeList()) {
+      return parseTypeParameterList();
+    }
+    return null;
+  }
+
+  /**
    * Parse a getter. The [commentAndMetadata] is the documentation comment and
    * metadata to be associated with the declaration. The externalKeyword] is the
    * 'external' token. The staticKeyword] is the static keyword, or `null` if
@@ -6473,10 +6552,7 @@
    *       | mapLiteral
    */
   TypedLiteral _parseListOrMapLiteral(Token modifier) {
-    TypeArgumentList typeArguments = null;
-    if (_matches(TokenType.LT)) {
-      typeArguments = parseTypeArgumentList();
-    }
+    TypeArgumentList typeArguments = _parseOptionalTypeArguments();
     if (_matches(TokenType.OPEN_CURLY_BRACKET)) {
       return _parseMapLiteral(modifier, typeArguments);
     } else if (_matches(TokenType.OPEN_SQUARE_BRACKET) ||
@@ -6610,10 +6686,7 @@
       Token staticKeyword,
       TypeName returnType) {
     SimpleIdentifier methodName = parseSimpleIdentifier();
-    TypeParameterList typeParameters = null;
-    if (parseGenericMethods && _matches(TokenType.LT)) {
-      typeParameters = parseTypeParameterList();
-    }
+    TypeParameterList typeParameters = _parseGenericMethodTypeParameters();
     FormalParameterList parameters;
     if (!_matches(TokenType.OPEN_PAREN) &&
         (_matches(TokenType.OPEN_CURLY_BRACKET) ||
@@ -7010,7 +7083,10 @@
    * advancing. Return the return type that was parsed.
    */
   TypeName _parseOptionalReturnType() {
-    if (_matchesKeyword(Keyword.VOID)) {
+    TypeName typeComment = _parseOptionalTypeNameComment();
+    if (typeComment != null) {
+      return typeComment;
+    } else if (_matchesKeyword(Keyword.VOID)) {
       return parseReturnType();
     } else if (_matchesIdentifier() &&
         !_matchesKeyword(Keyword.GET) &&
@@ -7030,6 +7106,24 @@
   }
 
   /**
+   * Parse a [TypeArgumentList] if present, otherwise return null.
+   * This also supports the comment form, if enabled: `/*<T>*/`
+   */
+  TypeArgumentList _parseOptionalTypeArguments() {
+    if (_matches(TokenType.LT) || _injectGenericCommentTypeList()) {
+      return parseTypeArgumentList();
+    }
+    return null;
+  }
+
+  TypeName _parseOptionalTypeNameComment() {
+    if (_injectGenericCommentTypeAssign()) {
+      return _parseTypeName();
+    }
+    return null;
+  }
+
+  /**
    * Parse a part or part-of directive. The [commentAndMetadata] is the metadata
    * to be associated with the directive. Return the part or part-of directive
    * that was parsed.
@@ -7081,10 +7175,7 @@
         (parseGenericMethods && _matches(TokenType.LT))) {
       do {
         if (_isLikelyParameterList()) {
-          TypeArgumentList typeArguments = null;
-          if (_matches(TokenType.LT)) {
-            typeArguments = parseTypeArgumentList();
-          }
+          TypeArgumentList typeArguments = _parseOptionalTypeArguments();
           ArgumentList argumentList = parseArgumentList();
           if (operand is PropertyAccess) {
             PropertyAccess access = operand as PropertyAccess;
@@ -7741,6 +7832,21 @@
     return _parseFunctionTypeAlias(commentAndMetadata, keyword);
   }
 
+  TypeName _parseTypeName() {
+    Identifier typeName;
+    if (_matchesKeyword(Keyword.VAR)) {
+      _reportErrorForCurrentToken(ParserErrorCode.VAR_AS_TYPE_NAME);
+      typeName = new SimpleIdentifier(getAndAdvance());
+    } else if (_matchesIdentifier()) {
+      typeName = parsePrefixedIdentifier();
+    } else {
+      typeName = _createSyntheticIdentifier();
+      _reportErrorForCurrentToken(ParserErrorCode.EXPECTED_TYPE_NAME);
+    }
+    TypeArgumentList typeArguments = _parseOptionalTypeArguments();
+    return new TypeName(typeName, typeArguments);
+  }
+
   /**
    * Parse a unary expression. Return the unary expression that was parsed.
    *
@@ -8084,6 +8190,22 @@
   }
 
   /**
+   * Scans the generic method comment, and returns the tokens, otherwise
+   * returns null.
+   */
+  Token _scanGenericMethodComment(String code, int offset) {
+    BooleanErrorListener listener = new BooleanErrorListener();
+    Scanner scanner =
+        new Scanner(null, new SubSequenceReader(code, offset), listener);
+    scanner.setSourceStart(1, 1);
+    Token firstToken = scanner.tokenize();
+    if (listener.errorReported) {
+      return null;
+    }
+    return firstToken;
+  }
+
+  /**
    * Skips a block with all containing blocks.
    */
   void _skipBlock() {
@@ -8420,7 +8542,8 @@
    */
   Token _skipTypeArgumentList(Token startToken) {
     Token token = startToken;
-    if (!_tokenMatches(token, TokenType.LT)) {
+    if (!_tokenMatches(token, TokenType.LT) &&
+        !_injectGenericCommentTypeList()) {
       return null;
     }
     token = _skipTypeName(token.next);
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 40a2162..ad1cd60 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -16,12 +16,16 @@
 import 'html.dart' as ht;
 import 'java_core.dart';
 import 'java_engine.dart';
+import 'scanner.dart';
 import 'scanner.dart' as sc;
 import 'sdk.dart' show DartSdk, SdkLibrary;
 import 'source.dart';
 import 'static_type_analyzer.dart';
+import 'type_system.dart';
 import 'utilities_dart.dart';
 
+export 'type_system.dart';
+
 /**
  * Callback signature used by ImplicitConstructorBuilder to register
  * computations to be performed, and their dependencies.  A call to this
@@ -44,10 +48,6 @@
 
 typedef void VoidFunction();
 
-typedef bool _GuardedSubtypeChecker<T>(T t1, T t2, Set<Element> visited);
-
-typedef bool _SubtypeChecker<T>(T t1, T t2);
-
 /**
  * Instances of the class `BestPracticesVerifier` traverse an AST structure looking for
  * violations of Dart best practices.
@@ -104,6 +104,12 @@
   }
 
   @override
+  Object visitAssertStatement(AssertStatement node) {
+    _checkForPossibleNullCondition(node.condition);
+    return super.visitAssertStatement(node);
+  }
+
+  @override
   Object visitAssignmentExpression(AssignmentExpression node) {
     sc.TokenType operatorType = node.operator.type;
     if (operatorType == sc.TokenType.EQ) {
@@ -136,18 +142,42 @@
   }
 
   @override
+  Object visitConditionalExpression(ConditionalExpression node) {
+    _checkForPossibleNullCondition(node.condition);
+    return super.visitConditionalExpression(node);
+  }
+
+  @override
+  Object visitDoStatement(DoStatement node) {
+    _checkForPossibleNullCondition(node.condition);
+    return super.visitDoStatement(node);
+  }
+
+  @override
   Object visitExportDirective(ExportDirective node) {
     _checkForDeprecatedMemberUse(node.uriElement, node);
     return super.visitExportDirective(node);
   }
 
   @override
+  Object visitForStatement(ForStatement node) {
+    _checkForPossibleNullCondition(node.condition);
+    return super.visitForStatement(node);
+  }
+
+  @override
   Object visitFunctionDeclaration(FunctionDeclaration node) {
     _checkForMissingReturn(node.returnType, node.functionExpression.body);
     return super.visitFunctionDeclaration(node);
   }
 
   @override
+  Object visitIfStatement(IfStatement node) {
+    _checkForPossibleNullCondition(node.condition);
+    return super.visitIfStatement(node);
+  }
+
+  @override
   Object visitImportDirective(ImportDirective node) {
     _checkForDeprecatedMemberUse(node.uriElement, node);
     ImportElement importElement = node.element;
@@ -186,6 +216,12 @@
   }
 
   @override
+  Object visitMethodInvocation(MethodInvocation node) {
+    _checkForCanBeNullAfterNullAware(node.realTarget, node.operator);
+    return super.visitMethodInvocation(node);
+  }
+
+  @override
   Object visitPostfixExpression(PostfixExpression node) {
     _checkForDeprecatedMemberUse(node.bestElement, node);
     return super.visitPostfixExpression(node);
@@ -198,6 +234,12 @@
   }
 
   @override
+  Object visitPropertyAccess(PropertyAccess node) {
+    _checkForCanBeNullAfterNullAware(node.realTarget, node.operator);
+    return super.visitPropertyAccess(node);
+  }
+
+  @override
   Object visitRedirectingConstructorInvocation(
       RedirectingConstructorInvocation node) {
     _checkForDeprecatedMemberUse(node.staticElement, node);
@@ -223,6 +265,12 @@
     return super.visitVariableDeclaration(node);
   }
 
+  @override
+  Object visitWhileStatement(WhileStatement node) {
+    _checkForPossibleNullCondition(node.condition);
+    return super.visitWhileStatement(node);
+  }
+
   /**
    * Check for the passed is expression for the unnecessary type check hint codes as well as null
    * checks expressed using an is expression.
@@ -415,6 +463,29 @@
   }
 
   /**
+   * Produce a hint if the given [target] could have a value of `null`.
+   */
+  void _checkForCanBeNullAfterNullAware(Expression target, Token operator) {
+    if (operator?.type == TokenType.QUESTION_PERIOD) {
+      return;
+    }
+    while (target is ParenthesizedExpression) {
+      target = (target as ParenthesizedExpression).expression;
+    }
+    if (target is MethodInvocation) {
+      if (target.operator?.type == TokenType.QUESTION_PERIOD) {
+        _errorReporter.reportErrorForNode(
+            HintCode.CAN_BE_NULL_AFTER_NULL_AWARE, target);
+      }
+    } else if (target is PropertyAccess) {
+      if (target.operator.type == TokenType.QUESTION_PERIOD) {
+        _errorReporter.reportErrorForNode(
+            HintCode.CAN_BE_NULL_AFTER_NULL_AWARE, target);
+      }
+    }
+  }
+
+  /**
    * Given some [Element], look at the associated metadata and report the use of the member if
    * it is declared as deprecated.
    *
@@ -619,6 +690,67 @@
   }
 
   /**
+   * Produce a hint if the given [condition] could have a value of `null`.
+   */
+  void _checkForPossibleNullCondition(Expression condition) {
+    while (condition is ParenthesizedExpression) {
+      condition = (condition as ParenthesizedExpression).expression;
+    }
+    if (condition is BinaryExpression) {
+      _checkForPossibleNullConditionInBinaryExpression(condition);
+    } else if (condition is PrefixExpression) {
+      _checkForPossibleNullConditionInPrefixExpression(condition);
+    } else {
+      _checkForPossibleNullConditionInSimpleExpression(condition);
+    }
+  }
+
+  /**
+   * Produce a hint if any of the parts of the given binary [condition] could
+   * have a value of `null`.
+   */
+  void _checkForPossibleNullConditionInBinaryExpression(
+      BinaryExpression condition) {
+    Token operator = condition.operator;
+    if (operator != null &&
+        (operator.type == TokenType.AMPERSAND_AMPERSAND ||
+            operator.type == TokenType.BAR_BAR)) {
+      _checkForPossibleNullCondition(condition.leftOperand);
+      _checkForPossibleNullCondition(condition.rightOperand);
+    }
+  }
+
+  /**
+   * Produce a hint if the operand of the given prefix [condition] could
+   * have a value of `null`.
+   */
+  void _checkForPossibleNullConditionInPrefixExpression(
+      PrefixExpression condition) {
+    if (condition.operator?.type == TokenType.BANG) {
+      _checkForPossibleNullCondition(condition.operand);
+    }
+  }
+
+  /**
+   * Produce a hint if the given [condition] could have a value of `null`.
+   */
+  void _checkForPossibleNullConditionInSimpleExpression(Expression condition) {
+    if (condition is MethodInvocation) {
+      Token operator = condition.operator;
+      if (operator != null && operator.type == TokenType.QUESTION_PERIOD) {
+        _errorReporter.reportErrorForNode(
+            HintCode.NULL_AWARE_IN_CONDITION, condition);
+      }
+    } else if (condition is PropertyAccess) {
+      Token operator = condition.operator;
+      if (operator != null && operator.type == TokenType.QUESTION_PERIOD) {
+        _errorReporter.reportErrorForNode(
+            HintCode.NULL_AWARE_IN_CONDITION, condition);
+      }
+    }
+  }
+
+  /**
    * Check for the passed class declaration for the
    * [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE] hint code.
    *
@@ -2421,11 +2553,12 @@
   bool _isValidMixin = false;
 
   /**
-   * A collection holding the function types defined in a class that need to have their type
-   * arguments set to the types of the type parameters for the class, or `null` if we are not
-   * currently processing nodes within a class.
+   * A collection holding the elements defined in a class that need to have
+   * their function type fixed to take into account type parameters of the
+   * enclosing class, or `null` if we are not currently processing nodes within
+   * a class.
    */
-  List<FunctionTypeImpl> _functionTypesToFix = null;
+  List<ExecutableElementImpl> _functionTypesToFix = null;
 
   /**
    * A table mapping field names to field elements for the fields defined in the current class, or
@@ -2482,7 +2615,7 @@
   Object visitClassDeclaration(ClassDeclaration node) {
     ElementHolder holder = new ElementHolder();
     _isValidMixin = true;
-    _functionTypesToFix = new List<FunctionTypeImpl>();
+    _functionTypesToFix = new List<ExecutableElementImpl>();
     //
     // Process field declarations before constructors and methods so that field
     // formal parameters can be correctly resolved to their fields.
@@ -2508,24 +2641,22 @@
     InterfaceTypeImpl interfaceType = new InterfaceTypeImpl(element);
     interfaceType.typeArguments = typeArguments;
     element.type = interfaceType;
-    List<ConstructorElement> constructors = holder.constructors;
-    if (constructors.length == 0) {
-      //
-      // Create the default constructor.
-      //
-      constructors = _createDefaultConstructors(interfaceType);
-    }
+    element.typeParameters = typeParameters;
     _setDocRange(element, node);
     element.abstract = node.isAbstract;
     element.accessors = holder.accessors;
+    List<ConstructorElement> constructors = holder.constructors;
+    if (constructors.isEmpty) {
+      constructors = _createDefaultConstructors(element);
+    }
     element.constructors = constructors;
     element.fields = holder.fields;
     element.methods = holder.methods;
-    element.typeParameters = typeParameters;
     element.validMixin = _isValidMixin;
-    int functionTypeCount = _functionTypesToFix.length;
-    for (int i = 0; i < functionTypeCount; i++) {
-      _functionTypesToFix[i].typeArguments = typeArguments;
+    // Function types must be initialized after the enclosing element has been
+    // set, for them to pick up the type parameters.
+    for (ExecutableElementImpl e in _functionTypesToFix) {
+      e.type = new FunctionTypeImpl(e);
     }
     _functionTypesToFix = null;
     _currentHolder.addType(element);
@@ -2551,7 +2682,6 @@
   @override
   Object visitClassTypeAlias(ClassTypeAlias node) {
     ElementHolder holder = new ElementHolder();
-    _functionTypesToFix = new List<FunctionTypeImpl>();
     _visitChildren(holder, node);
     SimpleIdentifier className = node.name;
     ClassElementImpl element = new ClassElementImpl.forNode(className);
@@ -2563,11 +2693,6 @@
     InterfaceTypeImpl interfaceType = new InterfaceTypeImpl(element);
     interfaceType.typeArguments = typeArguments;
     element.type = interfaceType;
-    // set default constructor
-    for (FunctionTypeImpl functionType in _functionTypesToFix) {
-      functionType.typeArguments = typeArguments;
-    }
-    _functionTypesToFix = null;
     _currentHolder.addType(element);
     className.staticElement = element;
     holder.validate();
@@ -2906,11 +3031,15 @@
         element.setVisibleRange(functionEnd, blockEnd - functionEnd - 1);
       }
     }
-    FunctionTypeImpl type = new FunctionTypeImpl(element);
     if (_functionTypesToFix != null) {
-      _functionTypesToFix.add(type);
+      _functionTypesToFix.add(element);
+    } else {
+      // TODO(jmesserly): for local functions inside of top-level generic
+      // functions, this is probably not right. The function type should be set
+      // after the enclosingElement is set, otherwise we won't be able to
+      // substitute those type parameters later.
+      element.type = new FunctionTypeImpl(element);
     }
-    element.type = type;
     element.hasImplicitReturnType = true;
     _currentHolder.addFunction(element);
     node.element = element;
@@ -2930,9 +3059,8 @@
     _setDocRange(element, node);
     element.parameters = parameters;
     element.typeParameters = typeParameters;
-    FunctionTypeImpl type = new FunctionTypeImpl.forTypedef(element);
-    type.typeArguments = _createTypeParameterTypes(typeParameters);
-    element.type = type;
+    _createTypeParameterTypes(typeParameters);
+    element.type = new FunctionTypeImpl.forTypedef(element);
     _currentHolder.addTypeAlias(element);
     aliasName.staticElement = element;
     holder.validate();
@@ -3314,14 +3442,13 @@
    * @return the [ConstructorElement]s array with the single default constructor element
    */
   List<ConstructorElement> _createDefaultConstructors(
-      InterfaceTypeImpl interfaceType) {
+      ClassElementImpl definingClass) {
     ConstructorElementImpl constructor =
         new ConstructorElementImpl.forNode(null);
     constructor.synthetic = true;
-    constructor.returnType = interfaceType;
-    FunctionTypeImpl type = new FunctionTypeImpl(constructor);
-    _functionTypesToFix.add(type);
-    constructor.type = type;
+    constructor.returnType = definingClass.type;
+    constructor.enclosingElement = definingClass;
+    constructor.type = new FunctionTypeImpl(constructor);
     return <ConstructorElement>[constructor];
   }
 
@@ -4824,7 +4951,7 @@
     _usedImportedElementsVisitor =
         new GatherUsedImportedElementsVisitor(_library);
     _enableDart2JSHints = _context.analysisOptions.dart2jsHint;
-    _manager = new InheritanceManager(_compilationUnits[0].element.library);
+    _manager = new InheritanceManager(_library);
     _usedLocalElementsVisitor = new GatherUsedLocalElementsVisitor(_library);
   }
 
@@ -5753,28 +5880,6 @@
   }
 
   /**
-   * Given some [InterfaceType] and some member name, this returns the
-   * [FunctionType] of the [ExecutableElement] that the
-   * class either declares itself, or inherits, that has the member name, if no member is inherited
-   * `null` is returned. The returned [FunctionType] has all type
-   * parameters substituted with corresponding type arguments from the given [InterfaceType].
-   *
-   * @param interfaceType the interface type to query
-   * @param memberName the name of the executable element to find and return
-   * @return the member's function type, or `null` if no such member exists
-   */
-  FunctionType lookupMemberType(
-      InterfaceType interfaceType, String memberName) {
-    ExecutableElement iteratorMember =
-        lookupMember(interfaceType.element, memberName);
-    if (iteratorMember == null) {
-      return null;
-    }
-    return substituteTypeArgumentsInMemberFromInheritance(
-        iteratorMember.type, memberName, interfaceType);
-  }
-
-  /**
    * Determine the set of methods which is overridden by the given class member. If no member is
    * inherited, an empty list is returned. If one of the inherited members is a
    * [MultiplyInheritedExecutableElement], then it is expanded into its constituent inherited
@@ -5822,6 +5927,9 @@
    * @param definingType the type that is overriding the member
    * @return the passed function type with any parameterized types substituted
    */
+  // TODO(jmesserly): investigate why this is needed in ErrorVerifier's override
+  // checking. There seems to be some rare cases where we get partially
+  // substituted type arguments, and the function types don't compare equally.
   FunctionType substituteTypeArgumentsInMemberFromInheritance(
       FunctionType baseFunctionType,
       String memberName,
@@ -9631,13 +9739,6 @@
   final List<VariableElement> variablesAndFields = <VariableElement>[];
 
   /**
-   * A flag indicating whether we should discard errors while resolving the
-   * initializer for variable declarations. We do this for top-level variables
-   * and fields because their initializer will be re-resolved at a later time.
-   */
-  bool discardErrorsInInitializer = false;
-
-  /**
    * Initialize a newly created visitor to resolve the nodes in an AST node.
    *
    * The [definingLibrary] is the element for the library containing the node
@@ -9660,8 +9761,7 @@
       InheritanceManager inheritanceManager,
       StaticTypeAnalyzerFactory typeAnalyzerFactory})
       : strongMode = definingLibrary.context.analysisOptions.strongMode,
-        super(definingLibrary, source, typeProvider,
-            new DisablableErrorListener(errorListener));
+        super(definingLibrary, source, typeProvider, errorListener);
 
   @override
   Object visitBlockFunctionBody(BlockFunctionBody node) {
@@ -9683,26 +9783,12 @@
   Object visitFieldDeclaration(FieldDeclaration node) {
     if (strongMode && node.isStatic) {
       _addVariables(node.fields.variables);
-      bool wasDiscarding = discardErrorsInInitializer;
-      discardErrorsInInitializer = true;
-      try {
-        return super.visitFieldDeclaration(node);
-      } finally {
-        discardErrorsInInitializer = wasDiscarding;
-      }
     }
     return super.visitFieldDeclaration(node);
   }
 
   @override
   Object visitNode(AstNode node) {
-    if (discardErrorsInInitializer) {
-      AstNode parent = node.parent;
-      if (parent is VariableDeclaration && parent.initializer == node) {
-        DisablableErrorListener listener = errorListener;
-        return listener.disableWhile(() => super.visitNode(node));
-      }
-    }
     return super.visitNode(node);
   }
 
@@ -9710,13 +9796,6 @@
   Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
     if (strongMode) {
       _addVariables(node.variables.variables);
-      bool wasDiscarding = discardErrorsInInitializer;
-      discardErrorsInInitializer = true;
-      try {
-        return super.visitTopLevelVariableDeclaration(node);
-      } finally {
-        discardErrorsInInitializer = wasDiscarding;
-      }
     }
     return super.visitTopLevelVariableDeclaration(node);
   }
@@ -11493,8 +11572,8 @@
     DartType expressionType = iteratorExpression.bestType;
     if (expressionType is InterfaceType) {
       InterfaceType interfaceType = expressionType;
-      FunctionType iteratorFunction =
-          _inheritanceManager.lookupMemberType(interfaceType, "iterator");
+      PropertyAccessorElement iteratorFunction =
+          interfaceType.lookUpInheritedGetter("iterator");
       if (iteratorFunction == null) {
         // TODO(brianwilkerson) Should we report this error?
         return null;
@@ -11502,8 +11581,8 @@
       DartType iteratorType = iteratorFunction.returnType;
       if (iteratorType is InterfaceType) {
         InterfaceType iteratorInterfaceType = iteratorType;
-        FunctionType currentFunction = _inheritanceManager.lookupMemberType(
-            iteratorInterfaceType, "current");
+        PropertyAccessorElement currentFunction =
+            iteratorInterfaceType.lookUpInheritedGetter("current");
         if (currentFunction == null) {
           // TODO(brianwilkerson) Should we report this error?
           return null;
@@ -11516,16 +11595,15 @@
 
   /**
    * The given expression is the expression used to compute the stream for an
-   * asyncronous for-each statement. Attempt to compute the type of objects that
-   * will be assigned to the loop variable and return that type. Return `null`
-   * if the type could not be determined. The [streamExpression] is the
-   * expression that will return the stream being iterated over.
+   * asynchronous for-each statement. Attempt to compute the type of objects
+   * that will be assigned to the loop variable and return that type.
+   * Return `null` if the type could not be determined. The [streamExpression]
+   * is the expression that will return the stream being iterated over.
    */
   DartType _getStreamElementType(Expression streamExpression) {
     DartType streamType = streamExpression.bestType;
     if (streamType is InterfaceType) {
-      FunctionType listenFunction =
-          _inheritanceManager.lookupMemberType(streamType, "listen");
+      MethodElement listenFunction = streamType.lookUpInheritedMethod("listen");
       if (listenFunction == null) {
         return null;
       }
@@ -11536,17 +11614,10 @@
       DartType onDataType = listenParameters[0].type;
       if (onDataType is FunctionType) {
         List<ParameterElement> onDataParameters = onDataType.parameters;
-        if (onDataParameters == null || onDataParameters.length < 1) {
+        if (onDataParameters == null || onDataParameters.isEmpty) {
           return null;
         }
-        DartType eventType = onDataParameters[0].type;
-        // TODO(paulberry): checking that typeParameters.isNotEmpty is a
-        // band-aid fix for dartbug.com/24191.  Figure out what the correct
-        // logic should be.
-        if (streamType.typeParameters.isNotEmpty &&
-            eventType.element == streamType.typeParameters[0]) {
-          return streamType.typeArguments[0];
-        }
+        return onDataParameters[0].type;
       }
     }
     return null;
@@ -12728,310 +12799,6 @@
 }
 
 /**
- * Implementation of [TypeSystem] using the strong mode rules.
- * https://github.com/dart-lang/dev_compiler/blob/master/STRONG_MODE.md
- */
-class StrongTypeSystemImpl implements TypeSystem {
-  final _specTypeSystem = new TypeSystemImpl();
-
-  StrongTypeSystemImpl();
-
-  @override
-  DartType getLeastUpperBound(
-      TypeProvider typeProvider, DartType type1, DartType type2) {
-    // TODO(leafp): Implement a strong mode version of this.
-    return _specTypeSystem.getLeastUpperBound(typeProvider, type1, type2);
-  }
-
-  // TODO(leafp): Document the rules in play here
-  @override
-  bool isAssignableTo(DartType fromType, DartType toType) {
-    // An actual subtype
-    if (isSubtypeOf(fromType, toType)) {
-      return true;
-    }
-
-    // Don't allow implicit downcasts between function types
-    // and call method objects, as these will almost always fail.
-    if ((fromType is FunctionType && _getCallMethodType(toType) != null) ||
-        (toType is FunctionType && _getCallMethodType(fromType) != null)) {
-      return false;
-    }
-
-    // If the subtype relation goes the other way, allow the implicit downcast.
-    // TODO(leafp): Emit warnings and hints for these in some way.
-    // TODO(leafp): Consider adding a flag to disable these?  Or just rely on
-    //   --warnings-as-errors?
-    if (isSubtypeOf(toType, fromType) ||
-        _specTypeSystem.isAssignableTo(toType, fromType)) {
-      // TODO(leafp): error if type is known to be exact (literal,
-      //  instance creation).
-      // TODO(leafp): Warn on composite downcast.
-      // TODO(leafp): hint on object/dynamic downcast.
-      // TODO(leafp): Consider allowing assignment casts.
-      return true;
-    }
-
-    return false;
-  }
-
-  @override
-  bool isSubtypeOf(DartType leftType, DartType rightType) {
-    return _isSubtypeOf(leftType, rightType, null);
-  }
-
-  FunctionType _getCallMethodType(DartType t) {
-    if (t is InterfaceType) {
-      ClassElement element = t.element;
-      InheritanceManager manager = new InheritanceManager(element.library);
-      FunctionType callType = manager.lookupMemberType(t, "call");
-      return callType;
-    }
-    return null;
-  }
-
-  // Given a type t, if t is an interface type with a call method
-  // defined, return the function type for the call method, otherwise
-  // return null.
-  _GuardedSubtypeChecker<DartType> _guard(
-      _GuardedSubtypeChecker<DartType> check) {
-    return (DartType t1, DartType t2, Set<Element> visited) {
-      Element element = t1.element;
-      if (visited == null) {
-        visited = new HashSet<Element>();
-      }
-      if (element == null || !visited.add(element)) {
-        return false;
-      }
-      try {
-        return check(t1, t2, visited);
-      } finally {
-        visited.remove(element);
-      }
-    };
-  }
-
-  bool _isBottom(DartType t, {bool dynamicIsBottom: false}) {
-    return (t.isDynamic && dynamicIsBottom) || t.isBottom;
-  }
-
-  // Guard against loops in the class hierarchy
-  /**
-   * Check that [f1] is a subtype of [f2].
-   * [fuzzyArrows] indicates whether or not the f1 and f2 should be
-   * treated as fuzzy arrow types (and hence dynamic parameters to f2 treated
-   * as bottom).
-   */
-  bool _isFunctionSubtypeOf(FunctionType f1, FunctionType f2,
-      {bool fuzzyArrows: true}) {
-    final r1s = f1.normalParameterTypes;
-    final o1s = f1.optionalParameterTypes;
-    final n1s = f1.namedParameterTypes;
-    final r2s = f2.normalParameterTypes;
-    final o2s = f2.optionalParameterTypes;
-    final n2s = f2.namedParameterTypes;
-    final ret1 = f1.returnType;
-    final ret2 = f2.returnType;
-
-    // A -> B <: C -> D if C <: A and
-    // either D is void or B <: D
-    if (!ret2.isVoid && !isSubtypeOf(ret1, ret2)) {
-      return false;
-    }
-
-    // Reject if one has named and the other has optional
-    if (n1s.length > 0 && o2s.length > 0) {
-      return false;
-    }
-    if (n2s.length > 0 && o1s.length > 0) {
-      return false;
-    }
-
-    // Rebind _isSubtypeOf for convenience
-    _SubtypeChecker<DartType> parameterSubtype = (DartType t1, DartType t2) =>
-        _isSubtypeOf(t1, t2, null, dynamicIsBottom: fuzzyArrows);
-
-    // f2 has named parameters
-    if (n2s.length > 0) {
-      // Check that every named parameter in f2 has a match in f1
-      for (String k2 in n2s.keys) {
-        if (!n1s.containsKey(k2)) {
-          return false;
-        }
-        if (!parameterSubtype(n2s[k2], n1s[k2])) {
-          return false;
-        }
-      }
-    }
-    // If we get here, we either have no named parameters,
-    // or else the named parameters match and we have no optional
-    // parameters
-
-    // If f1 has more required parameters, reject
-    if (r1s.length > r2s.length) {
-      return false;
-    }
-
-    // If f2 has more required + optional parameters, reject
-    if (r2s.length + o2s.length > r1s.length + o1s.length) {
-      return false;
-    }
-
-    // The parameter lists must look like the following at this point
-    // where rrr is a region of required, and ooo is a region of optionals.
-    // f1: rrr ooo ooo ooo
-    // f2: rrr rrr ooo
-    int rr = r1s.length; // required in both
-    int or = r2s.length - r1s.length; // optional in f1, required in f2
-    int oo = o2s.length; // optional in both
-
-    for (int i = 0; i < rr; ++i) {
-      if (!parameterSubtype(r2s[i], r1s[i])) {
-        return false;
-      }
-    }
-    for (int i = 0, j = rr; i < or; ++i, ++j) {
-      if (!parameterSubtype(r2s[j], o1s[i])) {
-        return false;
-      }
-    }
-    for (int i = or, j = 0; i < oo; ++i, ++j) {
-      if (!parameterSubtype(o2s[j], o1s[i])) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  bool _isInterfaceSubtypeOf(
-      InterfaceType i1, InterfaceType i2, Set<Element> visited) {
-    // Guard recursive calls
-    _GuardedSubtypeChecker<InterfaceType> guardedInterfaceSubtype =
-        _guard(_isInterfaceSubtypeOf);
-
-    if (i1 == i2) {
-      return true;
-    }
-
-    if (i1.element == i2.element) {
-      List<DartType> tArgs1 = i1.typeArguments;
-      List<DartType> tArgs2 = i2.typeArguments;
-
-      assert(tArgs1.length == tArgs2.length);
-
-      for (int i = 0; i < tArgs1.length; i++) {
-        DartType t1 = tArgs1[i];
-        DartType t2 = tArgs2[i];
-        if (!isSubtypeOf(t1, t2)) {
-          return false;
-        }
-      }
-      return true;
-    }
-
-    if (i2.isDartCoreFunction && i1.element.getMethod("call") != null) {
-      return true;
-    }
-
-    if (i1.isObject) {
-      return false;
-    }
-
-    if (guardedInterfaceSubtype(i1.superclass, i2, visited)) {
-      return true;
-    }
-
-    for (final parent in i1.interfaces) {
-      if (guardedInterfaceSubtype(parent, i2, visited)) {
-        return true;
-      }
-    }
-
-    for (final parent in i1.mixins) {
-      if (guardedInterfaceSubtype(parent, i2, visited)) {
-        return true;
-      }
-    }
-
-    return false;
-  }
-
-  bool _isSubtypeOf(DartType t1, DartType t2, Set<Element> visited,
-      {bool dynamicIsBottom: false}) {
-    // Guard recursive calls
-    _GuardedSubtypeChecker<DartType> guardedSubtype = _guard(_isSubtypeOf);
-
-    if (t1 == t2) {
-      return true;
-    }
-
-    // The types are void, dynamic, bottom, interface types, function types
-    // and type parameters.  We proceed by eliminating these different classes
-    // from consideration.
-
-    // Trivially true.
-    if (_isTop(t2, dynamicIsBottom: dynamicIsBottom) ||
-        _isBottom(t1, dynamicIsBottom: dynamicIsBottom)) {
-      return true;
-    }
-
-    // Trivially false.
-    if (_isTop(t1, dynamicIsBottom: dynamicIsBottom) ||
-        _isBottom(t2, dynamicIsBottom: dynamicIsBottom)) {
-      return false;
-    }
-
-    // S <: T where S is a type variable
-    //  T is not dynamic or object (handled above)
-    //  S != T (handled above)
-    //  So only true if bound of S is S' and
-    //  S' <: T
-    if (t1 is TypeParameterType) {
-      DartType bound = t1.element.bound;
-      if (bound == null) return false;
-      return guardedSubtype(bound, t2, visited);
-    }
-
-    if (t2 is TypeParameterType) {
-      return false;
-    }
-
-    if (t1.isVoid || t2.isVoid) {
-      return false;
-    }
-
-    // We've eliminated void, dynamic, bottom, and type parameters.  The only
-    // cases are the combinations of interface type and function type.
-
-    // A function type can only subtype an interface type if
-    // the interface type is Function
-    if (t1 is FunctionType && t2 is InterfaceType) {
-      return t2.isDartCoreFunction;
-    }
-
-    // An interface type can only subtype a function type if
-    // the interface type declares a call method with a type
-    // which is a super type of the function type.
-    if (t1 is InterfaceType && t2 is FunctionType) {
-      var callType = _getCallMethodType(t1);
-      return (callType != null) && _isFunctionSubtypeOf(callType, t2);
-    }
-
-    // Two interface types
-    if (t1 is InterfaceType && t2 is InterfaceType) {
-      return _isInterfaceSubtypeOf(t1, t2, visited);
-    }
-
-    return _isFunctionSubtypeOf(t1 as FunctionType, t2 as FunctionType);
-  }
-
-  // TODO(leafp): Document the rules in play here
-  bool _isTop(DartType t, {bool dynamicIsBottom: false}) {
-    return (t.isDynamic && !dynamicIsBottom) || t.isObject;
-  }
-}
-
-/**
  * Instances of this class manage the knowledge of what the set of subtypes are for a given type.
  */
 class SubtypeManager {
@@ -14288,9 +14055,7 @@
     } else {
       ClassElement definingClass = element.enclosingElement as ClassElement;
       element.returnType = definingClass.type;
-      FunctionTypeImpl type = new FunctionTypeImpl(element);
-      type.typeArguments = definingClass.type.typeArguments;
-      element.type = type;
+      element.type = new FunctionTypeImpl(element);
     }
     return null;
   }
@@ -14358,13 +14123,7 @@
           new CaughtException(new AnalysisException(), null));
     }
     element.returnType = _computeReturnType(node.returnType);
-    FunctionTypeImpl type = new FunctionTypeImpl(element);
-    ClassElement definingClass =
-        element.getAncestor((element) => element is ClassElement);
-    if (definingClass != null) {
-      type.typeArguments = definingClass.type.typeArguments;
-    }
-    element.type = type;
+    element.type = new FunctionTypeImpl(element);
     return null;
   }
 
@@ -14412,21 +14171,15 @@
           new CaughtException(new AnalysisException(), null));
     }
     element.returnType = _computeReturnType(node.returnType);
-    FunctionTypeImpl type = new FunctionTypeImpl(element);
-    ClassElement definingClass =
-        element.getAncestor((element) => element is ClassElement);
-    if (definingClass != null) {
-      type.typeArguments = definingClass.type.typeArguments;
-    }
-    element.type = type;
+    element.type = new FunctionTypeImpl(element);
     if (element is PropertyAccessorElement) {
       PropertyAccessorElement accessor = element as PropertyAccessorElement;
       PropertyInducingElementImpl variable =
           accessor.variable as PropertyInducingElementImpl;
       if (accessor.isGetter) {
-        variable.type = type.baseReturnType;
+        variable.type = element.returnType;
       } else if (variable.type == null) {
-        List<ParameterElement> parameters = type.baseParameters;
+        List<ParameterElement> parameters = element.parameters;
         if (parameters != null && parameters.length > 0) {
           variable.type = parameters[0].type;
         }
@@ -14767,13 +14520,7 @@
         PropertyAccessorElementImpl getter =
             variableElement.getter as PropertyAccessorElementImpl;
         getter.returnType = declaredType;
-        FunctionTypeImpl getterType = new FunctionTypeImpl(getter);
-        ClassElement definingClass =
-            element.getAncestor((element) => element is ClassElement);
-        if (definingClass != null) {
-          getterType.typeArguments = definingClass.type.typeArguments;
-        }
-        getter.type = getterType;
+        getter.type = new FunctionTypeImpl(getter);
         PropertyAccessorElementImpl setter =
             variableElement.setter as PropertyAccessorElementImpl;
         if (setter != null) {
@@ -14782,11 +14529,7 @@
             (parameters[0] as ParameterElementImpl).type = declaredType;
           }
           setter.returnType = VoidTypeImpl.instance;
-          FunctionTypeImpl setterType = new FunctionTypeImpl(setter);
-          if (definingClass != null) {
-            setterType.typeArguments = definingClass.type.typeArguments;
-          }
-          setter.type = setterType;
+          setter.type = new FunctionTypeImpl(setter);
         }
       }
     } else {
@@ -15196,38 +14939,12 @@
   void _setFunctionTypedParameterType(ParameterElementImpl element,
       TypeName returnType, FormalParameterList parameterList) {
     List<ParameterElement> parameters = _getElements(parameterList);
-    FunctionTypeAliasElementImpl aliasElement =
-        new FunctionTypeAliasElementImpl.forNode(null);
-    aliasElement.synthetic = true;
-    aliasElement.shareParameters(parameters);
-    aliasElement.returnType = _computeReturnType(returnType);
-    // FunctionTypeAliasElementImpl assumes the enclosing element is a
-    // CompilationUnitElement (because non-synthetic function types can only be
-    // declared at top level), so to avoid breaking things, go find the
-    // compilation unit element.
-    aliasElement.enclosingElement =
-        element.getAncestor((element) => element is CompilationUnitElement);
-    FunctionTypeImpl type = new FunctionTypeImpl.forTypedef(aliasElement);
-    ClassElement definingClass =
-        element.getAncestor((element) => element is ClassElement);
-    if (definingClass != null) {
-      aliasElement.shareTypeParameters(definingClass.typeParameters);
-      type.typeArguments = definingClass.type.typeArguments;
-    } else {
-      FunctionTypeAliasElement alias =
-          element.getAncestor((element) => element is FunctionTypeAliasElement);
-      while (alias != null && alias.isSynthetic) {
-        alias =
-            alias.getAncestor((element) => element is FunctionTypeAliasElement);
-      }
-      if (alias != null) {
-        aliasElement.typeParameters = alias.typeParameters;
-        type.typeArguments = alias.type.typeArguments;
-      } else {
-        type.typeArguments = DartType.EMPTY_LIST;
-      }
-    }
-    element.type = type;
+    FunctionElementImpl functionElement = new FunctionElementImpl.forNode(null);
+    functionElement.synthetic = true;
+    functionElement.shareParameters(parameters);
+    functionElement.returnType = _computeReturnType(returnType);
+    functionElement.enclosingElement = element;
+    element.type = new FunctionTypeImpl(functionElement);
   }
 
   /**
@@ -15257,139 +14974,6 @@
 }
 
 /**
- * The interface `TypeSystem` defines the behavior of an object representing
- * the type system.  This provides a common location to put methods that act on
- * types but may need access to more global data structures, and it paves the
- * way for a possible future where we may wish to make the type system
- * pluggable.
- */
-abstract class TypeSystem {
-  /**
-   * Compute the least upper bound of two types.
-   */
-  DartType getLeastUpperBound(
-      TypeProvider typeProvider, DartType type1, DartType type2);
-
-  /**
-   * Return `true` if the [leftType] is assignable to the [rightType] (that is,
-   * if leftType <==> rightType).
-   */
-  bool isAssignableTo(DartType leftType, DartType rightType);
-
-  /**
-   * Return `true` if the [leftType] is a subtype of the [rightType] (that is,
-   * if leftType <: rightType).
-   */
-  bool isSubtypeOf(DartType leftType, DartType rightType);
-
-  /**
-   * Create either a strong mode or regular type system based on context.
-   */
-  static TypeSystem create(AnalysisContext context) {
-    return (context.analysisOptions.strongMode)
-        ? new StrongTypeSystemImpl()
-        : new TypeSystemImpl();
-  }
-}
-
-/**
- * Implementation of [TypeSystem] using the rules in the Dart specification.
- */
-class TypeSystemImpl implements TypeSystem {
-  TypeSystemImpl();
-
-  @override
-  DartType getLeastUpperBound(
-      TypeProvider typeProvider, DartType type1, DartType type2) {
-    // The least upper bound relation is reflexive.
-    if (identical(type1, type2)) {
-      return type1;
-    }
-    // The least upper bound of dynamic and any type T is dynamic.
-    if (type1.isDynamic) {
-      return type1;
-    }
-    if (type2.isDynamic) {
-      return type2;
-    }
-    // The least upper bound of void and any type T != dynamic is void.
-    if (type1.isVoid) {
-      return type1;
-    }
-    if (type2.isVoid) {
-      return type2;
-    }
-    // The least upper bound of bottom and any type T is T.
-    if (type1.isBottom) {
-      return type2;
-    }
-    if (type2.isBottom) {
-      return type1;
-    }
-    // Let U be a type variable with upper bound B.  The least upper bound of U
-    // and a type T is the least upper bound of B and T.
-    while (type1 is TypeParameterType) {
-      // TODO(paulberry): is this correct in the complex of F-bounded
-      // polymorphism?
-      DartType bound = (type1 as TypeParameterType).element.bound;
-      if (bound == null) {
-        bound = typeProvider.objectType;
-      }
-      type1 = bound;
-    }
-    while (type2 is TypeParameterType) {
-      // TODO(paulberry): is this correct in the context of F-bounded
-      // polymorphism?
-      DartType bound = (type2 as TypeParameterType).element.bound;
-      if (bound == null) {
-        bound = typeProvider.objectType;
-      }
-      type2 = bound;
-    }
-    // The least upper bound of a function type and an interface type T is the
-    // least upper bound of Function and T.
-    if (type1 is FunctionType && type2 is InterfaceType) {
-      type1 = typeProvider.functionType;
-    }
-    if (type2 is FunctionType && type1 is InterfaceType) {
-      type2 = typeProvider.functionType;
-    }
-
-    // At this point type1 and type2 should both either be interface types or
-    // function types.
-    if (type1 is InterfaceType && type2 is InterfaceType) {
-      InterfaceType result =
-          InterfaceTypeImpl.computeLeastUpperBound(type1, type2);
-      if (result == null) {
-        return typeProvider.dynamicType;
-      }
-      return result;
-    } else if (type1 is FunctionType && type2 is FunctionType) {
-      FunctionType result =
-          FunctionTypeImpl.computeLeastUpperBound(type1, type2);
-      if (result == null) {
-        return typeProvider.functionType;
-      }
-      return result;
-    } else {
-      // Should never happen.  As a defensive measure, return the dynamic type.
-      assert(false);
-      return typeProvider.dynamicType;
-    }
-  }
-
-  @override
-  bool isAssignableTo(DartType leftType, DartType rightType) {
-    return leftType.isAssignableTo(rightType);
-  }
-
-  @override
-  bool isSubtypeOf(DartType leftType, DartType rightType) {
-    return leftType.isSubtypeOf(rightType);
-  }
-}
-
-/**
  * Instances of the class [UnusedLocalElementsVerifier] traverse an element
  * structure looking for cases of [HintCode.UNUSED_ELEMENT],
  * [HintCode.UNUSED_FIELD], [HintCode.UNUSED_LOCAL_VARIABLE], etc.
diff --git a/pkg/analyzer/lib/src/generated/scanner.dart b/pkg/analyzer/lib/src/generated/scanner.dart
index 0a9fa2a..a99997a 100644
--- a/pkg/analyzer/lib/src/generated/scanner.dart
+++ b/pkg/analyzer/lib/src/generated/scanner.dart
@@ -246,6 +246,7 @@
   CommentToken copy() => new CommentToken(type, _value, offset);
 }
 
+
 /**
  * A documentation comment token.
  */
@@ -723,6 +724,12 @@
   bool _hasUnmatchedGroups = false;
 
   /**
+   * A flag indicating whether to parse generic method comments, of the form
+   * `/*=T*/` and `/*<T>*/`.
+   */
+  bool scanGenericMethodComments = false;
+
+  /**
    * Initialize a newly created scanner to scan characters from the given
    * [source]. The given character [_reader] will be used to read the characters
    * in the source. The given [_errorListener] will be informed of any errors
@@ -1012,16 +1019,20 @@
   }
 
   void _appendCommentToken(TokenType type, String value) {
-    // Ignore comment tokens if client specified that it doesn't need them.
-    if (!_preserveComments) {
+    CommentToken token = null;
+    TokenType genericComment = _matchGenericMethodCommentType(value);
+    if (genericComment != null) {
+      token = new CommentToken(genericComment, value, _tokenStart);
+    } else if (!_preserveComments) {
+      // Ignore comment tokens if client specified that it doesn't need them.
       return;
-    }
-    // OK, remember comment tokens.
-    CommentToken token;
-    if (_isDocumentationComment(value)) {
-      token = new DocumentationCommentToken(type, value, _tokenStart);
     } else {
-      token = new CommentToken(type, value, _tokenStart);
+      // OK, remember comment tokens.
+      if (_isDocumentationComment(value)) {
+        token = new DocumentationCommentToken(type, value, _tokenStart);
+      } else {
+        token = new CommentToken(type, value, _tokenStart);
+      }
     }
     if (_firstComment == null) {
       _firstComment = token;
@@ -1152,6 +1163,27 @@
   }
 
   /**
+   * Checks if [value] is the start of a generic method type annotation comment.
+   *
+   * This can either be of the form `/*<T>*/` or `/*=T*/`. The token type is
+   * returned, or null if it was not a generic method comment.
+   */
+  TokenType _matchGenericMethodCommentType(String value) {
+    if (scanGenericMethodComments) {
+      // Match /*< and >*/
+      if (StringUtilities.startsWith3(value, 0, 0x2F, 0x2A, 0x3C) &&
+          StringUtilities.endsWith3(value, 0x3E, 0x2A, 0x2F)) {
+        return TokenType.GENERIC_METHOD_TYPE_LIST;
+      }
+      // Match /*=
+      if (StringUtilities.startsWith3(value, 0, 0x2F, 0x2A, 0x3D)) {
+        return TokenType.GENERIC_METHOD_TYPE_ASSIGN;
+      }
+    }
+    return null;
+  }
+
+  /**
    * Report an error at the current offset. The [errorCode] is the error code
    * indicating the nature of the error. The [arguments] are any arguments
    * needed to complete the error message
@@ -2057,9 +2089,9 @@
    * comments can be reached by following the token stream using [next] until
    * `null` is returned.
    *
-   * For example, if the original contents were "/* one */ /* two */ id", then
-   * the first preceding comment token will have a lexeme of "/* one */" and
-   * the next comment token will have a lexeme of "/* two */".
+   * For example, if the original contents were `/* one */ /* two */ id`, then
+   * the first preceding comment token will have a lexeme of `/* one */` and
+   * the next comment token will have a lexeme of `/* two */`.
    */
   CommentToken get precedingComments => null;
 
@@ -2501,6 +2533,12 @@
   static const TokenType PERIOD_PERIOD_PERIOD =
       const TokenType('PERIOD_PERIOD_PERIOD', TokenClass.NO_CLASS, "...");
 
+  static const TokenType GENERIC_METHOD_TYPE_LIST =
+      const TokenType('GENERIC_METHOD_TYPE_LIST');
+
+  static const TokenType GENERIC_METHOD_TYPE_ASSIGN =
+      const TokenType('GENERIC_METHOD_TYPE_ASSIGN');
+
   /**
    * The class of the token.
    */
diff --git a/pkg/analyzer/lib/src/generated/source.dart b/pkg/analyzer/lib/src/generated/source.dart
index 1a47516..24fec62 100644
--- a/pkg/analyzer/lib/src/generated/source.dart
+++ b/pkg/analyzer/lib/src/generated/source.dart
@@ -208,6 +208,17 @@
     }
   }
 
+//  /**
+//   * Return the offset of the first character on the line with the given
+//   * [lineNumber].
+//   */
+//  int getLineOffset(int lineNumber) {
+//    if (lineNumber < 0 || lineNumber >= _lineStarts.length) {
+//      throw new ArgumentError('Invalid line number: $lineNumber');
+//    }
+//    return _lineStarts[lineNumber];
+//  }
+
   /**
    * Return the location information for the character at the given offset.
    *
@@ -743,7 +754,7 @@
     } catch (exception, stackTrace) {
       String containingFullName =
           containingSource != null ? containingSource.fullName : '<null>';
-      AnalysisEngine.instance.logger.logError(
+      AnalysisEngine.instance.logger.logInformation(
           "Could not resolve URI ($containedUri) relative to source ($containingFullName)",
           new CaughtException(exception, stackTrace));
       return null;
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 3f8c0ef..4343549 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -1036,7 +1036,6 @@
     if (propagatedElement is MethodElement) {
       propagatedType = propagatedElement.type;
     } else if (propagatedElement is PropertyAccessorElement) {
-      Expression realTarget = node.realTarget;
       propagatedType = _getTypeOfProperty(propagatedElement);
     } else {
       // TODO(brianwilkerson) Report this internal error.
diff --git a/pkg/analyzer/lib/src/generated/testing/element_factory.dart b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
index 736fa0d..dff33e9 100644
--- a/pkg/analyzer/lib/src/generated/testing/element_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
@@ -42,6 +42,7 @@
       String typeName, InterfaceType superclassType,
       [List<String> parameterNames]) {
     ClassElementImpl element = new ClassElementImpl(typeName, 0);
+    element.constructors = const <ConstructorElement>[];
     element.supertype = superclassType;
     InterfaceTypeImpl type = new InterfaceTypeImpl(element);
     element.type = type;
@@ -120,8 +121,8 @@
       constructor.parameters = <ParameterElement>[];
     }
     constructor.returnType = type;
-    FunctionTypeImpl constructorType = new FunctionTypeImpl(constructor);
-    constructor.type = constructorType;
+    constructor.enclosingElement = definingClass;
+    constructor.type = new FunctionTypeImpl(constructor);
     return constructor;
   }
 
@@ -476,16 +477,15 @@
   }
 
   static MethodElementImpl methodElementWithParameters(
+      ClassElement enclosingElement,
       String methodName,
-      List<DartType> typeArguments,
       DartType returnType,
       List<ParameterElement> parameters) {
     MethodElementImpl method = new MethodElementImpl(methodName, 0);
+    method.enclosingElement = enclosingElement;
     method.parameters = parameters;
     method.returnType = returnType;
-    FunctionTypeImpl methodType = new FunctionTypeImpl(method);
-    methodType.typeArguments = typeArguments;
-    method.type = methodType;
+    method.type = new FunctionTypeImpl(method);
     return method;
   }
 
@@ -578,7 +578,8 @@
     }
     variable.const3 = isConst;
     variable.final2 = isFinal;
-    variable.synthetic = true;
+    variable.synthetic = false;
+    variable.type = type;
     PropertyAccessorElementImpl getter =
         new PropertyAccessorElementImpl.forVariable(variable);
     getter.getter = true;
diff --git a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
index 5b5204a..a183a6f 100644
--- a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
+++ b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
@@ -598,19 +598,15 @@
    * defined for the class.
    */
   void _propagateTypeArguments(ClassElementImpl classElement) {
-    List<DartType> typeArguments =
-        TypeParameterTypeImpl.getTypes(classElement.typeParameters);
     for (PropertyAccessorElement accessor in classElement.accessors) {
-      FunctionTypeImpl functionType = accessor.type as FunctionTypeImpl;
-      functionType.typeArguments = typeArguments;
+      (accessor as ExecutableElementImpl).type = new FunctionTypeImpl(accessor);
     }
     for (MethodElement method in classElement.methods) {
-      FunctionTypeImpl functionType = method.type as FunctionTypeImpl;
-      functionType.typeArguments = typeArguments;
+      (method as ExecutableElementImpl).type = new FunctionTypeImpl(method);
     }
     for (ConstructorElement constructor in classElement.constructors) {
-      FunctionTypeImpl functionType = constructor.type as FunctionTypeImpl;
-      functionType.typeArguments = typeArguments;
+      (constructor as ExecutableElementImpl).type =
+          new FunctionTypeImpl(constructor);
     }
   }
 
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
new file mode 100644
index 0000000..ef6bbfb
--- /dev/null
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -0,0 +1,451 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.src.generated.type_system;
+
+import 'dart:collection';
+
+import 'element.dart';
+import 'engine.dart' show AnalysisContext;
+import 'resolver.dart' show TypeProvider;
+
+typedef bool _GuardedSubtypeChecker<T>(T t1, T t2, Set<Element> visited);
+
+typedef bool _SubtypeChecker<T>(T t1, T t2);
+
+
+/**
+ * Implementation of [TypeSystem] using the strong mode rules.
+ * https://github.com/dart-lang/dev_compiler/blob/master/STRONG_MODE.md
+ */
+class StrongTypeSystemImpl implements TypeSystem {
+  final _specTypeSystem = new TypeSystemImpl();
+
+  StrongTypeSystemImpl();
+
+  @override
+  DartType getLeastUpperBound(
+      TypeProvider typeProvider, DartType type1, DartType type2) {
+    // TODO(leafp): Implement a strong mode version of this.
+    return _specTypeSystem.getLeastUpperBound(typeProvider, type1, type2);
+  }
+
+  // TODO(leafp): Document the rules in play here
+  @override
+  bool isAssignableTo(DartType fromType, DartType toType) {
+    // An actual subtype
+    if (isSubtypeOf(fromType, toType)) {
+      return true;
+    }
+
+    // Don't allow implicit downcasts between function types
+    // and call method objects, as these will almost always fail.
+    if ((fromType is FunctionType && _getCallMethodType(toType) != null) ||
+        (toType is FunctionType && _getCallMethodType(fromType) != null)) {
+      return false;
+    }
+
+    // If the subtype relation goes the other way, allow the implicit downcast.
+    // TODO(leafp): Emit warnings and hints for these in some way.
+    // TODO(leafp): Consider adding a flag to disable these?  Or just rely on
+    //   --warnings-as-errors?
+    if (isSubtypeOf(toType, fromType) ||
+        _specTypeSystem.isAssignableTo(toType, fromType)) {
+      // TODO(leafp): error if type is known to be exact (literal,
+      //  instance creation).
+      // TODO(leafp): Warn on composite downcast.
+      // TODO(leafp): hint on object/dynamic downcast.
+      // TODO(leafp): Consider allowing assignment casts.
+      return true;
+    }
+
+    return false;
+  }
+
+  @override
+  bool isSubtypeOf(DartType leftType, DartType rightType) {
+    return _isSubtypeOf(leftType, rightType, null);
+  }
+
+  FunctionType _getCallMethodType(DartType t) {
+    if (t is InterfaceType) {
+      return t.lookUpInheritedMethod("call")?.type;
+    }
+    return null;
+  }
+
+  // Given a type t, if t is an interface type with a call method
+  // defined, return the function type for the call method, otherwise
+  // return null.
+  _GuardedSubtypeChecker<DartType> _guard(
+      _GuardedSubtypeChecker<DartType> check) {
+    return (DartType t1, DartType t2, Set<Element> visited) {
+      Element element = t1.element;
+      if (visited == null) {
+        visited = new HashSet<Element>();
+      }
+      if (element == null || !visited.add(element)) {
+        return false;
+      }
+      try {
+        return check(t1, t2, visited);
+      } finally {
+        visited.remove(element);
+      }
+    };
+  }
+
+  bool _isBottom(DartType t, {bool dynamicIsBottom: false}) {
+    return (t.isDynamic && dynamicIsBottom) || t.isBottom;
+  }
+
+  // Guard against loops in the class hierarchy
+  /**
+   * Check that [f1] is a subtype of [f2].
+   * [fuzzyArrows] indicates whether or not the f1 and f2 should be
+   * treated as fuzzy arrow types (and hence dynamic parameters to f2 treated
+   * as bottom).
+   */
+  bool _isFunctionSubtypeOf(FunctionType f1, FunctionType f2,
+      {bool fuzzyArrows: true}) {
+    final r1s = f1.normalParameterTypes;
+    final o1s = f1.optionalParameterTypes;
+    final n1s = f1.namedParameterTypes;
+    final r2s = f2.normalParameterTypes;
+    final o2s = f2.optionalParameterTypes;
+    final n2s = f2.namedParameterTypes;
+    final ret1 = f1.returnType;
+    final ret2 = f2.returnType;
+
+    // A -> B <: C -> D if C <: A and
+    // either D is void or B <: D
+    if (!ret2.isVoid && !isSubtypeOf(ret1, ret2)) {
+      return false;
+    }
+
+    // Reject if one has named and the other has optional
+    if (n1s.length > 0 && o2s.length > 0) {
+      return false;
+    }
+    if (n2s.length > 0 && o1s.length > 0) {
+      return false;
+    }
+
+    // Rebind _isSubtypeOf for convenience
+    _SubtypeChecker<DartType> parameterSubtype = (DartType t1, DartType t2) =>
+        _isSubtypeOf(t1, t2, null, dynamicIsBottom: fuzzyArrows);
+
+    // f2 has named parameters
+    if (n2s.length > 0) {
+      // Check that every named parameter in f2 has a match in f1
+      for (String k2 in n2s.keys) {
+        if (!n1s.containsKey(k2)) {
+          return false;
+        }
+        if (!parameterSubtype(n2s[k2], n1s[k2])) {
+          return false;
+        }
+      }
+    }
+    // If we get here, we either have no named parameters,
+    // or else the named parameters match and we have no optional
+    // parameters
+
+    // If f1 has more required parameters, reject
+    if (r1s.length > r2s.length) {
+      return false;
+    }
+
+    // If f2 has more required + optional parameters, reject
+    if (r2s.length + o2s.length > r1s.length + o1s.length) {
+      return false;
+    }
+
+    // The parameter lists must look like the following at this point
+    // where rrr is a region of required, and ooo is a region of optionals.
+    // f1: rrr ooo ooo ooo
+    // f2: rrr rrr ooo
+    int rr = r1s.length; // required in both
+    int or = r2s.length - r1s.length; // optional in f1, required in f2
+    int oo = o2s.length; // optional in both
+
+    for (int i = 0; i < rr; ++i) {
+      if (!parameterSubtype(r2s[i], r1s[i])) {
+        return false;
+      }
+    }
+    for (int i = 0, j = rr; i < or; ++i, ++j) {
+      if (!parameterSubtype(r2s[j], o1s[i])) {
+        return false;
+      }
+    }
+    for (int i = or, j = 0; i < oo; ++i, ++j) {
+      if (!parameterSubtype(o2s[j], o1s[i])) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  bool _isInterfaceSubtypeOf(
+      InterfaceType i1, InterfaceType i2, Set<Element> visited) {
+    // Guard recursive calls
+    _GuardedSubtypeChecker<InterfaceType> guardedInterfaceSubtype =
+        _guard(_isInterfaceSubtypeOf);
+
+    if (i1 == i2) {
+      return true;
+    }
+
+    if (i1.element == i2.element) {
+      List<DartType> tArgs1 = i1.typeArguments;
+      List<DartType> tArgs2 = i2.typeArguments;
+
+      assert(tArgs1.length == tArgs2.length);
+
+      for (int i = 0; i < tArgs1.length; i++) {
+        DartType t1 = tArgs1[i];
+        DartType t2 = tArgs2[i];
+        if (!isSubtypeOf(t1, t2)) {
+          return false;
+        }
+      }
+      return true;
+    }
+
+    if (i2.isDartCoreFunction && i1.element.getMethod("call") != null) {
+      return true;
+    }
+
+    if (i1.isObject) {
+      return false;
+    }
+
+    if (guardedInterfaceSubtype(i1.superclass, i2, visited)) {
+      return true;
+    }
+
+    for (final parent in i1.interfaces) {
+      if (guardedInterfaceSubtype(parent, i2, visited)) {
+        return true;
+      }
+    }
+
+    for (final parent in i1.mixins) {
+      if (guardedInterfaceSubtype(parent, i2, visited)) {
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  bool _isSubtypeOf(DartType t1, DartType t2, Set<Element> visited,
+      {bool dynamicIsBottom: false}) {
+    // Guard recursive calls
+    _GuardedSubtypeChecker<DartType> guardedSubtype = _guard(_isSubtypeOf);
+
+    if (t1 == t2) {
+      return true;
+    }
+
+    // The types are void, dynamic, bottom, interface types, function types
+    // and type parameters.  We proceed by eliminating these different classes
+    // from consideration.
+
+    // Trivially true.
+    if (_isTop(t2, dynamicIsBottom: dynamicIsBottom) ||
+        _isBottom(t1, dynamicIsBottom: dynamicIsBottom)) {
+      return true;
+    }
+
+    // Trivially false.
+    if (_isTop(t1, dynamicIsBottom: dynamicIsBottom) ||
+        _isBottom(t2, dynamicIsBottom: dynamicIsBottom)) {
+      return false;
+    }
+
+    // S <: T where S is a type variable
+    //  T is not dynamic or object (handled above)
+    //  S != T (handled above)
+    //  So only true if bound of S is S' and
+    //  S' <: T
+    if (t1 is TypeParameterType) {
+      DartType bound = t1.element.bound;
+      if (bound == null) return false;
+      return guardedSubtype(bound, t2, visited);
+    }
+
+    if (t2 is TypeParameterType) {
+      return false;
+    }
+
+    if (t1.isVoid || t2.isVoid) {
+      return false;
+    }
+
+    // We've eliminated void, dynamic, bottom, and type parameters.  The only
+    // cases are the combinations of interface type and function type.
+
+    // A function type can only subtype an interface type if
+    // the interface type is Function
+    if (t1 is FunctionType && t2 is InterfaceType) {
+      return t2.isDartCoreFunction;
+    }
+
+    // An interface type can only subtype a function type if
+    // the interface type declares a call method with a type
+    // which is a super type of the function type.
+    if (t1 is InterfaceType && t2 is FunctionType) {
+      var callType = _getCallMethodType(t1);
+      return (callType != null) && _isFunctionSubtypeOf(callType, t2);
+    }
+
+    // Two interface types
+    if (t1 is InterfaceType && t2 is InterfaceType) {
+      return _isInterfaceSubtypeOf(t1, t2, visited);
+    }
+
+    return _isFunctionSubtypeOf(t1 as FunctionType, t2 as FunctionType);
+  }
+
+  // TODO(leafp): Document the rules in play here
+  bool _isTop(DartType t, {bool dynamicIsBottom: false}) {
+    return (t.isDynamic && !dynamicIsBottom) || t.isObject;
+  }
+}
+
+
+/**
+ * The interface `TypeSystem` defines the behavior of an object representing
+ * the type system.  This provides a common location to put methods that act on
+ * types but may need access to more global data structures, and it paves the
+ * way for a possible future where we may wish to make the type system
+ * pluggable.
+ */
+abstract class TypeSystem {
+  /**
+   * Compute the least upper bound of two types.
+   */
+  DartType getLeastUpperBound(
+      TypeProvider typeProvider, DartType type1, DartType type2);
+
+  /**
+   * Return `true` if the [leftType] is assignable to the [rightType] (that is,
+   * if leftType <==> rightType).
+   */
+  bool isAssignableTo(DartType leftType, DartType rightType);
+
+  /**
+   * Return `true` if the [leftType] is a subtype of the [rightType] (that is,
+   * if leftType <: rightType).
+   */
+  bool isSubtypeOf(DartType leftType, DartType rightType);
+
+  /**
+   * Create either a strong mode or regular type system based on context.
+   */
+  static TypeSystem create(AnalysisContext context) {
+    return (context.analysisOptions.strongMode)
+        ? new StrongTypeSystemImpl()
+        : new TypeSystemImpl();
+  }
+}
+
+/**
+ * Implementation of [TypeSystem] using the rules in the Dart specification.
+ */
+class TypeSystemImpl implements TypeSystem {
+  TypeSystemImpl();
+
+  @override
+  DartType getLeastUpperBound(
+      TypeProvider typeProvider, DartType type1, DartType type2) {
+    // The least upper bound relation is reflexive.
+    if (identical(type1, type2)) {
+      return type1;
+    }
+    // The least upper bound of dynamic and any type T is dynamic.
+    if (type1.isDynamic) {
+      return type1;
+    }
+    if (type2.isDynamic) {
+      return type2;
+    }
+    // The least upper bound of void and any type T != dynamic is void.
+    if (type1.isVoid) {
+      return type1;
+    }
+    if (type2.isVoid) {
+      return type2;
+    }
+    // The least upper bound of bottom and any type T is T.
+    if (type1.isBottom) {
+      return type2;
+    }
+    if (type2.isBottom) {
+      return type1;
+    }
+    // Let U be a type variable with upper bound B.  The least upper bound of U
+    // and a type T is the least upper bound of B and T.
+    while (type1 is TypeParameterType) {
+      // TODO(paulberry): is this correct in the complex of F-bounded
+      // polymorphism?
+      DartType bound = (type1 as TypeParameterType).element.bound;
+      if (bound == null) {
+        bound = typeProvider.objectType;
+      }
+      type1 = bound;
+    }
+    while (type2 is TypeParameterType) {
+      // TODO(paulberry): is this correct in the context of F-bounded
+      // polymorphism?
+      DartType bound = (type2 as TypeParameterType).element.bound;
+      if (bound == null) {
+        bound = typeProvider.objectType;
+      }
+      type2 = bound;
+    }
+    // The least upper bound of a function type and an interface type T is the
+    // least upper bound of Function and T.
+    if (type1 is FunctionType && type2 is InterfaceType) {
+      type1 = typeProvider.functionType;
+    }
+    if (type2 is FunctionType && type1 is InterfaceType) {
+      type2 = typeProvider.functionType;
+    }
+
+    // At this point type1 and type2 should both either be interface types or
+    // function types.
+    if (type1 is InterfaceType && type2 is InterfaceType) {
+      InterfaceType result =
+          InterfaceTypeImpl.computeLeastUpperBound(type1, type2);
+      if (result == null) {
+        return typeProvider.dynamicType;
+      }
+      return result;
+    } else if (type1 is FunctionType && type2 is FunctionType) {
+      FunctionType result =
+          FunctionTypeImpl.computeLeastUpperBound(type1, type2);
+      if (result == null) {
+        return typeProvider.functionType;
+      }
+      return result;
+    } else {
+      // Should never happen.  As a defensive measure, return the dynamic type.
+      assert(false);
+      return typeProvider.dynamicType;
+    }
+  }
+
+  @override
+  bool isAssignableTo(DartType leftType, DartType rightType) {
+    return leftType.isAssignableTo(rightType);
+  }
+
+  @override
+  bool isSubtypeOf(DartType leftType, DartType rightType) {
+    return leftType.isSubtypeOf(rightType);
+  }
+}
diff --git a/pkg/analyzer/lib/src/generated/utilities_general.dart b/pkg/analyzer/lib/src/generated/utilities_general.dart
index d000b54..c1a3446 100644
--- a/pkg/analyzer/lib/src/generated/utilities_general.dart
+++ b/pkg/analyzer/lib/src/generated/utilities_general.dart
@@ -8,6 +8,24 @@
 import 'dart:developer' show UserTag;
 
 /**
+ * Test if the given [value] is `true` or the string "true" (case-insensitive).
+ */
+bool isTrue(Object value) =>
+    value is bool ? value : toLowerCase(value) == 'true';
+
+/**
+ * Safely convert this [value] to lower case, returning `null` if [value] is
+ * null.
+ */
+String toLowerCase(Object value) => value?.toString()?.toLowerCase();
+
+/**
+ * Safely convert this [value] to upper case, returning `null` if [value] is
+ * null.
+ */
+String toUpperCase(Object value) => value?.toString()?.toUpperCase();
+
+/**
  * Jenkins hash function, optimized for small integers.
  * Borrowed from sdk/lib/math/jenkins_smi_hash.dart.
  */
diff --git a/pkg/analyzer/lib/src/summary/builder.dart b/pkg/analyzer/lib/src/summary/builder.dart
new file mode 100644
index 0000000..f63bdd5
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary/builder.dart
@@ -0,0 +1,24 @@
+// 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.
+
+/**
+ * Format-agnostic infrastructure for building summary objects.
+ */
+library analyzer.src.summary.builder;
+
+import 'dart:convert';
+
+/**
+ * Instances of this class encapsulate the necessary state to keep track of a
+ * serialized summary that is in the process of being built.
+ *
+ * This class is intended to be passed to the constructors of the summary
+ * Builder classes.
+ */
+class BuilderContext {
+  // Note: at the moment this is a placeholder class since the current
+  // serialization format (JSON) doesn't require any state tracking.  If/when
+  // we switch to a serialization format that requires state tracking, the
+  // state will be stored here.
+}
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
new file mode 100644
index 0000000..61a4978
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -0,0 +1,1285 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// This file has been automatically generated.  Please do not edit it manually.
+// To regenerate the file, use the script "pkg/analyzer/tool/generate_files".
+
+library analyzer.src.summary.format;
+
+import 'dart:convert';
+import 'builder.dart' as builder;
+
+enum PrelinkedReferenceKind {
+  classOrEnum,
+  typedef,
+  other,
+  unresolved,
+}
+
+enum UnlinkedExecutableKind {
+  functionOrMethod,
+  getter,
+  setter,
+  constructor,
+}
+
+enum UnlinkedParamKind {
+  required,
+  positional,
+  named,
+}
+
+class PrelinkedDependency {
+  String _uri;
+
+  PrelinkedDependency.fromJson(Map json)
+    : _uri = json["uri"];
+
+  String get uri => _uri ?? '';
+}
+
+class PrelinkedDependencyBuilder {
+  final Map _json = {};
+
+  PrelinkedDependencyBuilder(builder.BuilderContext context);
+
+  void set uri(String _value) {
+    assert(!_json.containsKey("uri"));
+    if (_value != null) {
+      _json["uri"] = _value;
+    }
+  }
+
+  Map finish() => _json;
+}
+
+PrelinkedDependencyBuilder encodePrelinkedDependency(builder.BuilderContext builderContext, {String uri}) {
+  PrelinkedDependencyBuilder builder = new PrelinkedDependencyBuilder(builderContext);
+  builder.uri = uri;
+  return builder;
+}
+
+class PrelinkedLibrary {
+  UnlinkedLibrary _unlinked;
+  List<PrelinkedDependency> _dependencies;
+  List<int> _importDependencies;
+  List<PrelinkedReference> _references;
+
+  PrelinkedLibrary.fromJson(Map json)
+    : _unlinked = json["unlinked"] == null ? null : new UnlinkedLibrary.fromJson(json["unlinked"]),
+      _dependencies = json["dependencies"]?.map((x) => new PrelinkedDependency.fromJson(x))?.toList(),
+      _importDependencies = json["importDependencies"],
+      _references = json["references"]?.map((x) => new PrelinkedReference.fromJson(x))?.toList();
+
+  PrelinkedLibrary.fromBuffer(List<int> buffer) : this.fromJson(JSON.decode(UTF8.decode(buffer)));
+
+  UnlinkedLibrary get unlinked => _unlinked;
+  List<PrelinkedDependency> get dependencies => _dependencies ?? const <PrelinkedDependency>[];
+  List<int> get importDependencies => _importDependencies ?? const <int>[];
+  List<PrelinkedReference> get references => _references ?? const <PrelinkedReference>[];
+}
+
+class PrelinkedLibraryBuilder {
+  final Map _json = {};
+
+  PrelinkedLibraryBuilder(builder.BuilderContext context);
+
+  void set unlinked(UnlinkedLibraryBuilder _value) {
+    assert(!_json.containsKey("unlinked"));
+    if (_value != null) {
+      _json["unlinked"] = _value.finish();
+    }
+  }
+
+  void set dependencies(List<PrelinkedDependencyBuilder> _value) {
+    assert(!_json.containsKey("dependencies"));
+    if (_value != null || _value.isEmpty) {
+      _json["dependencies"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  void set importDependencies(List<int> _value) {
+    assert(!_json.containsKey("importDependencies"));
+    if (_value != null || _value.isEmpty) {
+      _json["importDependencies"] = _value.toList();
+    }
+  }
+
+  void set references(List<PrelinkedReferenceBuilder> _value) {
+    assert(!_json.containsKey("references"));
+    if (_value != null || _value.isEmpty) {
+      _json["references"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  List<int> toBuffer() => UTF8.encode(JSON.encode(finish()));
+
+  Map finish() => _json;
+}
+
+PrelinkedLibraryBuilder encodePrelinkedLibrary(builder.BuilderContext builderContext, {UnlinkedLibraryBuilder unlinked, List<PrelinkedDependencyBuilder> dependencies, List<int> importDependencies, List<PrelinkedReferenceBuilder> references}) {
+  PrelinkedLibraryBuilder builder = new PrelinkedLibraryBuilder(builderContext);
+  builder.unlinked = unlinked;
+  builder.dependencies = dependencies;
+  builder.importDependencies = importDependencies;
+  builder.references = references;
+  return builder;
+}
+
+class PrelinkedReference {
+  int _dependency;
+  PrelinkedReferenceKind _kind;
+
+  PrelinkedReference.fromJson(Map json)
+    : _dependency = json["dependency"],
+      _kind = json["kind"] == null ? null : PrelinkedReferenceKind.values[json["kind"]];
+
+  int get dependency => _dependency ?? 0;
+  PrelinkedReferenceKind get kind => _kind ?? PrelinkedReferenceKind.classOrEnum;
+}
+
+class PrelinkedReferenceBuilder {
+  final Map _json = {};
+
+  PrelinkedReferenceBuilder(builder.BuilderContext context);
+
+  void set dependency(int _value) {
+    assert(!_json.containsKey("dependency"));
+    if (_value != null) {
+      _json["dependency"] = _value;
+    }
+  }
+
+  void set kind(PrelinkedReferenceKind _value) {
+    assert(!_json.containsKey("kind"));
+    if (_value != null || _value == PrelinkedReferenceKind.classOrEnum) {
+      _json["kind"] = _value.index;
+    }
+  }
+
+  Map finish() => _json;
+}
+
+PrelinkedReferenceBuilder encodePrelinkedReference(builder.BuilderContext builderContext, {int dependency, PrelinkedReferenceKind kind}) {
+  PrelinkedReferenceBuilder builder = new PrelinkedReferenceBuilder(builderContext);
+  builder.dependency = dependency;
+  builder.kind = kind;
+  return builder;
+}
+
+class UnlinkedClass {
+  String _name;
+  int _unit;
+  List<UnlinkedTypeParam> _typeParameters;
+  UnlinkedTypeRef _supertype;
+  List<UnlinkedTypeRef> _mixins;
+  List<UnlinkedTypeRef> _interfaces;
+  List<UnlinkedVariable> _fields;
+  List<UnlinkedExecutable> _executables;
+  bool _isAbstract;
+  bool _isMixinApplication;
+
+  UnlinkedClass.fromJson(Map json)
+    : _name = json["name"],
+      _unit = json["unit"],
+      _typeParameters = json["typeParameters"]?.map((x) => new UnlinkedTypeParam.fromJson(x))?.toList(),
+      _supertype = json["supertype"] == null ? null : new UnlinkedTypeRef.fromJson(json["supertype"]),
+      _mixins = json["mixins"]?.map((x) => new UnlinkedTypeRef.fromJson(x))?.toList(),
+      _interfaces = json["interfaces"]?.map((x) => new UnlinkedTypeRef.fromJson(x))?.toList(),
+      _fields = json["fields"]?.map((x) => new UnlinkedVariable.fromJson(x))?.toList(),
+      _executables = json["executables"]?.map((x) => new UnlinkedExecutable.fromJson(x))?.toList(),
+      _isAbstract = json["isAbstract"],
+      _isMixinApplication = json["isMixinApplication"];
+
+  String get name => _name ?? '';
+  int get unit => _unit ?? 0;
+  List<UnlinkedTypeParam> get typeParameters => _typeParameters ?? const <UnlinkedTypeParam>[];
+  UnlinkedTypeRef get supertype => _supertype;
+  List<UnlinkedTypeRef> get mixins => _mixins ?? const <UnlinkedTypeRef>[];
+  List<UnlinkedTypeRef> get interfaces => _interfaces ?? const <UnlinkedTypeRef>[];
+  List<UnlinkedVariable> get fields => _fields ?? const <UnlinkedVariable>[];
+  List<UnlinkedExecutable> get executables => _executables ?? const <UnlinkedExecutable>[];
+  bool get isAbstract => _isAbstract ?? false;
+  bool get isMixinApplication => _isMixinApplication ?? false;
+}
+
+class UnlinkedClassBuilder {
+  final Map _json = {};
+
+  UnlinkedClassBuilder(builder.BuilderContext context);
+
+  void set name(String _value) {
+    assert(!_json.containsKey("name"));
+    if (_value != null) {
+      _json["name"] = _value;
+    }
+  }
+
+  void set unit(int _value) {
+    assert(!_json.containsKey("unit"));
+    if (_value != null) {
+      _json["unit"] = _value;
+    }
+  }
+
+  void set typeParameters(List<UnlinkedTypeParamBuilder> _value) {
+    assert(!_json.containsKey("typeParameters"));
+    if (_value != null || _value.isEmpty) {
+      _json["typeParameters"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  void set supertype(UnlinkedTypeRefBuilder _value) {
+    assert(!_json.containsKey("supertype"));
+    if (_value != null) {
+      _json["supertype"] = _value.finish();
+    }
+  }
+
+  void set mixins(List<UnlinkedTypeRefBuilder> _value) {
+    assert(!_json.containsKey("mixins"));
+    if (_value != null || _value.isEmpty) {
+      _json["mixins"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  void set interfaces(List<UnlinkedTypeRefBuilder> _value) {
+    assert(!_json.containsKey("interfaces"));
+    if (_value != null || _value.isEmpty) {
+      _json["interfaces"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  void set fields(List<UnlinkedVariableBuilder> _value) {
+    assert(!_json.containsKey("fields"));
+    if (_value != null || _value.isEmpty) {
+      _json["fields"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  void set executables(List<UnlinkedExecutableBuilder> _value) {
+    assert(!_json.containsKey("executables"));
+    if (_value != null || _value.isEmpty) {
+      _json["executables"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  void set isAbstract(bool _value) {
+    assert(!_json.containsKey("isAbstract"));
+    if (_value != null) {
+      _json["isAbstract"] = _value;
+    }
+  }
+
+  void set isMixinApplication(bool _value) {
+    assert(!_json.containsKey("isMixinApplication"));
+    if (_value != null) {
+      _json["isMixinApplication"] = _value;
+    }
+  }
+
+  Map finish() => _json;
+}
+
+UnlinkedClassBuilder encodeUnlinkedClass(builder.BuilderContext builderContext, {String name, int unit, List<UnlinkedTypeParamBuilder> typeParameters, UnlinkedTypeRefBuilder supertype, List<UnlinkedTypeRefBuilder> mixins, List<UnlinkedTypeRefBuilder> interfaces, List<UnlinkedVariableBuilder> fields, List<UnlinkedExecutableBuilder> executables, bool isAbstract, bool isMixinApplication}) {
+  UnlinkedClassBuilder builder = new UnlinkedClassBuilder(builderContext);
+  builder.name = name;
+  builder.unit = unit;
+  builder.typeParameters = typeParameters;
+  builder.supertype = supertype;
+  builder.mixins = mixins;
+  builder.interfaces = interfaces;
+  builder.fields = fields;
+  builder.executables = executables;
+  builder.isAbstract = isAbstract;
+  builder.isMixinApplication = isMixinApplication;
+  return builder;
+}
+
+class UnlinkedCombinator {
+  List<UnlinkedCombinatorName> _shows;
+  List<UnlinkedCombinatorName> _hides;
+
+  UnlinkedCombinator.fromJson(Map json)
+    : _shows = json["shows"]?.map((x) => new UnlinkedCombinatorName.fromJson(x))?.toList(),
+      _hides = json["hides"]?.map((x) => new UnlinkedCombinatorName.fromJson(x))?.toList();
+
+  List<UnlinkedCombinatorName> get shows => _shows ?? const <UnlinkedCombinatorName>[];
+  List<UnlinkedCombinatorName> get hides => _hides ?? const <UnlinkedCombinatorName>[];
+}
+
+class UnlinkedCombinatorBuilder {
+  final Map _json = {};
+
+  UnlinkedCombinatorBuilder(builder.BuilderContext context);
+
+  void set shows(List<UnlinkedCombinatorNameBuilder> _value) {
+    assert(!_json.containsKey("shows"));
+    if (_value != null || _value.isEmpty) {
+      _json["shows"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  void set hides(List<UnlinkedCombinatorNameBuilder> _value) {
+    assert(!_json.containsKey("hides"));
+    if (_value != null || _value.isEmpty) {
+      _json["hides"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  Map finish() => _json;
+}
+
+UnlinkedCombinatorBuilder encodeUnlinkedCombinator(builder.BuilderContext builderContext, {List<UnlinkedCombinatorNameBuilder> shows, List<UnlinkedCombinatorNameBuilder> hides}) {
+  UnlinkedCombinatorBuilder builder = new UnlinkedCombinatorBuilder(builderContext);
+  builder.shows = shows;
+  builder.hides = hides;
+  return builder;
+}
+
+class UnlinkedCombinatorName {
+  String _name;
+
+  UnlinkedCombinatorName.fromJson(Map json)
+    : _name = json["name"];
+
+  String get name => _name ?? '';
+}
+
+class UnlinkedCombinatorNameBuilder {
+  final Map _json = {};
+
+  UnlinkedCombinatorNameBuilder(builder.BuilderContext context);
+
+  void set name(String _value) {
+    assert(!_json.containsKey("name"));
+    if (_value != null) {
+      _json["name"] = _value;
+    }
+  }
+
+  Map finish() => _json;
+}
+
+UnlinkedCombinatorNameBuilder encodeUnlinkedCombinatorName(builder.BuilderContext builderContext, {String name}) {
+  UnlinkedCombinatorNameBuilder builder = new UnlinkedCombinatorNameBuilder(builderContext);
+  builder.name = name;
+  return builder;
+}
+
+class UnlinkedEnum {
+  String _name;
+  List<UnlinkedEnumValue> _values;
+  int _unit;
+
+  UnlinkedEnum.fromJson(Map json)
+    : _name = json["name"],
+      _values = json["values"]?.map((x) => new UnlinkedEnumValue.fromJson(x))?.toList(),
+      _unit = json["unit"];
+
+  String get name => _name ?? '';
+  List<UnlinkedEnumValue> get values => _values ?? const <UnlinkedEnumValue>[];
+  int get unit => _unit ?? 0;
+}
+
+class UnlinkedEnumBuilder {
+  final Map _json = {};
+
+  UnlinkedEnumBuilder(builder.BuilderContext context);
+
+  void set name(String _value) {
+    assert(!_json.containsKey("name"));
+    if (_value != null) {
+      _json["name"] = _value;
+    }
+  }
+
+  void set values(List<UnlinkedEnumValueBuilder> _value) {
+    assert(!_json.containsKey("values"));
+    if (_value != null || _value.isEmpty) {
+      _json["values"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  void set unit(int _value) {
+    assert(!_json.containsKey("unit"));
+    if (_value != null) {
+      _json["unit"] = _value;
+    }
+  }
+
+  Map finish() => _json;
+}
+
+UnlinkedEnumBuilder encodeUnlinkedEnum(builder.BuilderContext builderContext, {String name, List<UnlinkedEnumValueBuilder> values, int unit}) {
+  UnlinkedEnumBuilder builder = new UnlinkedEnumBuilder(builderContext);
+  builder.name = name;
+  builder.values = values;
+  builder.unit = unit;
+  return builder;
+}
+
+class UnlinkedEnumValue {
+  String _name;
+
+  UnlinkedEnumValue.fromJson(Map json)
+    : _name = json["name"];
+
+  String get name => _name ?? '';
+}
+
+class UnlinkedEnumValueBuilder {
+  final Map _json = {};
+
+  UnlinkedEnumValueBuilder(builder.BuilderContext context);
+
+  void set name(String _value) {
+    assert(!_json.containsKey("name"));
+    if (_value != null) {
+      _json["name"] = _value;
+    }
+  }
+
+  Map finish() => _json;
+}
+
+UnlinkedEnumValueBuilder encodeUnlinkedEnumValue(builder.BuilderContext builderContext, {String name}) {
+  UnlinkedEnumValueBuilder builder = new UnlinkedEnumValueBuilder(builderContext);
+  builder.name = name;
+  return builder;
+}
+
+class UnlinkedExecutable {
+  String _name;
+  int _unit;
+  List<UnlinkedTypeParam> _typeParameters;
+  UnlinkedTypeRef _returnType;
+  List<UnlinkedParam> _parameters;
+  UnlinkedExecutableKind _kind;
+  bool _isAbstract;
+  bool _isStatic;
+  bool _isConst;
+  bool _isFactory;
+
+  UnlinkedExecutable.fromJson(Map json)
+    : _name = json["name"],
+      _unit = json["unit"],
+      _typeParameters = json["typeParameters"]?.map((x) => new UnlinkedTypeParam.fromJson(x))?.toList(),
+      _returnType = json["returnType"] == null ? null : new UnlinkedTypeRef.fromJson(json["returnType"]),
+      _parameters = json["parameters"]?.map((x) => new UnlinkedParam.fromJson(x))?.toList(),
+      _kind = json["kind"] == null ? null : UnlinkedExecutableKind.values[json["kind"]],
+      _isAbstract = json["isAbstract"],
+      _isStatic = json["isStatic"],
+      _isConst = json["isConst"],
+      _isFactory = json["isFactory"];
+
+  String get name => _name ?? '';
+  int get unit => _unit ?? 0;
+  List<UnlinkedTypeParam> get typeParameters => _typeParameters ?? const <UnlinkedTypeParam>[];
+  UnlinkedTypeRef get returnType => _returnType;
+  List<UnlinkedParam> get parameters => _parameters ?? const <UnlinkedParam>[];
+  UnlinkedExecutableKind get kind => _kind ?? UnlinkedExecutableKind.functionOrMethod;
+  bool get isAbstract => _isAbstract ?? false;
+  bool get isStatic => _isStatic ?? false;
+  bool get isConst => _isConst ?? false;
+  bool get isFactory => _isFactory ?? false;
+}
+
+class UnlinkedExecutableBuilder {
+  final Map _json = {};
+
+  UnlinkedExecutableBuilder(builder.BuilderContext context);
+
+  void set name(String _value) {
+    assert(!_json.containsKey("name"));
+    if (_value != null) {
+      _json["name"] = _value;
+    }
+  }
+
+  void set unit(int _value) {
+    assert(!_json.containsKey("unit"));
+    if (_value != null) {
+      _json["unit"] = _value;
+    }
+  }
+
+  void set typeParameters(List<UnlinkedTypeParamBuilder> _value) {
+    assert(!_json.containsKey("typeParameters"));
+    if (_value != null || _value.isEmpty) {
+      _json["typeParameters"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  void set returnType(UnlinkedTypeRefBuilder _value) {
+    assert(!_json.containsKey("returnType"));
+    if (_value != null) {
+      _json["returnType"] = _value.finish();
+    }
+  }
+
+  void set parameters(List<UnlinkedParamBuilder> _value) {
+    assert(!_json.containsKey("parameters"));
+    if (_value != null || _value.isEmpty) {
+      _json["parameters"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  void set kind(UnlinkedExecutableKind _value) {
+    assert(!_json.containsKey("kind"));
+    if (_value != null || _value == UnlinkedExecutableKind.functionOrMethod) {
+      _json["kind"] = _value.index;
+    }
+  }
+
+  void set isAbstract(bool _value) {
+    assert(!_json.containsKey("isAbstract"));
+    if (_value != null) {
+      _json["isAbstract"] = _value;
+    }
+  }
+
+  void set isStatic(bool _value) {
+    assert(!_json.containsKey("isStatic"));
+    if (_value != null) {
+      _json["isStatic"] = _value;
+    }
+  }
+
+  void set isConst(bool _value) {
+    assert(!_json.containsKey("isConst"));
+    if (_value != null) {
+      _json["isConst"] = _value;
+    }
+  }
+
+  void set isFactory(bool _value) {
+    assert(!_json.containsKey("isFactory"));
+    if (_value != null) {
+      _json["isFactory"] = _value;
+    }
+  }
+
+  Map finish() => _json;
+}
+
+UnlinkedExecutableBuilder encodeUnlinkedExecutable(builder.BuilderContext builderContext, {String name, int unit, List<UnlinkedTypeParamBuilder> typeParameters, UnlinkedTypeRefBuilder returnType, List<UnlinkedParamBuilder> parameters, UnlinkedExecutableKind kind, bool isAbstract, bool isStatic, bool isConst, bool isFactory}) {
+  UnlinkedExecutableBuilder builder = new UnlinkedExecutableBuilder(builderContext);
+  builder.name = name;
+  builder.unit = unit;
+  builder.typeParameters = typeParameters;
+  builder.returnType = returnType;
+  builder.parameters = parameters;
+  builder.kind = kind;
+  builder.isAbstract = isAbstract;
+  builder.isStatic = isStatic;
+  builder.isConst = isConst;
+  builder.isFactory = isFactory;
+  return builder;
+}
+
+class UnlinkedExport {
+  String _uri;
+  List<UnlinkedCombinator> _combinators;
+
+  UnlinkedExport.fromJson(Map json)
+    : _uri = json["uri"],
+      _combinators = json["combinators"]?.map((x) => new UnlinkedCombinator.fromJson(x))?.toList();
+
+  String get uri => _uri ?? '';
+  List<UnlinkedCombinator> get combinators => _combinators ?? const <UnlinkedCombinator>[];
+}
+
+class UnlinkedExportBuilder {
+  final Map _json = {};
+
+  UnlinkedExportBuilder(builder.BuilderContext context);
+
+  void set uri(String _value) {
+    assert(!_json.containsKey("uri"));
+    if (_value != null) {
+      _json["uri"] = _value;
+    }
+  }
+
+  void set combinators(List<UnlinkedCombinatorBuilder> _value) {
+    assert(!_json.containsKey("combinators"));
+    if (_value != null || _value.isEmpty) {
+      _json["combinators"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  Map finish() => _json;
+}
+
+UnlinkedExportBuilder encodeUnlinkedExport(builder.BuilderContext builderContext, {String uri, List<UnlinkedCombinatorBuilder> combinators}) {
+  UnlinkedExportBuilder builder = new UnlinkedExportBuilder(builderContext);
+  builder.uri = uri;
+  builder.combinators = combinators;
+  return builder;
+}
+
+class UnlinkedImport {
+  String _uri;
+  int _offset;
+  int _prefix;
+  List<UnlinkedCombinator> _combinators;
+  bool _isDeferred;
+  bool _isImplicit;
+
+  UnlinkedImport.fromJson(Map json)
+    : _uri = json["uri"],
+      _offset = json["offset"],
+      _prefix = json["prefix"],
+      _combinators = json["combinators"]?.map((x) => new UnlinkedCombinator.fromJson(x))?.toList(),
+      _isDeferred = json["isDeferred"],
+      _isImplicit = json["isImplicit"];
+
+  String get uri => _uri ?? '';
+  int get offset => _offset ?? 0;
+  int get prefix => _prefix ?? 0;
+  List<UnlinkedCombinator> get combinators => _combinators ?? const <UnlinkedCombinator>[];
+  bool get isDeferred => _isDeferred ?? false;
+  bool get isImplicit => _isImplicit ?? false;
+}
+
+class UnlinkedImportBuilder {
+  final Map _json = {};
+
+  UnlinkedImportBuilder(builder.BuilderContext context);
+
+  void set uri(String _value) {
+    assert(!_json.containsKey("uri"));
+    if (_value != null) {
+      _json["uri"] = _value;
+    }
+  }
+
+  void set offset(int _value) {
+    assert(!_json.containsKey("offset"));
+    if (_value != null) {
+      _json["offset"] = _value;
+    }
+  }
+
+  void set prefix(int _value) {
+    assert(!_json.containsKey("prefix"));
+    if (_value != null) {
+      _json["prefix"] = _value;
+    }
+  }
+
+  void set combinators(List<UnlinkedCombinatorBuilder> _value) {
+    assert(!_json.containsKey("combinators"));
+    if (_value != null || _value.isEmpty) {
+      _json["combinators"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  void set isDeferred(bool _value) {
+    assert(!_json.containsKey("isDeferred"));
+    if (_value != null) {
+      _json["isDeferred"] = _value;
+    }
+  }
+
+  void set isImplicit(bool _value) {
+    assert(!_json.containsKey("isImplicit"));
+    if (_value != null) {
+      _json["isImplicit"] = _value;
+    }
+  }
+
+  Map finish() => _json;
+}
+
+UnlinkedImportBuilder encodeUnlinkedImport(builder.BuilderContext builderContext, {String uri, int offset, int prefix, List<UnlinkedCombinatorBuilder> combinators, bool isDeferred, bool isImplicit}) {
+  UnlinkedImportBuilder builder = new UnlinkedImportBuilder(builderContext);
+  builder.uri = uri;
+  builder.offset = offset;
+  builder.prefix = prefix;
+  builder.combinators = combinators;
+  builder.isDeferred = isDeferred;
+  builder.isImplicit = isImplicit;
+  return builder;
+}
+
+class UnlinkedLibrary {
+  List<UnlinkedReference> _references;
+  List<UnlinkedUnit> _units;
+  String _name;
+  List<UnlinkedClass> _classes;
+  List<UnlinkedEnum> _enums;
+  List<UnlinkedExecutable> _executables;
+  List<UnlinkedExport> _exports;
+  List<UnlinkedImport> _imports;
+  List<UnlinkedTypedef> _typedefs;
+  List<UnlinkedVariable> _variables;
+  List<UnlinkedPrefix> _prefixes;
+
+  UnlinkedLibrary.fromJson(Map json)
+    : _references = json["references"]?.map((x) => new UnlinkedReference.fromJson(x))?.toList(),
+      _units = json["units"]?.map((x) => new UnlinkedUnit.fromJson(x))?.toList(),
+      _name = json["name"],
+      _classes = json["classes"]?.map((x) => new UnlinkedClass.fromJson(x))?.toList(),
+      _enums = json["enums"]?.map((x) => new UnlinkedEnum.fromJson(x))?.toList(),
+      _executables = json["executables"]?.map((x) => new UnlinkedExecutable.fromJson(x))?.toList(),
+      _exports = json["exports"]?.map((x) => new UnlinkedExport.fromJson(x))?.toList(),
+      _imports = json["imports"]?.map((x) => new UnlinkedImport.fromJson(x))?.toList(),
+      _typedefs = json["typedefs"]?.map((x) => new UnlinkedTypedef.fromJson(x))?.toList(),
+      _variables = json["variables"]?.map((x) => new UnlinkedVariable.fromJson(x))?.toList(),
+      _prefixes = json["prefixes"]?.map((x) => new UnlinkedPrefix.fromJson(x))?.toList();
+
+  List<UnlinkedReference> get references => _references ?? const <UnlinkedReference>[];
+  List<UnlinkedUnit> get units => _units ?? const <UnlinkedUnit>[];
+  String get name => _name ?? '';
+  List<UnlinkedClass> get classes => _classes ?? const <UnlinkedClass>[];
+  List<UnlinkedEnum> get enums => _enums ?? const <UnlinkedEnum>[];
+  List<UnlinkedExecutable> get executables => _executables ?? const <UnlinkedExecutable>[];
+  List<UnlinkedExport> get exports => _exports ?? const <UnlinkedExport>[];
+  List<UnlinkedImport> get imports => _imports ?? const <UnlinkedImport>[];
+  List<UnlinkedTypedef> get typedefs => _typedefs ?? const <UnlinkedTypedef>[];
+  List<UnlinkedVariable> get variables => _variables ?? const <UnlinkedVariable>[];
+  List<UnlinkedPrefix> get prefixes => _prefixes ?? const <UnlinkedPrefix>[];
+}
+
+class UnlinkedLibraryBuilder {
+  final Map _json = {};
+
+  UnlinkedLibraryBuilder(builder.BuilderContext context);
+
+  void set references(List<UnlinkedReferenceBuilder> _value) {
+    assert(!_json.containsKey("references"));
+    if (_value != null || _value.isEmpty) {
+      _json["references"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  void set units(List<UnlinkedUnitBuilder> _value) {
+    assert(!_json.containsKey("units"));
+    if (_value != null || _value.isEmpty) {
+      _json["units"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  void set name(String _value) {
+    assert(!_json.containsKey("name"));
+    if (_value != null) {
+      _json["name"] = _value;
+    }
+  }
+
+  void set classes(List<UnlinkedClassBuilder> _value) {
+    assert(!_json.containsKey("classes"));
+    if (_value != null || _value.isEmpty) {
+      _json["classes"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  void set enums(List<UnlinkedEnumBuilder> _value) {
+    assert(!_json.containsKey("enums"));
+    if (_value != null || _value.isEmpty) {
+      _json["enums"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  void set executables(List<UnlinkedExecutableBuilder> _value) {
+    assert(!_json.containsKey("executables"));
+    if (_value != null || _value.isEmpty) {
+      _json["executables"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  void set exports(List<UnlinkedExportBuilder> _value) {
+    assert(!_json.containsKey("exports"));
+    if (_value != null || _value.isEmpty) {
+      _json["exports"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  void set imports(List<UnlinkedImportBuilder> _value) {
+    assert(!_json.containsKey("imports"));
+    if (_value != null || _value.isEmpty) {
+      _json["imports"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  void set typedefs(List<UnlinkedTypedefBuilder> _value) {
+    assert(!_json.containsKey("typedefs"));
+    if (_value != null || _value.isEmpty) {
+      _json["typedefs"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  void set variables(List<UnlinkedVariableBuilder> _value) {
+    assert(!_json.containsKey("variables"));
+    if (_value != null || _value.isEmpty) {
+      _json["variables"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  void set prefixes(List<UnlinkedPrefixBuilder> _value) {
+    assert(!_json.containsKey("prefixes"));
+    if (_value != null || _value.isEmpty) {
+      _json["prefixes"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  Map finish() => _json;
+}
+
+UnlinkedLibraryBuilder encodeUnlinkedLibrary(builder.BuilderContext builderContext, {List<UnlinkedReferenceBuilder> references, List<UnlinkedUnitBuilder> units, String name, List<UnlinkedClassBuilder> classes, List<UnlinkedEnumBuilder> enums, List<UnlinkedExecutableBuilder> executables, List<UnlinkedExportBuilder> exports, List<UnlinkedImportBuilder> imports, List<UnlinkedTypedefBuilder> typedefs, List<UnlinkedVariableBuilder> variables, List<UnlinkedPrefixBuilder> prefixes}) {
+  UnlinkedLibraryBuilder builder = new UnlinkedLibraryBuilder(builderContext);
+  builder.references = references;
+  builder.units = units;
+  builder.name = name;
+  builder.classes = classes;
+  builder.enums = enums;
+  builder.executables = executables;
+  builder.exports = exports;
+  builder.imports = imports;
+  builder.typedefs = typedefs;
+  builder.variables = variables;
+  builder.prefixes = prefixes;
+  return builder;
+}
+
+class UnlinkedParam {
+  String _name;
+  UnlinkedTypeRef _type;
+  List<UnlinkedParam> _parameters;
+  UnlinkedParamKind _kind;
+  bool _isFunctionTyped;
+  bool _isInitializingFormal;
+
+  UnlinkedParam.fromJson(Map json)
+    : _name = json["name"],
+      _type = json["type"] == null ? null : new UnlinkedTypeRef.fromJson(json["type"]),
+      _parameters = json["parameters"]?.map((x) => new UnlinkedParam.fromJson(x))?.toList(),
+      _kind = json["kind"] == null ? null : UnlinkedParamKind.values[json["kind"]],
+      _isFunctionTyped = json["isFunctionTyped"],
+      _isInitializingFormal = json["isInitializingFormal"];
+
+  String get name => _name ?? '';
+  UnlinkedTypeRef get type => _type;
+  List<UnlinkedParam> get parameters => _parameters ?? const <UnlinkedParam>[];
+  UnlinkedParamKind get kind => _kind ?? UnlinkedParamKind.required;
+  bool get isFunctionTyped => _isFunctionTyped ?? false;
+  bool get isInitializingFormal => _isInitializingFormal ?? false;
+}
+
+class UnlinkedParamBuilder {
+  final Map _json = {};
+
+  UnlinkedParamBuilder(builder.BuilderContext context);
+
+  void set name(String _value) {
+    assert(!_json.containsKey("name"));
+    if (_value != null) {
+      _json["name"] = _value;
+    }
+  }
+
+  void set type(UnlinkedTypeRefBuilder _value) {
+    assert(!_json.containsKey("type"));
+    if (_value != null) {
+      _json["type"] = _value.finish();
+    }
+  }
+
+  void set parameters(List<UnlinkedParamBuilder> _value) {
+    assert(!_json.containsKey("parameters"));
+    if (_value != null || _value.isEmpty) {
+      _json["parameters"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  void set kind(UnlinkedParamKind _value) {
+    assert(!_json.containsKey("kind"));
+    if (_value != null || _value == UnlinkedParamKind.required) {
+      _json["kind"] = _value.index;
+    }
+  }
+
+  void set isFunctionTyped(bool _value) {
+    assert(!_json.containsKey("isFunctionTyped"));
+    if (_value != null) {
+      _json["isFunctionTyped"] = _value;
+    }
+  }
+
+  void set isInitializingFormal(bool _value) {
+    assert(!_json.containsKey("isInitializingFormal"));
+    if (_value != null) {
+      _json["isInitializingFormal"] = _value;
+    }
+  }
+
+  Map finish() => _json;
+}
+
+UnlinkedParamBuilder encodeUnlinkedParam(builder.BuilderContext builderContext, {String name, UnlinkedTypeRefBuilder type, List<UnlinkedParamBuilder> parameters, UnlinkedParamKind kind, bool isFunctionTyped, bool isInitializingFormal}) {
+  UnlinkedParamBuilder builder = new UnlinkedParamBuilder(builderContext);
+  builder.name = name;
+  builder.type = type;
+  builder.parameters = parameters;
+  builder.kind = kind;
+  builder.isFunctionTyped = isFunctionTyped;
+  builder.isInitializingFormal = isInitializingFormal;
+  return builder;
+}
+
+class UnlinkedPrefix {
+  String _name;
+
+  UnlinkedPrefix.fromJson(Map json)
+    : _name = json["name"];
+
+  String get name => _name ?? '';
+}
+
+class UnlinkedPrefixBuilder {
+  final Map _json = {};
+
+  UnlinkedPrefixBuilder(builder.BuilderContext context);
+
+  void set name(String _value) {
+    assert(!_json.containsKey("name"));
+    if (_value != null) {
+      _json["name"] = _value;
+    }
+  }
+
+  Map finish() => _json;
+}
+
+UnlinkedPrefixBuilder encodeUnlinkedPrefix(builder.BuilderContext builderContext, {String name}) {
+  UnlinkedPrefixBuilder builder = new UnlinkedPrefixBuilder(builderContext);
+  builder.name = name;
+  return builder;
+}
+
+class UnlinkedReference {
+  String _name;
+  int _prefix;
+
+  UnlinkedReference.fromJson(Map json)
+    : _name = json["name"],
+      _prefix = json["prefix"];
+
+  String get name => _name ?? '';
+  int get prefix => _prefix ?? 0;
+}
+
+class UnlinkedReferenceBuilder {
+  final Map _json = {};
+
+  UnlinkedReferenceBuilder(builder.BuilderContext context);
+
+  void set name(String _value) {
+    assert(!_json.containsKey("name"));
+    if (_value != null) {
+      _json["name"] = _value;
+    }
+  }
+
+  void set prefix(int _value) {
+    assert(!_json.containsKey("prefix"));
+    if (_value != null) {
+      _json["prefix"] = _value;
+    }
+  }
+
+  Map finish() => _json;
+}
+
+UnlinkedReferenceBuilder encodeUnlinkedReference(builder.BuilderContext builderContext, {String name, int prefix}) {
+  UnlinkedReferenceBuilder builder = new UnlinkedReferenceBuilder(builderContext);
+  builder.name = name;
+  builder.prefix = prefix;
+  return builder;
+}
+
+class UnlinkedTypedef {
+  String _name;
+  int _unit;
+  List<UnlinkedTypeParam> _typeParameters;
+  UnlinkedTypeRef _returnType;
+  List<UnlinkedParam> _parameters;
+
+  UnlinkedTypedef.fromJson(Map json)
+    : _name = json["name"],
+      _unit = json["unit"],
+      _typeParameters = json["typeParameters"]?.map((x) => new UnlinkedTypeParam.fromJson(x))?.toList(),
+      _returnType = json["returnType"] == null ? null : new UnlinkedTypeRef.fromJson(json["returnType"]),
+      _parameters = json["parameters"]?.map((x) => new UnlinkedParam.fromJson(x))?.toList();
+
+  String get name => _name ?? '';
+  int get unit => _unit ?? 0;
+  List<UnlinkedTypeParam> get typeParameters => _typeParameters ?? const <UnlinkedTypeParam>[];
+  UnlinkedTypeRef get returnType => _returnType;
+  List<UnlinkedParam> get parameters => _parameters ?? const <UnlinkedParam>[];
+}
+
+class UnlinkedTypedefBuilder {
+  final Map _json = {};
+
+  UnlinkedTypedefBuilder(builder.BuilderContext context);
+
+  void set name(String _value) {
+    assert(!_json.containsKey("name"));
+    if (_value != null) {
+      _json["name"] = _value;
+    }
+  }
+
+  void set unit(int _value) {
+    assert(!_json.containsKey("unit"));
+    if (_value != null) {
+      _json["unit"] = _value;
+    }
+  }
+
+  void set typeParameters(List<UnlinkedTypeParamBuilder> _value) {
+    assert(!_json.containsKey("typeParameters"));
+    if (_value != null || _value.isEmpty) {
+      _json["typeParameters"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  void set returnType(UnlinkedTypeRefBuilder _value) {
+    assert(!_json.containsKey("returnType"));
+    if (_value != null) {
+      _json["returnType"] = _value.finish();
+    }
+  }
+
+  void set parameters(List<UnlinkedParamBuilder> _value) {
+    assert(!_json.containsKey("parameters"));
+    if (_value != null || _value.isEmpty) {
+      _json["parameters"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  Map finish() => _json;
+}
+
+UnlinkedTypedefBuilder encodeUnlinkedTypedef(builder.BuilderContext builderContext, {String name, int unit, List<UnlinkedTypeParamBuilder> typeParameters, UnlinkedTypeRefBuilder returnType, List<UnlinkedParamBuilder> parameters}) {
+  UnlinkedTypedefBuilder builder = new UnlinkedTypedefBuilder(builderContext);
+  builder.name = name;
+  builder.unit = unit;
+  builder.typeParameters = typeParameters;
+  builder.returnType = returnType;
+  builder.parameters = parameters;
+  return builder;
+}
+
+class UnlinkedTypeParam {
+  String _name;
+  UnlinkedTypeRef _bound;
+
+  UnlinkedTypeParam.fromJson(Map json)
+    : _name = json["name"],
+      _bound = json["bound"] == null ? null : new UnlinkedTypeRef.fromJson(json["bound"]);
+
+  String get name => _name ?? '';
+  UnlinkedTypeRef get bound => _bound;
+}
+
+class UnlinkedTypeParamBuilder {
+  final Map _json = {};
+
+  UnlinkedTypeParamBuilder(builder.BuilderContext context);
+
+  void set name(String _value) {
+    assert(!_json.containsKey("name"));
+    if (_value != null) {
+      _json["name"] = _value;
+    }
+  }
+
+  void set bound(UnlinkedTypeRefBuilder _value) {
+    assert(!_json.containsKey("bound"));
+    if (_value != null) {
+      _json["bound"] = _value.finish();
+    }
+  }
+
+  Map finish() => _json;
+}
+
+UnlinkedTypeParamBuilder encodeUnlinkedTypeParam(builder.BuilderContext builderContext, {String name, UnlinkedTypeRefBuilder bound}) {
+  UnlinkedTypeParamBuilder builder = new UnlinkedTypeParamBuilder(builderContext);
+  builder.name = name;
+  builder.bound = bound;
+  return builder;
+}
+
+class UnlinkedTypeRef {
+  int _reference;
+  int _paramReference;
+  List<UnlinkedTypeRef> _typeArguments;
+
+  UnlinkedTypeRef.fromJson(Map json)
+    : _reference = json["reference"],
+      _paramReference = json["paramReference"],
+      _typeArguments = json["typeArguments"]?.map((x) => new UnlinkedTypeRef.fromJson(x))?.toList();
+
+  int get reference => _reference ?? 0;
+  int get paramReference => _paramReference ?? 0;
+  List<UnlinkedTypeRef> get typeArguments => _typeArguments ?? const <UnlinkedTypeRef>[];
+}
+
+class UnlinkedTypeRefBuilder {
+  final Map _json = {};
+
+  UnlinkedTypeRefBuilder(builder.BuilderContext context);
+
+  void set reference(int _value) {
+    assert(!_json.containsKey("reference"));
+    if (_value != null) {
+      _json["reference"] = _value;
+    }
+  }
+
+  void set paramReference(int _value) {
+    assert(!_json.containsKey("paramReference"));
+    if (_value != null) {
+      _json["paramReference"] = _value;
+    }
+  }
+
+  void set typeArguments(List<UnlinkedTypeRefBuilder> _value) {
+    assert(!_json.containsKey("typeArguments"));
+    if (_value != null || _value.isEmpty) {
+      _json["typeArguments"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  Map finish() => _json;
+}
+
+UnlinkedTypeRefBuilder encodeUnlinkedTypeRef(builder.BuilderContext builderContext, {int reference, int paramReference, List<UnlinkedTypeRefBuilder> typeArguments}) {
+  UnlinkedTypeRefBuilder builder = new UnlinkedTypeRefBuilder(builderContext);
+  builder.reference = reference;
+  builder.paramReference = paramReference;
+  builder.typeArguments = typeArguments;
+  return builder;
+}
+
+class UnlinkedUnit {
+  String _uri;
+
+  UnlinkedUnit.fromJson(Map json)
+    : _uri = json["uri"];
+
+  String get uri => _uri ?? '';
+}
+
+class UnlinkedUnitBuilder {
+  final Map _json = {};
+
+  UnlinkedUnitBuilder(builder.BuilderContext context);
+
+  void set uri(String _value) {
+    assert(!_json.containsKey("uri"));
+    if (_value != null) {
+      _json["uri"] = _value;
+    }
+  }
+
+  Map finish() => _json;
+}
+
+UnlinkedUnitBuilder encodeUnlinkedUnit(builder.BuilderContext builderContext, {String uri}) {
+  UnlinkedUnitBuilder builder = new UnlinkedUnitBuilder(builderContext);
+  builder.uri = uri;
+  return builder;
+}
+
+class UnlinkedVariable {
+  String _name;
+  int _unit;
+  UnlinkedTypeRef _type;
+  bool _isStatic;
+  bool _isFinal;
+  bool _isConst;
+
+  UnlinkedVariable.fromJson(Map json)
+    : _name = json["name"],
+      _unit = json["unit"],
+      _type = json["type"] == null ? null : new UnlinkedTypeRef.fromJson(json["type"]),
+      _isStatic = json["isStatic"],
+      _isFinal = json["isFinal"],
+      _isConst = json["isConst"];
+
+  String get name => _name ?? '';
+  int get unit => _unit ?? 0;
+  UnlinkedTypeRef get type => _type;
+  bool get isStatic => _isStatic ?? false;
+  bool get isFinal => _isFinal ?? false;
+  bool get isConst => _isConst ?? false;
+}
+
+class UnlinkedVariableBuilder {
+  final Map _json = {};
+
+  UnlinkedVariableBuilder(builder.BuilderContext context);
+
+  void set name(String _value) {
+    assert(!_json.containsKey("name"));
+    if (_value != null) {
+      _json["name"] = _value;
+    }
+  }
+
+  void set unit(int _value) {
+    assert(!_json.containsKey("unit"));
+    if (_value != null) {
+      _json["unit"] = _value;
+    }
+  }
+
+  void set type(UnlinkedTypeRefBuilder _value) {
+    assert(!_json.containsKey("type"));
+    if (_value != null) {
+      _json["type"] = _value.finish();
+    }
+  }
+
+  void set isStatic(bool _value) {
+    assert(!_json.containsKey("isStatic"));
+    if (_value != null) {
+      _json["isStatic"] = _value;
+    }
+  }
+
+  void set isFinal(bool _value) {
+    assert(!_json.containsKey("isFinal"));
+    if (_value != null) {
+      _json["isFinal"] = _value;
+    }
+  }
+
+  void set isConst(bool _value) {
+    assert(!_json.containsKey("isConst"));
+    if (_value != null) {
+      _json["isConst"] = _value;
+    }
+  }
+
+  Map finish() => _json;
+}
+
+UnlinkedVariableBuilder encodeUnlinkedVariable(builder.BuilderContext builderContext, {String name, int unit, UnlinkedTypeRefBuilder type, bool isStatic, bool isFinal, bool isConst}) {
+  UnlinkedVariableBuilder builder = new UnlinkedVariableBuilder(builderContext);
+  builder.name = name;
+  builder.unit = unit;
+  builder.type = type;
+  builder.isStatic = isStatic;
+  builder.isFinal = isFinal;
+  builder.isConst = isConst;
+  return builder;
+}
+
diff --git a/pkg/analyzer/lib/src/summary/summarize_elements.dart b/pkg/analyzer/lib/src/summary/summarize_elements.dart
new file mode 100644
index 0000000..79a73a3
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary/summarize_elements.dart
@@ -0,0 +1,625 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library serialization.elements;
+
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/summary/builder.dart';
+import 'package:analyzer/src/summary/format.dart';
+
+/**
+ * Serialize all the elements in [lib] to a summary using [ctx] as the context
+ * for building the summary, and using [typeProvider] to find built-in types.
+ */
+PrelinkedLibraryBuilder serializeLibrary(
+    BuilderContext ctx, LibraryElement lib, TypeProvider typeProvider) {
+  return new _LibrarySerializer(ctx, lib, typeProvider).serializeLibrary();
+}
+
+/**
+ * Instances of this class keep track of intermediate state during
+ * serialization of a single library.`
+ */
+class _LibrarySerializer {
+  /**
+   * The library to be serialized.
+   */
+  final LibraryElement libraryElement;
+
+  /**
+   * The type provider.  This is used to locate the library for `dart:core`.
+   */
+  final TypeProvider typeProvider;
+
+  /**
+   * List of objects which should be written to [UnlinkedLibrary.classes].
+   */
+  final List<UnlinkedClassBuilder> classes = <UnlinkedClassBuilder>[];
+
+  /**
+   * List of objects which should be written to [UnlinkedLibrary.enums].
+   */
+  final List<UnlinkedEnumBuilder> enums = <UnlinkedEnumBuilder>[];
+
+  /**
+   * List of objects which should be written to [UnlinkedLibrary.executables].
+   */
+  final List<UnlinkedExecutableBuilder> executables =
+      <UnlinkedExecutableBuilder>[];
+
+  /**
+   * List of objects which should be written to [UnlinkedLibrary.typedefs].
+   */
+  final List<UnlinkedTypedefBuilder> typedefs = <UnlinkedTypedefBuilder>[];
+
+  /**
+   * List of objects which should be written to [UnlinkedLibrary.units].
+   */
+  final List<UnlinkedUnitBuilder> units = <UnlinkedUnitBuilder>[];
+
+  /**
+   * List of objects which should be written to [UnlinkedLibrary.variables].
+   */
+  final List<UnlinkedVariableBuilder> variables = <UnlinkedVariableBuilder>[];
+
+  /**
+   * Map from [LibraryElement] to the index of the entry in the "dependency
+   * table" that refers to it.
+   */
+  final Map<LibraryElement, int> dependencyMap = <LibraryElement, int>{};
+
+  /**
+   * The "dependency table".  This is the list of objects which should be
+   * written to [PrelinkedLibrary.dependencies].
+   */
+  final List<PrelinkedDependencyBuilder> dependencies =
+      <PrelinkedDependencyBuilder>[];
+
+  /**
+   * The unlinked portion of the "imports table".  This is the list of objects
+   * which should be written to [UnlinkedLibrary.imports].
+   */
+  final List<UnlinkedImportBuilder> unlinkedImports = <UnlinkedImportBuilder>[];
+
+  /**
+   * The prelinked portion of the "imports table".  This is the list of ints
+   * which should be written to [PrelinkedLibrary.imports].
+   */
+  final List<int> prelinkedImports = <int>[];
+
+  /**
+   * Map from prefix [String] to the index of the entry in the "prefix" table
+   * that refers to it.  The empty prefix is not included in this map.
+   */
+  final Map<String, int> prefixMap = <String, int>{};
+
+  /**
+   * The "prefix table".  This is the list of objects which should be written
+   * to [UnlinkedLibrary.prefixes].
+   */
+  final List<UnlinkedPrefixBuilder> prefixes = <UnlinkedPrefixBuilder>[];
+
+  /**
+   * Map from [Element] to the index of the entry in the "references table"
+   * that refers to it.
+   */
+  final Map<Element, int> referenceMap = <Element, int>{};
+
+  /**
+   * The unlinked portion of the "references table".  This is the list of
+   * objects which should be written to [UnlinkedLibrary.references].
+   */
+  final List<UnlinkedReferenceBuilder> unlinkedReferences =
+      <UnlinkedReferenceBuilder>[];
+
+  /**
+   * The prelinked portion of the "references table".  This is the list of
+   * objects which should be written to [PrelinkedLibrary.references].
+   */
+  final List<PrelinkedReferenceBuilder> prelinkedReferences =
+      <PrelinkedReferenceBuilder>[];
+
+  //final Map<String, int> prefixIndices = <String, int>{};
+
+  /**
+   * Index into the "references table" representing `dynamic`, if such an index
+   * exists.  `null` if no such entry has been made in the references table
+   * yet.
+   */
+  int dynamicReferenceIndex = null;
+
+  /**
+   * Index into the "references table" representing an unresolved reference, if
+   * such an index exists.  `null` if no such entry has been made in the
+   * references table yet.
+   */
+  int unresolvedReferenceIndex = null;
+
+  /**
+   * Set of libraries which have been seen so far while visiting the transitive
+   * closure of exports.
+   */
+  final Set<LibraryElement> librariesAddedToTransitiveExportClosure =
+      new Set<LibraryElement>();
+
+  /**
+   * [BuilderContext] used to serialize the output summary.
+   */
+  final BuilderContext ctx;
+
+  _LibrarySerializer(this.ctx, this.libraryElement, this.typeProvider) {
+    dependencies.add(encodePrelinkedDependency(ctx));
+    dependencyMap[libraryElement] = 0;
+    prefixes.add(encodeUnlinkedPrefix(ctx));
+  }
+
+  /**
+   * Retrieve the library element for `dart:core`.
+   */
+  LibraryElement get coreLibrary => typeProvider.objectType.element.library;
+
+  /**
+   * Add all classes, enums, typedefs, executables, and top level variables
+   * from the given compilation unit [element] to the library summary.
+   * [unitNum] indicates the ordinal position of this compilation unit in the
+   * library.
+   */
+  void addCompilationUnitElements(CompilationUnitElement element, int unitNum) {
+    UnlinkedUnitBuilder b = new UnlinkedUnitBuilder(ctx);
+    if (element.uri != null) {
+      b.uri = element.uri;
+    }
+    units.add(b);
+    for (ClassElement cls in element.types) {
+      classes.add(serializeClass(cls, unitNum));
+    }
+    for (ClassElement e in element.enums) {
+      enums.add(serializeEnum(e, unitNum));
+    }
+    for (FunctionTypeAliasElement type in element.functionTypeAliases) {
+      typedefs.add(serializeTypedef(type, unitNum));
+    }
+    for (FunctionElement executable in element.functions) {
+      executables.add(serializeExecutable(executable, unitNum));
+    }
+    for (PropertyAccessorElement accessor in element.accessors) {
+      if (!accessor.isSynthetic) {
+        executables.add(serializeExecutable(accessor, unitNum));
+      } else if (accessor.isGetter) {
+        PropertyInducingElement variable = accessor.variable;
+        if (variable != null) {
+          assert(!variable.isSynthetic);
+          variables.add(serializeVariable(variable, unitNum));
+        }
+      }
+    }
+  }
+
+  /**
+   * Add [exportedLibrary] (and the transitive closure of all libraries it
+   * exports) to the dependency table ([PrelinkedLibrary.dependencies]).
+   */
+  void addTransitiveExportClosure(LibraryElement exportedLibrary) {
+    if (librariesAddedToTransitiveExportClosure.add(exportedLibrary)) {
+      serializeDependency(exportedLibrary);
+      for (LibraryElement transitiveExport
+          in exportedLibrary.exportedLibraries) {
+        addTransitiveExportClosure(transitiveExport);
+      }
+    }
+  }
+
+  /**
+   * Compute the appropriate De Bruijn index to represent the given type
+   * parameter [type].
+   */
+  int findTypeParameterIndex(TypeParameterType type, Element context) {
+    int index = 0;
+    while (context != null) {
+      List<TypeParameterElement> typeParameters;
+      if (context is ClassElement) {
+        typeParameters = context.typeParameters;
+      } else if (context is FunctionTypeAliasElement) {
+        typeParameters = context.typeParameters;
+      } else if (context is ExecutableElement) {
+        typeParameters = context.typeParameters;
+      }
+      if (typeParameters != null) {
+        for (int i = 0; i < typeParameters.length; i++) {
+          TypeParameterElement param = typeParameters[i];
+          if (param == type.element) {
+            return index + typeParameters.length - i;
+          }
+        }
+        index += typeParameters.length;
+      }
+      context = context.enclosingElement;
+    }
+    throw new StateError('Unbound type parameter $type');
+  }
+
+  /**
+   * Serialize the given [classElement], which exists in the unit numbered
+   * [unitNum], creating an [UnlinkedClass].
+   */
+  UnlinkedClassBuilder serializeClass(ClassElement classElement, int unitNum) {
+    UnlinkedClassBuilder b = new UnlinkedClassBuilder(ctx);
+    b.name = classElement.name;
+    b.unit = unitNum;
+    b.typeParameters =
+        classElement.typeParameters.map(serializeTypeParam).toList();
+    if (classElement.supertype != null && !classElement.supertype.isObject) {
+      b.supertype = serializeTypeRef(classElement.supertype, classElement);
+    }
+    b.mixins = classElement.mixins
+        .map((InterfaceType t) => serializeTypeRef(t, classElement))
+        .toList();
+    b.interfaces = classElement.interfaces
+        .map((InterfaceType t) => serializeTypeRef(t, classElement))
+        .toList();
+    List<UnlinkedVariableBuilder> fields = <UnlinkedVariableBuilder>[];
+    List<UnlinkedExecutableBuilder> executables = <UnlinkedExecutableBuilder>[];
+    for (ConstructorElement executable in classElement.constructors) {
+      if (!executable.isSynthetic) {
+        executables.add(serializeExecutable(executable, 0));
+      }
+    }
+    for (MethodElement executable in classElement.methods) {
+      executables.add(serializeExecutable(executable, 0));
+    }
+    for (PropertyAccessorElement accessor in classElement.accessors) {
+      if (!accessor.isSynthetic) {
+        executables.add(serializeExecutable(accessor, 0));
+      } else if (accessor.isGetter) {
+        PropertyInducingElement field = accessor.variable;
+        if (field != null && !field.isSynthetic) {
+          fields.add(serializeVariable(field, 0));
+        }
+      }
+    }
+    b.fields = fields;
+    b.executables = executables;
+    b.isAbstract = classElement.isAbstract;
+    b.isMixinApplication = classElement.isMixinApplication;
+    return b;
+  }
+
+  /**
+   * Serialize the given [combinator] into an [UnlinkedCombinator].
+   */
+  UnlinkedCombinatorBuilder serializeCombinator(
+      NamespaceCombinator combinator) {
+    UnlinkedCombinatorBuilder b = new UnlinkedCombinatorBuilder(ctx);
+    if (combinator is ShowElementCombinator) {
+      b.shows = combinator.shownNames.map(serializeCombinatorName).toList();
+    } else if (combinator is HideElementCombinator) {
+      b.hides = combinator.hiddenNames.map(serializeCombinatorName).toList();
+    }
+    return b;
+  }
+
+  /**
+   * Serialize the given [name] into an [UnlinkedCombinatorName].
+   */
+  UnlinkedCombinatorNameBuilder serializeCombinatorName(String name) {
+    return encodeUnlinkedCombinatorName(ctx, name: name);
+  }
+
+  /**
+   * Return the index of the entry in the dependency table
+   * ([PrelinkedLibrary.dependencies]) for the given [dependentLibrary].  A new
+   * entry is added to the table if necessary to satisfy the request.
+   */
+  int serializeDependency(LibraryElement dependentLibrary) {
+    return dependencyMap.putIfAbsent(dependentLibrary, () {
+      int index = dependencies.length;
+      dependencies.add(encodePrelinkedDependency(ctx,
+          uri: dependentLibrary.source.uri.toString()));
+      return index;
+    });
+  }
+
+  /**
+   * Return the index of the entry in the references table
+   * ([UnlinkedLibrary.references] and [PrelinkedLibrary.references])
+   * representing the pseudo-type `dynamic`.  A new entry is added to the table
+   * if necessary to satisfy the request.
+   */
+  int serializeDynamicReference() {
+    if (dynamicReferenceIndex == null) {
+      assert(unlinkedReferences.length == prelinkedReferences.length);
+      dynamicReferenceIndex = unlinkedReferences.length;
+      unlinkedReferences.add(encodeUnlinkedReference(ctx));
+      prelinkedReferences.add(encodePrelinkedReference(ctx,
+          kind: PrelinkedReferenceKind.classOrEnum));
+    }
+    return dynamicReferenceIndex;
+  }
+
+  /**
+   * Serialize the given [enumElement], which exists in the unit numbered
+   * [unitNum], creating an [UnlinkedEnum].
+   */
+  UnlinkedEnumBuilder serializeEnum(ClassElement enumElement, int unitNum) {
+    UnlinkedEnumBuilder b = new UnlinkedEnumBuilder(ctx);
+    b.name = enumElement.name;
+    List<UnlinkedEnumValueBuilder> values = <UnlinkedEnumValueBuilder>[];
+    for (FieldElement field in enumElement.fields) {
+      if (field.isConst && field.type.element == enumElement) {
+        values.add(encodeUnlinkedEnumValue(ctx, name: field.name));
+      }
+    }
+    b.values = values;
+    b.unit = unitNum;
+    return b;
+  }
+
+  /**
+   * Serialize the given [executableElement], which exists in the unit numbered
+   * [unitNum], creating an [UnlinkedExecutable].  For elements declared inside
+   * a class, [unitNum] should be zero.
+   */
+  UnlinkedExecutableBuilder serializeExecutable(
+      ExecutableElement executableElement, int unitNum) {
+    if (executableElement.enclosingElement is ClassElement) {
+      assert(unitNum == 0);
+    }
+    UnlinkedExecutableBuilder b = new UnlinkedExecutableBuilder(ctx);
+    b.name = executableElement.name;
+    b.unit = unitNum;
+    if (!executableElement.type.returnType.isVoid) {
+      b.returnType = serializeTypeRef(
+          executableElement.type.returnType, executableElement);
+    }
+    b.typeParameters =
+        executableElement.typeParameters.map(serializeTypeParam).toList();
+    b.parameters =
+        executableElement.type.parameters.map(serializeParam).toList();
+    if (executableElement is PropertyAccessorElement) {
+      if (executableElement.isGetter) {
+        b.kind = UnlinkedExecutableKind.getter;
+      } else {
+        b.kind = UnlinkedExecutableKind.setter;
+      }
+    } else if (executableElement is ConstructorElement) {
+      b.kind = UnlinkedExecutableKind.constructor;
+      b.isConst = executableElement.isConst;
+      b.isFactory = executableElement.isFactory;
+    } else {
+      b.kind = UnlinkedExecutableKind.functionOrMethod;
+    }
+    b.isAbstract = executableElement.isAbstract;
+    b.isStatic = executableElement.isStatic &&
+        executableElement.enclosingElement is ClassElement;
+    return b;
+  }
+
+  /**
+   * Serialize the given [exportElement] into an [UnlinkedExport].
+   */
+  UnlinkedExportBuilder serializeExport(ExportElement exportElement) {
+    UnlinkedExportBuilder b = new UnlinkedExportBuilder(ctx);
+    b.uri = exportElement.uri;
+    b.combinators = exportElement.combinators.map(serializeCombinator).toList();
+    return b;
+  }
+
+  /**
+   * Serialize the given [importElement], adding information about it to
+   * the [unlinkedImports] and [prelinkedImports] lists.
+   */
+  void serializeImport(ImportElement importElement) {
+    assert(unlinkedImports.length == prelinkedImports.length);
+    UnlinkedImportBuilder b = new UnlinkedImportBuilder(ctx);
+    b.isDeferred = importElement.isDeferred;
+    b.offset = importElement.nameOffset;
+    b.combinators = importElement.combinators.map(serializeCombinator).toList();
+    if (importElement.prefix != null) {
+      b.prefix = prefixMap.putIfAbsent(importElement.prefix.name, () {
+        int index = prefixes.length;
+        prefixes
+            .add(encodeUnlinkedPrefix(ctx, name: importElement.prefix.name));
+        return index;
+      });
+    }
+    if (importElement.isSynthetic) {
+      b.isImplicit = true;
+    } else {
+      b.uri = importElement.uri;
+    }
+    addTransitiveExportClosure(importElement.importedLibrary);
+    unlinkedImports.add(b);
+    prelinkedImports.add(serializeDependency(importElement.importedLibrary));
+  }
+
+  /**
+   * Serialize the whole library element into a [PrelinkedLibrary].  Should be
+   * called exactly once for each instance of [_LibrarySerializer].
+   */
+  PrelinkedLibraryBuilder serializeLibrary() {
+    UnlinkedLibraryBuilder ub = new UnlinkedLibraryBuilder(ctx);
+    PrelinkedLibraryBuilder pb = new PrelinkedLibraryBuilder(ctx);
+    if (libraryElement.name.isNotEmpty) {
+      ub.name = libraryElement.name;
+    }
+    for (ImportElement importElement in libraryElement.imports) {
+      serializeImport(importElement);
+    }
+    ub.exports = libraryElement.exports.map(serializeExport).toList();
+    addCompilationUnitElements(libraryElement.definingCompilationUnit, 0);
+    for (int i = 0; i < libraryElement.parts.length; i++) {
+      addCompilationUnitElements(libraryElement.parts[i], i + 1);
+    }
+    ub.classes = classes;
+    ub.enums = enums;
+    ub.executables = executables;
+    ub.imports = unlinkedImports;
+    ub.prefixes = prefixes;
+    ub.references = unlinkedReferences;
+    ub.typedefs = typedefs;
+    ub.units = units;
+    ub.variables = variables;
+    pb.unlinked = ub;
+    pb.dependencies = dependencies;
+    pb.importDependencies = prelinkedImports;
+    pb.references = prelinkedReferences;
+    return pb;
+  }
+
+  /**
+   * Serialize the given [parameter] into an [UnlinkedParam].
+   */
+  UnlinkedParamBuilder serializeParam(ParameterElement parameter) {
+    UnlinkedParamBuilder b = new UnlinkedParamBuilder(ctx);
+    b.name = parameter.name;
+    switch (parameter.parameterKind) {
+      case ParameterKind.REQUIRED:
+        b.kind = UnlinkedParamKind.required;
+        break;
+      case ParameterKind.POSITIONAL:
+        b.kind = UnlinkedParamKind.positional;
+        break;
+      case ParameterKind.NAMED:
+        b.kind = UnlinkedParamKind.named;
+        break;
+    }
+    b.isInitializingFormal = parameter.isInitializingFormal;
+    DartType type = parameter.type;
+    if (type is FunctionType) {
+      b.isFunctionTyped = true;
+      if (!type.returnType.isVoid) {
+        b.type = serializeTypeRef(type.returnType, parameter);
+      }
+      b.parameters = type.parameters.map(serializeParam).toList();
+    } else {
+      b.type = serializeTypeRef(type, parameter);
+    }
+    return b;
+  }
+
+  /**
+   * Serialize the given [typedefElement], which exists in the unit numbered
+   * [unitNum], creating an [UnlinkedTypedef].
+   */
+  UnlinkedTypedefBuilder serializeTypedef(
+      FunctionTypeAliasElement typedefElement, int unitNum) {
+    UnlinkedTypedefBuilder b = new UnlinkedTypedefBuilder(ctx);
+    b.name = typedefElement.name;
+    b.unit = unitNum;
+    b.typeParameters =
+        typedefElement.typeParameters.map(serializeTypeParam).toList();
+    if (!typedefElement.returnType.isVoid) {
+      b.returnType =
+          serializeTypeRef(typedefElement.returnType, typedefElement);
+    }
+    b.parameters = typedefElement.parameters.map(serializeParam).toList();
+    return b;
+  }
+
+  /**
+   * Serialize the given [typeParameter] into an [UnlinkedTypeParam].
+   */
+  UnlinkedTypeParamBuilder serializeTypeParam(
+      TypeParameterElement typeParameter) {
+    UnlinkedTypeParamBuilder b = new UnlinkedTypeParamBuilder(ctx);
+    b.name = typeParameter.name;
+    if (typeParameter.bound != null) {
+      b.bound = serializeTypeRef(typeParameter.bound, typeParameter);
+    }
+    return b;
+  }
+
+  /**
+   * Serialize the given [type] into an [UnlinkedTypeRef].
+   */
+  UnlinkedTypeRefBuilder serializeTypeRef(DartType type, Element context) {
+    UnlinkedTypeRefBuilder b = new UnlinkedTypeRefBuilder(ctx);
+    if (type is TypeParameterType) {
+      Element enclosingElement = type.element.enclosingElement;
+      b.paramReference = findTypeParameterIndex(type, context);
+    } else {
+      Element element = type.element;
+      CompilationUnitElement dependentCompilationUnit =
+          element.getAncestor((Element e) => e is CompilationUnitElement);
+      LibraryElement dependentLibrary = element.library;
+      if (dependentLibrary == null) {
+        assert(type.isDynamic);
+        if (type is UndefinedTypeImpl) {
+          b.reference = serializeUnresolvedReference();
+        } else {
+          b.reference = serializeDynamicReference();
+        }
+      } else {
+        b.reference = referenceMap.putIfAbsent(element, () {
+          assert(unlinkedReferences.length == prelinkedReferences.length);
+          int index = unlinkedReferences.length;
+          // TODO(paulberry): set UnlinkedReference.prefix.
+          unlinkedReferences
+              .add(encodeUnlinkedReference(ctx, name: element.name));
+          prelinkedReferences.add(encodePrelinkedReference(ctx,
+              dependency: serializeDependency(dependentLibrary),
+              kind: element is FunctionTypeAliasElement
+                  ? PrelinkedReferenceKind.typedef
+                  : PrelinkedReferenceKind.classOrEnum));
+          return index;
+        });
+      }
+      List<DartType> typeArguments;
+      if (type is InterfaceType) {
+        typeArguments = type.typeArguments;
+      } else if (type is FunctionType) {
+        typeArguments = type.typeArguments;
+      }
+      if (typeArguments != null &&
+          typeArguments.any((DartType argument) => !argument.isDynamic)) {
+        b.typeArguments = typeArguments
+            .map((DartType t) => serializeTypeRef(t, context))
+            .toList();
+      }
+    }
+    return b;
+  }
+
+  /**
+   * Return the index of the entry in the references table
+   * ([UnlinkedLibrary.references] and [PrelinkedLibrary.references]) used for
+   * unresolved references.  A new entry is added to the table if necessary to
+   * satisfy the request.
+   */
+  int serializeUnresolvedReference() {
+    // TODO(paulberry): in order for relinking to work, we need to record the
+    // name and prefix of the unresolved symbol.  This is not (yet) encoded in
+    // the element model.
+    if (unresolvedReferenceIndex == null) {
+      assert(unlinkedReferences.length == prelinkedReferences.length);
+      unresolvedReferenceIndex = unlinkedReferences.length;
+      unlinkedReferences.add(encodeUnlinkedReference(ctx));
+      prelinkedReferences.add(encodePrelinkedReference(ctx,
+          kind: PrelinkedReferenceKind.unresolved));
+    }
+    return unresolvedReferenceIndex;
+  }
+
+  /**
+   * Serialize the given [variable], which exists in the unit numbered
+   * [unitNum], creating an [UnlinkedVariable].  For variables declared inside
+   * a class (i.e. fields), [unitNum] should be zero.
+   */
+  UnlinkedVariableBuilder serializeVariable(
+      PropertyInducingElement variable, int unitNum) {
+    if (variable.enclosingElement is ClassElement) {
+      assert(unitNum == 0);
+    }
+    UnlinkedVariableBuilder b = new UnlinkedVariableBuilder(ctx);
+    b.name = variable.name;
+    b.unit = unitNum;
+    b.type = serializeTypeRef(variable.type, variable);
+    b.isStatic = variable.isStatic && variable.enclosingElement is ClassElement;
+    b.isFinal = variable.isFinal;
+    b.isConst = variable.isConst;
+    return b;
+  }
+}
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index 9eca05f..2aae1a1 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -2144,11 +2144,19 @@
       String inputName = result.name + '_input';
       errorLists.add(getRequiredInput(inputName));
     }
+
+    //
+    // Gather error filters.
+    //
+    List<ErrorFilter> filters =
+        context.getConfigurationData(CONFIGURED_ERROR_FILTERS);
     for (ResultDescriptor result in enginePlugin.dartErrorsForUnit) {
       String inputName = result.name + '_input';
       Map<Source, List<AnalysisError>> errorMap = getRequiredInput(inputName);
       for (List<AnalysisError> errors in errorMap.values) {
-        errorLists.add(errors);
+        errorLists.add(errors.where((AnalysisError error) {
+          return !filters.any((ErrorFilter filter) => filter(error));
+        }).toList());
       }
     }
     //
@@ -3251,6 +3259,7 @@
     AnalysisOptions options = context.analysisOptions;
     parser.parseFunctionBodies = options.analyzeFunctionBodiesPredicate(source);
     parser.parseGenericMethods = options.enableGenericMethods;
+    parser.parseGenericMethodComments = options.strongMode;
     CompilationUnit unit = parser.parseCompilationUnit(tokenStream);
     unit.lineInfo = lineInfo;
 
@@ -4429,6 +4438,7 @@
           errorListener);
       scanner.setSourceStart(fragment.line, fragment.column);
       scanner.preserveComments = context.analysisOptions.preserveComments;
+      scanner.scanGenericMethodComments = context.analysisOptions.strongMode;
 
       outputs[TOKEN_STREAM] = scanner.tokenize();
       outputs[LINE_INFO] = new LineInfo(scanner.lineStarts);
@@ -4439,6 +4449,7 @@
       Scanner scanner =
           new Scanner(source, new CharSequenceReader(content), errorListener);
       scanner.preserveComments = context.analysisOptions.preserveComments;
+      scanner.scanGenericMethodComments = context.analysisOptions.strongMode;
 
       outputs[TOKEN_STREAM] = scanner.tokenize();
       outputs[LINE_INFO] = new LineInfo(scanner.lineStarts);
diff --git a/pkg/analyzer/lib/src/task/driver.dart b/pkg/analyzer/lib/src/task/driver.dart
index c6abda8..43565f3 100644
--- a/pkg/analyzer/lib/src/task/driver.dart
+++ b/pkg/analyzer/lib/src/task/driver.dart
@@ -168,7 +168,8 @@
     }
     TaskDescriptor taskDescriptor = taskManager.findTask(target, result);
     try {
-      WorkItem workItem = new WorkItem(context, target, taskDescriptor, result);
+      WorkItem workItem =
+          new WorkItem(context, target, taskDescriptor, result, null);
       return new WorkOrder(taskManager, workItem);
     } catch (exception, stackTrace) {
       throw new AnalysisException(
@@ -530,21 +531,6 @@
  */
 class WorkItem {
   /**
-   * A table mapping the names of analysis tasks to the number of times each
-   * kind of task has been performed.
-   */
-  static final Map<TaskDescriptor, int> countMap =
-      new HashMap<TaskDescriptor, int>();
-
-  /**
-   * A table mapping the names of analysis tasks to stopwatches used to compute
-   * how much time was spent between creating an item and creating (for
-   * performing) of each kind of task
-   */
-  static final Map<TaskDescriptor, Stopwatch> stopwatchMap =
-      new HashMap<TaskDescriptor, Stopwatch>();
-
-  /**
    * The context in which the task will be performed.
    */
   final InternalAnalysisContext context;
@@ -565,9 +551,9 @@
   final ResultDescriptor spawningResult;
 
   /**
-   * The current inputs computing stopwatch.
+   * The work order that this item is part of, may be `null`.
    */
-  Stopwatch stopwatch;
+  WorkOrder workOrder;
 
   /**
    * An iterator used to iterate over the descriptors of the inputs to the task,
@@ -607,7 +593,8 @@
    * Initialize a newly created work item to compute the inputs for the task
    * described by the given descriptor.
    */
-  WorkItem(this.context, this.target, this.descriptor, this.spawningResult) {
+  WorkItem(this.context, this.target, this.descriptor, this.spawningResult,
+      this.workOrder) {
     AnalysisTarget actualTarget =
         identical(target, AnalysisContextTarget.request)
             ? new AnalysisContextTarget(context)
@@ -619,19 +606,6 @@
       builder = null;
     }
     inputs = new HashMap<String, dynamic>();
-    // Update performance counters.
-    {
-      stopwatch = stopwatchMap[descriptor];
-      if (stopwatch == null) {
-        stopwatch = new Stopwatch();
-        stopwatchMap[descriptor] = stopwatch;
-      }
-      stopwatch.start();
-    }
-    {
-      int count = countMap[descriptor];
-      countMap[descriptor] = count == null ? 1 : count + 1;
-    }
   }
 
   @override
@@ -651,7 +625,6 @@
    * Build the task represented by this work item.
    */
   AnalysisTask buildTask() {
-    stopwatch.stop();
     if (builder != null) {
       throw new StateError("some inputs have not been computed");
     }
@@ -680,6 +653,25 @@
     while (builder != null) {
       AnalysisTarget inputTarget = builder.currentTarget;
       ResultDescriptor inputResult = builder.currentResult;
+
+      // TODO(scheglov) record information to debug
+      // https://github.com/dart-lang/sdk/issues/24939
+      if (inputTarget == null || inputResult == null) {
+        try {
+          String message =
+              'Invalid input descriptor ($inputTarget, $inputResult) for $this';
+          if (workOrder != null) {
+            message += '\nPath:\n' + workOrder.workItems.join('|\n');
+          }
+          throw new AnalysisException(message);
+        } catch (exception, stackTrace) {
+          this.exception = new CaughtException(exception, stackTrace);
+          AnalysisEngine.instance.logger
+              .logError('Task failed: $this', this.exception);
+        }
+        return null;
+      }
+
       inputTargetedResults.add(new TargetedResult(inputTarget, inputResult));
       CacheEntry inputEntry = context.getCacheEntry(inputTarget);
       CacheState inputState = inputEntry.getState(inputResult);
@@ -708,7 +700,8 @@
         try {
           TaskDescriptor descriptor =
               taskManager.findTask(inputTarget, inputResult);
-          return new WorkItem(context, inputTarget, descriptor, inputResult);
+          return new WorkItem(
+              context, inputTarget, descriptor, inputResult, workOrder);
         } on AnalysisException catch (exception, stackTrace) {
           this.exception = new CaughtException(exception, stackTrace);
           return null;
@@ -756,7 +749,9 @@
    * the given work item.
    */
   WorkOrder(TaskManager taskManager, WorkItem item)
-      : _dependencyWalker = new _WorkOrderDependencyWalker(taskManager, item);
+      : _dependencyWalker = new _WorkOrderDependencyWalker(taskManager, item) {
+    item.workOrder = this;
+  }
 
   @override
   WorkItem get current {
diff --git a/pkg/analyzer/lib/src/task/html.dart b/pkg/analyzer/lib/src/task/html.dart
index b603f1f..219e1ee 100644
--- a/pkg/analyzer/lib/src/task/html.dart
+++ b/pkg/analyzer/lib/src/task/html.dart
@@ -360,12 +360,7 @@
    * Compute [LineInfo] for the given [content].
    */
   static LineInfo _computeLineInfo(String content) {
-    List<int> lineStarts = <int>[0];
-    for (int index = 0; index < content.length; index++) {
-      if (content.codeUnitAt(index) == 0x0A) {
-        lineStarts.add(index + 1);
-      }
-    }
+    List<int> lineStarts = StringUtilities.computeLineStarts(content);
     return new LineInfo(lineStarts);
   }
 }
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index 9f22f7f..45faf41 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.dart
@@ -8,7 +8,9 @@
 import 'package:analyzer/plugin/options.dart';
 import 'package:analyzer/source/analysis_options_provider.dart';
 import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_general.dart';
 import 'package:analyzer/src/task/general.dart';
 import 'package:analyzer/task/general.dart';
 import 'package:analyzer/task/model.dart';
@@ -22,10 +24,59 @@
     new ListResultDescriptor<AnalysisError>(
         'ANALYSIS_OPTIONS_ERRORS', AnalysisError.NO_ERRORS);
 
-/// Validates `analyzer` top-level options.
-class AnalyzerOptionsValidator extends TopLevelOptionValidator {
+final _OptionsProcessor _processor = new _OptionsProcessor();
+
+/// Configure this [context] based on configuration details specified in
+/// the given [options].
+void configureContextOptions(
+        AnalysisContext context, Map<String, YamlNode> options) =>
+    _processor.configure(context, options);
+
+/// `analyzer` analysis options constants.
+class AnalyzerOptions {
+  static const String analyzer = 'analyzer';
+  static const String enableGenericMethods = 'enableGenericMethods';
+  static const String enableSuperMixins = 'enableSuperMixins';
+  static const String errors = 'errors';
+  static const String exclude = 'exclude';
+  static const String language = 'language';
+  static const String plugins = 'plugins';
+  static const String strong_mode = 'strong-mode';
+
+  /// Ways to say `ignore`.
+  static const List<String> ignoreSynonyms = const ['ignore', 'false'];
+
+  /// Ways to say `include`.
+  static const List<String> includeSynonyms = const ['include', 'true'];
+
+  /// Ways to say `true` or `false`.
+  static const List<String> trueOrFalse = const ['true', 'false'];
+
+  /// Supported top-level `analyzer` options.
+  static const List<String> topLevel = const [
+    errors,
+    exclude,
+    language,
+    plugins,
+    strong_mode
+  ];
+
+  /// Supported `analyzer` language configuration options.
+  static const List<String> languageOptions = const [
+    enableGenericMethods,
+    enableSuperMixins
+  ];
+}
+
+/// Validates `analyzer` options.
+class AnalyzerOptionsValidator extends CompositeValidator {
   AnalyzerOptionsValidator()
-      : super('analyzer', const ['exclude', 'plugins', 'strong-mode']);
+      : super([
+          new TopLevelAnalyzerOptionsValidator(),
+          new StrongModeOptionValueValidator(),
+          new ErrorFilterOptionValidator(),
+          new LanguageOptionValidator()
+        ]);
 }
 
 /// Convenience class for composing validators.
@@ -38,6 +89,77 @@
       validators.forEach((v) => v.validate(reporter, options));
 }
 
+/// Builds error reports with value proposals.
+class ErrorBuilder {
+  String proposal;
+  AnalysisOptionsWarningCode code;
+
+  /// Create a builder for the given [supportedOptions].
+  ErrorBuilder(List<String> supportedOptions) {
+    assert(supportedOptions != null && !supportedOptions.isEmpty);
+    if (supportedOptions.length > 1) {
+      proposal = StringUtilities.printListOfQuotedNames(supportedOptions);
+      code = pluralProposalCode;
+    } else {
+      proposal = "'${supportedOptions.join()}'";
+      code = singularProposalCode;
+    }
+  }
+  AnalysisOptionsWarningCode get pluralProposalCode =>
+      AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES;
+
+  AnalysisOptionsWarningCode get singularProposalCode =>
+      AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE;
+
+  /// Report an unsupported [node] value, defined in the given [scopeName].
+  void reportError(ErrorReporter reporter, String scopeName, YamlNode node) {
+    reporter.reportErrorForSpan(
+        code, node.span, [scopeName, node.value, proposal]);
+  }
+}
+
+/// Validates `analyzer` error filter options.
+class ErrorFilterOptionValidator extends OptionsValidator {
+  /// Pretty list of legal includes.
+  static final String legalIncludes = StringUtilities.printListOfQuotedNames(
+      new List.from(AnalyzerOptions.ignoreSynonyms)
+        ..addAll(AnalyzerOptions.includeSynonyms));
+
+  @override
+  void validate(ErrorReporter reporter, Map<String, YamlNode> options) {
+    var analyzer = options[AnalyzerOptions.analyzer];
+    if (analyzer is! YamlMap) {
+      return;
+    }
+
+    var filters = analyzer[AnalyzerOptions.errors];
+    if (filters is YamlMap) {
+      String value;
+      filters.nodes.forEach((k, v) {
+        if (k is YamlScalar) {
+          value = toUpperCase(k.value);
+          if (!ErrorCode.values.any((ErrorCode code) => code.name == value)) {
+            reporter.reportErrorForSpan(
+                AnalysisOptionsWarningCode.UNRECOGNIZED_ERROR_CODE,
+                k.span,
+                [k.value?.toString()]);
+          }
+        }
+        if (v is YamlScalar) {
+          value = toLowerCase(v.value);
+          if (!AnalyzerOptions.ignoreSynonyms.contains(value) &&
+              !AnalyzerOptions.includeSynonyms.contains(value)) {
+            reporter.reportErrorForSpan(
+                AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES,
+                v.span,
+                [AnalyzerOptions.errors, v.value?.toString(), legalIncludes]);
+          }
+        }
+      });
+    }
+  }
+}
+
 /// A task that generates errors for an `.analysis_options` file.
 class GenerateOptionsErrorsTask extends SourceBasedAnalysisTask {
   /// The name of the input whose value is the content of the file.
@@ -81,7 +203,7 @@
     // Record outputs.
     //
     outputs[ANALYSIS_OPTIONS_ERRORS] = errors;
-    outputs[LINE_INFO] = _computeLineInfo(content);
+    outputs[LINE_INFO] = computeLineInfo(content);
   }
 
   List<AnalysisError> _validate(Map<String, YamlNode> options) =>
@@ -93,20 +215,52 @@
   static Map<String, TaskInput> buildInputs(Source source) =>
       <String, TaskInput>{CONTENT_INPUT_NAME: CONTENT.of(source)};
 
+  /// Compute [LineInfo] for the given [content].
+  static LineInfo computeLineInfo(String content) {
+    List<int> lineStarts = StringUtilities.computeLineStarts(content);
+    return new LineInfo(lineStarts);
+  }
+
   /// Create a task based on the given [target] in the given [context].
   static GenerateOptionsErrorsTask createTask(
           AnalysisContext context, AnalysisTarget target) =>
       new GenerateOptionsErrorsTask(context, target);
+}
 
-  /// Compute [LineInfo] for the given [content].
-  static LineInfo _computeLineInfo(String content) {
-    List<int> lineStarts = <int>[0];
-    for (int index = 0; index < content.length; index++) {
-      if (content.codeUnitAt(index) == 0x0A) {
-        lineStarts.add(index + 1);
-      }
+/// Validates `analyzer` language configuration options.
+class LanguageOptionValidator extends OptionsValidator {
+  ErrorBuilder builder = new ErrorBuilder(AnalyzerOptions.languageOptions);
+  ErrorBuilder trueOrFalseBuilder = new TrueOrFalseValueErrorBuilder();
+
+  @override
+  void validate(ErrorReporter reporter, Map<String, YamlNode> options) {
+    var analyzer = options[AnalyzerOptions.analyzer];
+    if (analyzer is! YamlMap) {
+      return;
     }
-    return new LineInfo(lineStarts);
+
+    var language = analyzer[AnalyzerOptions.language];
+    if (language is YamlMap) {
+      language.nodes.forEach((k, v) {
+        String key, value;
+        bool validKey = false;
+        if (k is YamlScalar) {
+          key = k.value?.toString();
+          if (!AnalyzerOptions.languageOptions.contains(key)) {
+            builder.reportError(reporter, AnalyzerOptions.language, k);
+          } else {
+            // If we have a valid key, go on and check the value.
+            validKey = true;
+          }
+        }
+        if (validKey && v is YamlScalar) {
+          value = toLowerCase(v.value);
+          if (!AnalyzerOptions.trueOrFalse.contains(value)) {
+            trueOrFalseBuilder.reportError(reporter, key, v);
+          }
+        }
+      });
+    }
   }
 }
 
@@ -137,14 +291,55 @@
   }
 }
 
+/// Validates `analyzer` strong-mode value configuration options.
+class StrongModeOptionValueValidator extends OptionsValidator {
+  ErrorBuilder trueOrFalseBuilder = new TrueOrFalseValueErrorBuilder();
+
+  @override
+  void validate(ErrorReporter reporter, Map<String, YamlNode> options) {
+    var analyzer = options[AnalyzerOptions.analyzer];
+    if (analyzer is! YamlMap) {
+      return;
+    }
+
+    var v = analyzer.nodes[AnalyzerOptions.strong_mode];
+    if (v is YamlScalar) {
+      var value = toLowerCase(v.value);
+      if (!AnalyzerOptions.trueOrFalse.contains(value)) {
+        trueOrFalseBuilder.reportError(
+            reporter, AnalyzerOptions.strong_mode, v);
+      }
+    }
+  }
+}
+
+/// Validates `analyzer` top-level options.
+class TopLevelAnalyzerOptionsValidator extends TopLevelOptionValidator {
+  TopLevelAnalyzerOptionsValidator()
+      : super(AnalyzerOptions.analyzer, AnalyzerOptions.topLevel);
+}
+
 /// Validates top-level options. For example,
 ///     plugin:
 ///       top-level-option: true
 class TopLevelOptionValidator extends OptionsValidator {
   final String pluginName;
   final List<String> supportedOptions;
+  String _valueProposal;
+  AnalysisOptionsWarningCode _warningCode;
+  TopLevelOptionValidator(this.pluginName, this.supportedOptions) {
+    assert(supportedOptions != null && !supportedOptions.isEmpty);
+    if (supportedOptions.length > 1) {
+      _valueProposal = StringUtilities.printListOfQuotedNames(supportedOptions);
+      _warningCode =
+          AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES;
+    } else {
+      _valueProposal = "'${supportedOptions.join()}'";
+      _warningCode =
+          AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE;
+    }
+  }
 
-  TopLevelOptionValidator(this.pluginName, this.supportedOptions);
   @override
   void validate(ErrorReporter reporter, Map<String, YamlNode> options) {
     YamlNode node = options[pluginName];
@@ -153,9 +348,7 @@
         if (k is YamlScalar) {
           if (!supportedOptions.contains(k.value)) {
             reporter.reportErrorForSpan(
-                AnalysisOptionsWarningCode.UNSUPPORTED_OPTION,
-                k.span,
-                [pluginName, k.value]);
+                _warningCode, k.span, [pluginName, k.value, _valueProposal]);
           }
         }
         //TODO(pq): consider an error if the node is not a Scalar.
@@ -163,3 +356,99 @@
     }
   }
 }
+
+/// An error-builder that knows about `true` and `false` legal values.
+class TrueOrFalseValueErrorBuilder extends ErrorBuilder {
+  TrueOrFalseValueErrorBuilder() : super(AnalyzerOptions.trueOrFalse);
+  @override
+  AnalysisOptionsWarningCode get pluralProposalCode =>
+      AnalysisOptionsWarningCode.UNSUPPORTED_VALUE;
+}
+
+class _OptionsProcessor {
+  void configure(AnalysisContext context, Map<String, YamlNode> options) {
+    if (options == null) {
+      return;
+    }
+
+    var analyzer = options[AnalyzerOptions.analyzer];
+    if (analyzer is! Map) {
+      return;
+    }
+
+    // Set strong mode (default is false).
+    var strongMode = analyzer[AnalyzerOptions.strong_mode];
+    setStrongMode(context, strongMode);
+
+    // Set filters.
+    var filters = analyzer[AnalyzerOptions.errors];
+    setFilters(context, filters);
+
+    // Process language options.
+    var language = analyzer[AnalyzerOptions.language];
+    setLanguageOptions(context, language);
+  }
+
+  void setFilters(AnalysisContext context, Object codes) {
+    List<ErrorFilter> filters = <ErrorFilter>[];
+    // If codes are enumerated, collect them as filters; else leave filters
+    // empty to overwrite previous value.
+    if (codes is YamlMap) {
+      String value;
+      codes.nodes.forEach((k, v) {
+        if (k is YamlScalar && v is YamlScalar) {
+          value = toLowerCase(v.value);
+          if (AnalyzerOptions.ignoreSynonyms.contains(value)) {
+            // Case-insensitive.
+            String code = toUpperCase(k.value);
+            filters.add((AnalysisError error) => error.errorCode.name == code);
+          }
+        }
+      });
+    }
+    context.setConfigurationData(CONFIGURED_ERROR_FILTERS, filters);
+  }
+
+  void setLanguageOption(
+      AnalysisContext context, Object feature, Object value) {
+    if (feature == AnalyzerOptions.enableSuperMixins) {
+      if (isTrue(value)) {
+        AnalysisOptionsImpl options =
+            new AnalysisOptionsImpl.from(context.analysisOptions);
+        options.enableSuperMixins = true;
+        context.analysisOptions = options;
+      }
+    }
+    if (feature == AnalyzerOptions.enableGenericMethods) {
+      if (isTrue(value)) {
+        AnalysisOptionsImpl options =
+            new AnalysisOptionsImpl.from(context.analysisOptions);
+        options.enableGenericMethods = true;
+        context.analysisOptions = options;
+      }
+    }
+  }
+
+  void setLanguageOptions(AnalysisContext context, Object configs) {
+    if (configs is YamlMap) {
+      configs.nodes.forEach((k, v) {
+        if (k is YamlScalar && v is YamlScalar) {
+          String feature = k.value?.toString();
+          setLanguageOption(context, feature, v.value);
+        }
+      });
+    } else if (configs is Map) {
+      configs.forEach((k, v) => setLanguageOption(context, k, v));
+    }
+  }
+
+  void setStrongMode(AnalysisContext context, Object strongMode) {
+    bool strong = strongMode is bool ? strongMode : false;
+    if (context.analysisOptions.strongMode != strong) {
+      AnalysisOptionsImpl options =
+          new AnalysisOptionsImpl.from(context.analysisOptions);
+      options.strongMode = strong;
+      context.analysisOptions = options;
+    }
+  }
+}
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 9cfefe8..5a6bcaa 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -51,9 +51,10 @@
       var errorLocation = node.withClause.mixinTypes[i];
       for (int j = i - 1; j >= 0; j--) {
         _checkIndividualOverridesFromType(
-            current, mixins[j], errorLocation, seen);
+            current, mixins[j], errorLocation, seen, true);
       }
-      _checkIndividualOverridesFromType(current, parent, errorLocation, seen);
+      _checkIndividualOverridesFromType(
+          current, parent, errorLocation, seen, true);
     }
   }
 
@@ -85,9 +86,9 @@
     var visited = new Set<InterfaceType>();
     do {
       visited.add(current);
-      current.mixins.reversed
-          .forEach((m) => _checkIndividualOverridesFromClass(node, m, seen));
-      _checkIndividualOverridesFromClass(node, current.superclass, seen);
+      current.mixins.reversed.forEach(
+          (m) => _checkIndividualOverridesFromClass(node, m, seen, true));
+      _checkIndividualOverridesFromClass(node, current.superclass, seen, true);
       current = current.superclass;
     } while (!current.isObject && !visited.contains(current));
   }
@@ -171,10 +172,10 @@
     // Check direct overrides on [type]
     for (var interfaceType in interfaces) {
       if (node != null) {
-        _checkIndividualOverridesFromClass(node, interfaceType, seen);
+        _checkIndividualOverridesFromClass(node, interfaceType, seen, false);
       } else {
         _checkIndividualOverridesFromType(
-            type, interfaceType, errorLocation, seen);
+            type, interfaceType, errorLocation, seen, false);
       }
     }
 
@@ -186,7 +187,7 @@
         // We copy [seen] so we can report separately if more than one mixin or
         // the base class have an invalid override.
         _checkIndividualOverridesFromType(
-            type.mixins[i], interfaceType, loc, new Set.from(seen));
+            type.mixins[i], interfaceType, loc, new Set.from(seen), false);
       }
     }
 
@@ -212,12 +213,16 @@
   /// is used when invoking this function multiple times when checking several
   /// types in a class hierarchy. Errors are reported only the first time an
   /// invalid override involving a specific member is encountered.
-  _checkIndividualOverridesFromType(InterfaceType subType,
-      InterfaceType baseType, AstNode errorLocation, Set<String> seen) {
+  _checkIndividualOverridesFromType(
+      InterfaceType subType,
+      InterfaceType baseType,
+      AstNode errorLocation,
+      Set<String> seen,
+      bool isSubclass) {
     void checkHelper(ExecutableElement e) {
       if (e.isStatic) return;
       if (seen.contains(e.name)) return;
-      if (_checkSingleOverride(e, baseType, null, errorLocation)) {
+      if (_checkSingleOverride(e, baseType, null, errorLocation, isSubclass)) {
         seen.add(e.name);
       }
     }
@@ -230,8 +235,8 @@
   ///
   /// The [errorLocation] node indicates where errors are reported, see
   /// [_checkSingleOverride] for more details.
-  _checkIndividualOverridesFromClass(
-      ClassDeclaration node, InterfaceType baseType, Set<String> seen) {
+  _checkIndividualOverridesFromClass(ClassDeclaration node,
+      InterfaceType baseType, Set<String> seen, bool isSubclass) {
     for (var member in node.members) {
       if (member is ConstructorDeclaration) continue;
       if (member is FieldDeclaration) {
@@ -242,10 +247,12 @@
           if (seen.contains(name)) continue;
           var getter = element.getter;
           var setter = element.setter;
-          bool found = _checkSingleOverride(getter, baseType, variable, member);
+          bool found = _checkSingleOverride(
+              getter, baseType, variable, member, isSubclass);
           if (!variable.isFinal &&
               !variable.isConst &&
-              _checkSingleOverride(setter, baseType, variable, member)) {
+              _checkSingleOverride(
+                  setter, baseType, variable, member, isSubclass)) {
             found = true;
           }
           if (found) seen.add(name);
@@ -254,7 +261,8 @@
         if ((member as MethodDeclaration).isStatic) continue;
         var method = (member as MethodDeclaration).element;
         if (seen.contains(method.name)) continue;
-        if (_checkSingleOverride(method, baseType, member, member)) {
+        if (_checkSingleOverride(
+            method, baseType, member, member, isSubclass)) {
           seen.add(method.name);
         }
       }
@@ -288,14 +296,23 @@
   /// the AST node that defines [element]. This is used to determine whether the
   /// type of the element could be inferred from the types in the super classes.
   bool _checkSingleOverride(ExecutableElement element, InterfaceType type,
-      AstNode node, AstNode errorLocation) {
+      AstNode node, AstNode errorLocation, bool isSubclass) {
     assert(!element.isStatic);
 
     FunctionType subType = _rules.elementType(element);
     // TODO(vsm): Test for generic
     FunctionType baseType = _getMemberType(type, element);
-
     if (baseType == null) return false;
+
+    if (isSubclass && element is PropertyAccessorElement) {
+      // Disallow any overriding if the base class defines this member
+      // as a field.  We effectively treat fields as final / non-virtual.
+      PropertyInducingElement field = _getMemberField(type, element);
+      if (field != null) {
+        _recordMessage(new InvalidFieldOverride(
+            errorLocation, element, type, subType, baseType));
+      }
+    }
     if (!_rules.isAssignable(subType, baseType)) {
       // See whether non-assignable cases fit one of our common patterns:
       //
@@ -602,24 +619,22 @@
     node.visitChildren(this);
   }
 
-  @override
-  void visitPropertyAccess(PropertyAccess node) {
-    var target = node.realTarget;
-    if (rules.isDynamicTarget(target) &&
-        !_isObjectProperty(target, node.propertyName)) {
+  void _checkFieldAccess(AstNode node, AstNode target, SimpleIdentifier field) {
+    if ((rules.isDynamicTarget(target) || field.staticElement == null) &&
+        !_isObjectProperty(target, field)) {
       _recordDynamicInvoke(node, target);
     }
     node.visitChildren(this);
   }
 
   @override
+  void visitPropertyAccess(PropertyAccess node) {
+    _checkFieldAccess(node, node.realTarget, node.propertyName);
+  }
+
+  @override
   void visitPrefixedIdentifier(PrefixedIdentifier node) {
-    final target = node.prefix;
-    if (rules.isDynamicTarget(target) &&
-        !_isObjectProperty(target, node.identifier)) {
-      _recordDynamicInvoke(node, target);
-    }
-    node.visitChildren(this);
+    _checkFieldAccess(node, node.prefix, node.identifier);
   }
 
   @override
@@ -950,6 +965,33 @@
   }
 }
 
+// Return the field on type corresponding to member, or null if none
+// exists or the "field" is actually a getter/setter.
+PropertyInducingElement _getMemberField(
+    InterfaceType type, PropertyAccessorElement member) {
+  String memberName = member.name;
+  PropertyInducingElement field;
+  if (member.isGetter) {
+    // The subclass member is an explicit getter or a field
+    // - lookup the getter on the superclass.
+    var getter = type.getGetter(memberName);
+    if (getter == null || getter.isStatic) return null;
+    field = getter.variable;
+  } else if (!member.isSynthetic) {
+    // The subclass member is an explicit setter
+    // - lookup the setter on the superclass.
+    // Note: an implicit (synthetic) setter would have already been flagged on
+    // the getter above.
+    var setter = type.getSetter(memberName);
+    if (setter == null || setter.isStatic) return null;
+    field = setter.variable;
+  } else {
+    return null;
+  }
+  if (field.isSynthetic) return null;
+  return field;
+}
+
 /// Looks up the declaration that matches [member] in [type] and returns it's
 /// declared type.
 FunctionType _getMemberType(InterfaceType type, ExecutableElement member) =>
@@ -964,6 +1006,15 @@
 
   FunctionType f(InterfaceType type) {
     ExecutableElement baseMethod;
+
+    if (member.isPrivate) {
+      var subtypeLibrary = member.library;
+      var baseLibrary = type.element.library;
+      if (baseLibrary != subtypeLibrary) {
+        return null;
+      }
+    }
+
     try {
       if (isGetter) {
         assert(!isSetter);
diff --git a/pkg/analyzer/lib/src/task/strong/info.dart b/pkg/analyzer/lib/src/task/strong/info.dart
index 1aa42b2..9d4812f 100644
--- a/pkg/analyzer/lib/src/task/strong/info.dart
+++ b/pkg/analyzer/lib/src/task/strong/info.dart
@@ -452,6 +452,15 @@
   String get message => _messageHelper('Invalid override');
 }
 
+class InvalidFieldOverride extends InvalidOverride {
+  InvalidFieldOverride(AstNode node, ExecutableElement element,
+      InterfaceType base, DartType subType, DartType baseType)
+      : super(node, element, base, subType, baseType);
+
+  String get message => 'Field declaration {3}.{1} cannot be '
+      'overridden in {0}.';
+}
+
 /// Dart constructors have one weird quirk, illustrated with this example:
 ///
 ///     class Base {
diff --git a/pkg/analyzer/lib/src/task/strong/rules.dart b/pkg/analyzer/lib/src/task/strong/rules.dart
index 3cd6db2..32236a8 100644
--- a/pkg/analyzer/lib/src/task/strong/rules.dart
+++ b/pkg/analyzer/lib/src/task/strong/rules.dart
@@ -57,10 +57,7 @@
   /// return null.
   FunctionType getCallMethodType(DartType t) {
     if (t is InterfaceType) {
-      ClassElement element = t.element;
-      InheritanceManager manager = new InheritanceManager(element.library);
-      FunctionType callType = manager.lookupMemberType(t, "call");
-      return callType;
+      return t.lookUpMethod("call", null)?.type;
     }
     return null;
   }
diff --git a/pkg/analyzer/lib/src/task/strong_mode.dart b/pkg/analyzer/lib/src/task/strong_mode.dart
index ea3559d..c3716ad 100644
--- a/pkg/analyzer/lib/src/task/strong_mode.dart
+++ b/pkg/analyzer/lib/src/task/strong_mode.dart
@@ -8,7 +8,9 @@
 
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/resolver.dart'
+    show TypeProvider, InheritanceManager;
+import 'package:analyzer/src/generated/type_system.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 
 /**
@@ -25,11 +27,11 @@
       //
       // Update the type of the setter to reflect the new parameter type.
       //
+      // TODO(jmesserly): why is this necessary? The function type should always
+      // delegate to the orginal element.
       FunctionType functionType = element.type;
       if (functionType is FunctionTypeImpl) {
-        element.type =
-            new FunctionTypeImpl(element, functionType.prunedTypedefs)
-              ..typeArguments = functionType.typeArguments;
+        element.type = new FunctionTypeImpl(element);
       } else {
         assert(false);
       }
@@ -51,11 +53,12 @@
     // Update the return type of the element, which is stored in two places:
     // directly in the element and indirectly in the type of the element.
     //
+    // TODO(jmesserly): why is this necessary? The function type should always
+    // delegate to the orginal element.
     element.returnType = type;
     FunctionType functionType = element.type;
     if (functionType is FunctionTypeImpl) {
-      element.type = new FunctionTypeImpl(element, functionType.prunedTypedefs)
-        ..typeArguments = functionType.typeArguments;
+      element.type = new FunctionTypeImpl(element);
     } else {
       assert(false);
     }
diff --git a/pkg/analyzer/lib/src/util/absolute_path.dart b/pkg/analyzer/lib/src/util/absolute_path.dart
new file mode 100644
index 0000000..f31935d
--- /dev/null
+++ b/pkg/analyzer/lib/src/util/absolute_path.dart
@@ -0,0 +1,110 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.src.util.absolute_path;
+
+/// The class for manipulating absolute paths.
+class AbsolutePathContext {
+  final String separator;
+
+  int _separatorChar;
+
+  AbsolutePathContext(this.separator) {
+    if (separator.length != 1) {
+      throw new ArgumentError.value(
+          separator, 'separator', 'must be exactly one character long');
+    }
+    _separatorChar = separator.codeUnitAt(0);
+  }
+
+  /// Append the given relative [suffix] to the given absolute [parent].
+  ///
+  ///     context.append('/path/to', 'foo'); // -> '/path/to/foo'
+  ///
+  /// The given [suffix] cannot be an absolute path or use `..`.
+  String append(String parent, String suffix) {
+    return '$parent$separator$suffix';
+  }
+
+  /// Return the part of the absolute [path] after the last separator on the
+  /// context's platform.
+  ///
+  ///     context.basename('/path/to/foo.dart'); // -> 'foo.dart'
+  ///     context.basename('/path/to');          // -> 'to'
+  ///     context.basename('/path');             // -> 'path'
+  ///     context.basename('/');                 // -> ''
+  String basename(String path) {
+    int index = path.lastIndexOf(separator);
+    return path.substring(index + 1);
+  }
+
+  /// Return the part of the absolute [path] before the last separator.
+  ///
+  ///     context.dirname('/path/to/foo.dart'); // -> '/path/to'
+  ///     context.dirname('/path/to');          // -> '/path'
+  ///     context.dirname(r'/path');            // -> '/'
+  ///     context.dirname(r'/');                // -> '/'
+  ///     context.dirname(r'C:\path');          // -> 'C:\'
+  ///     context.dirname(r'C:\');              // -> 'C:\'
+  String dirname(String path) {
+    int firstIndex = path.indexOf(separator);
+    int lastIndex = path.lastIndexOf(separator);
+    return lastIndex == firstIndex
+        ? path.substring(0, firstIndex + 1)
+        : path.substring(0, lastIndex);
+  }
+
+  /// Return `true` if [child] is a path beneath [parent], and `false`
+  /// otherwise. Both the [child] and [parent] paths must be absolute paths.
+  ///
+  ///     context.isWithin('/root/path', '/root/path/a'); // -> true
+  ///     context.isWithin('/root/path', '/root/other');  // -> false
+  ///     context.isWithin('/root/path', '/root/path');   // -> false
+  bool isWithin(String parent, String child) {
+    int parentLength = parent.length;
+    int childLength = child.length;
+    if (parentLength >= childLength) {
+      return false;
+    }
+    if (child.codeUnitAt(parentLength) != _separatorChar) {
+      return false;
+    }
+    return _startsWithUnsafe(child, parent);
+  }
+
+  /// Split [path] into its components using [separator].
+  ///
+  ///     context.split('/path/to/foo'); // -> ['', 'path', 'to', 'foo']
+  List<String> split(String path) {
+    return path.split(separator);
+  }
+
+  /// If the given [child] is within the given [parent], then return the
+  /// relative path from [parent] to [child]. Otherwise return `null`. Both
+  /// the [child] and [parent] paths must be absolute paths.
+  ///
+  ///     context.relative('/root/path', '/root/path/a/b.dart'); // -> 'a/b.dart'
+  ///     context.relative('/root/path', '/root/other.dart');    // -> null
+  String suffix(String parent, String child) {
+    String parentPrefix = parent + separator;
+    if (child.startsWith(parentPrefix)) {
+      return child.substring(parentPrefix.length);
+    }
+    return null;
+  }
+
+  /// Return `true` if [str] starts with the given [prefix].
+  ///
+  /// The check is done from the end of [prefix], because absolute paths
+  /// usually have the same prefix, e.g. the user's home directory.
+  static bool _startsWithUnsafe(String str, String prefix) {
+    int len = prefix.length;
+    for (int i = len - 1; i >= 0; i--) {
+      if (str.codeUnitAt(i) != prefix.codeUnitAt(i)) {
+        return false;
+      }
+    }
+    return true;
+  }
+}
diff --git a/pkg/analyzer/lib/src/util/glob.dart b/pkg/analyzer/lib/src/util/glob.dart
new file mode 100644
index 0000000..ab86b4f
--- /dev/null
+++ b/pkg/analyzer/lib/src/util/glob.dart
@@ -0,0 +1,117 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.src.util.glob;
+
+/**
+ * A pattern that matches against filesystem path-like strings with wildcards.
+ *
+ * The pattern matches strings as follows:
+ *   * The pattern must use `/` as the path separator.
+ *   * The whole string must match, not a substring.
+ *   * Any non wildcard is matched as a literal.
+ *   * '*' matches one or more characters except '/'.
+ *   * '?' matches exactly one character except '/'.
+ *   * '**' matches one or more characters including '/'.
+ */
+class Glob {
+  /**
+   * The special characters are: \ ^ $ . | + [ ] ( ) { }
+   * as defined here: http://ecma-international.org/ecma-262/5.1/#sec-15.10
+   */
+  static final RegExp _specialChars =
+      new RegExp(r'([\\\^\$\.\|\+\[\]\(\)\{\}])');
+
+  /**
+   * The path separator used to separate components in file paths.
+   */
+  final String _separator;
+
+  /**
+   * The pattern string.
+   */
+  final String _pattern;
+
+  String _suffix;
+  RegExp _regex;
+
+  Glob(this._separator, this._pattern) {
+    if (_hasJustPrefix(_pattern, '**/*')) {
+      _suffix = _pattern.substring(4).toLowerCase();
+    } else if (_hasJustPrefix(_pattern, '**')) {
+      _suffix = _pattern.substring(2).toLowerCase();
+    } else {
+      _regex = _regexpFromGlobPattern(_pattern);
+    }
+  }
+
+  @override
+  int get hashCode => _pattern.hashCode;
+
+  bool operator ==(other) => other is Glob && _pattern == other._pattern;
+
+  /**
+   * Return `true` if the given [path] matches this glob.
+   * The given [path] must use the same [_separator] as the glob.
+   */
+  bool matches(String path) {
+    String posixPath = _toPosixPath(path);
+    if (_suffix != null) {
+      return posixPath.toLowerCase().endsWith(_suffix);
+    }
+    return _regex.matchAsPrefix(posixPath) != null;
+  }
+
+  @override
+  String toString() => _pattern;
+
+  /**
+   * Return the Posix version of the given [path].
+   */
+  String _toPosixPath(String path) {
+    if (_separator == '/') {
+      return path;
+    }
+    return path.replaceAll(_separator, '/');
+  }
+
+  /**
+   * Return `true` if the [pattern] start with the given [prefix] and does
+   * not have `*` or `?` characters after the [prefix].
+   */
+  static bool _hasJustPrefix(String pattern, String prefix) {
+    if (pattern.startsWith(prefix)) {
+      int prefixLength = prefix.length;
+      return pattern.indexOf('*', prefixLength) == -1 &&
+          pattern.indexOf('?', prefixLength) == -1;
+    }
+    return false;
+  }
+
+  static RegExp _regexpFromGlobPattern(String pattern) {
+    StringBuffer sb = new StringBuffer();
+    sb.write('^');
+    List<String> chars = pattern.split('');
+    for (int i = 0; i < chars.length; i++) {
+      String c = chars[i];
+      if (_specialChars.hasMatch(c)) {
+        sb.write(r'\');
+        sb.write(c);
+      } else if (c == '*') {
+        if (i + 1 < chars.length && chars[i + 1] == '*') {
+          sb.write('.*');
+          i++;
+        } else {
+          sb.write('[^/]*');
+        }
+      } else if (c == '?') {
+        sb.write('[^/]');
+      } else {
+        sb.write(c);
+      }
+    }
+    sb.write(r'$');
+    return new RegExp(sb.toString(), caseSensitive: false);
+  }
+}
diff --git a/pkg/analyzer/lib/src/util/yaml.dart b/pkg/analyzer/lib/src/util/yaml.dart
new file mode 100644
index 0000000..4f71bd7
--- /dev/null
+++ b/pkg/analyzer/lib/src/util/yaml.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.src.util.yaml;
+
+import 'dart:collection';
+
+/// Merges two maps (of yaml) with simple override semantics, suitable for
+/// merging two maps where one map defines default values that are added to
+/// (and possibly overriden) by an overriding map.
+class Merger {
+  /// Merges a default [o1] with an overriding object [o2].
+  ///
+  ///   * lists are merged (without duplicates).
+  ///   * lists of scalar values can be promoted to simple maps when merged with
+  ///     maps of strings to booleans (e.g., ['opt1', 'opt2'] becomes
+  ///     {'opt1': true, 'opt2': true}.
+  ///   * maps are merged recursively.
+  ///   * if map values cannot be merged, the overriding value is taken.
+  ///
+  Object merge(Object o1, Object o2) {
+    // Handle promotion first.
+    if (o1 is List && isMapToBools(o2)) {
+      o1 = new Map.fromIterable(o1, key: (item) => item, value: (item) => true);
+    } else if (isMapToBools(o1) && o2 is List) {
+      o2 = new Map.fromIterable(o2, key: (item) => item, value: (item) => true);
+    }
+
+    if (o1 is Map && o2 is Map) {
+      return mergeMap(o1, o2);
+    }
+    if (o1 is List && o2 is List) {
+      return mergeList(o1, o2);
+    }
+    // Default to override.
+    return o2;
+  }
+
+  /// Merge lists, avoiding duplicates.
+  List mergeList(List l1, List l2) =>
+      new List()..addAll(l1)..addAll(l2.where((item) => !l1.contains(item)));
+
+  /// Merge maps (recursively).
+  Map mergeMap(Map m1, Map m2) {
+    Map merged = new HashMap()..addAll(m1);
+    m2.forEach((k, v) {
+      merged[k] = merge(merged[k], v);
+    });
+    return merged;
+  }
+
+  static bool isMapToBools(Object o) =>
+      o is Map && o.values.every((v) => v is bool);
+}
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index d30df1f..1973fb9 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 0.26.1+16
+version: 0.26.2+1
 author: Dart Team <misc@dartlang.org>
 description: Static analyzer for Dart.
 homepage: http://www.dartlang.org
diff --git a/pkg/analyzer/test/file_system/physical_resource_provider_test.dart b/pkg/analyzer/test/file_system/physical_resource_provider_test.dart
index 87d976a..852c7b2c 100644
--- a/pkg/analyzer/test/file_system/physical_resource_provider_test.dart
+++ b/pkg/analyzer/test/file_system/physical_resource_provider_test.dart
@@ -301,7 +301,7 @@
           // See https://github.com/dart-lang/sdk/issues/23762
           // Not sure why this breaks under Windows, but testing to see whether
           // we are running Windows causes the type to change. For now we print
-          // the type out of curriosity.
+          // the type out of curiosity.
           print(
               'PhysicalResourceProviderTest:test_watchFile_delete received an event with type = ${changesReceived[0].type}');
         } else {
@@ -378,8 +378,8 @@
   }
 
   test_watchFolder_modifyFile_inSubDir() {
-    var subdirPath = join(tempPath, 'foo');
-    new io.Directory(subdirPath).createSync();
+    var fooPath = join(tempPath, 'foo');
+    new io.Directory(fooPath).createSync();
     var path = join(tempPath, 'bar');
     var file = new io.File(path);
     file.writeAsStringSync('contents 1');
@@ -410,7 +410,7 @@
       File file = PhysicalResourceProvider.INSTANCE.getResource(path);
       var changesReceived = <WatchEvent>[];
       var subscription = file.changes.listen(changesReceived.add);
-      // Delay running the rest of the test to allow file.changes propogate.
+      // Delay running the rest of the test to allow file.changes propagate.
       return _delayed(() => test(changesReceived)).whenComplete(() {
         subscription.cancel();
       });
diff --git a/pkg/analyzer/test/generated/all_the_rest_test.dart b/pkg/analyzer/test/generated/all_the_rest_test.dart
index dc07ef9..a9a7ab1 100644
--- a/pkg/analyzer/test/generated/all_the_rest_test.dart
+++ b/pkg/analyzer/test/generated/all_the_rest_test.dart
@@ -7350,7 +7350,9 @@
     SourceSpan span = new SourceFile(src).span(offset, offset + length);
 
     reporter.reportErrorForSpan(
-        AnalysisOptionsWarningCode.UNSUPPORTED_OPTION, span, ['test', 'zap']);
+        AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE,
+        span,
+        ['test', 'zip', 'zap']);
     expect(listener.errors, hasLength(1));
     expect(listener.errors.first.offset, offset);
     expect(listener.errors.first.length, length);
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
index 743399e..851a4ee 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
@@ -222,6 +222,46 @@
     verify([source]);
   }
 
+  void test_annotationWithNotClass() {
+    Source source = addSource('''
+class Property {
+  final int value;
+  const Property(this.value);
+}
+
+const Property property = const Property(42);
+
+@property(123)
+main() {
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [CompileTimeErrorCode.ANNOTATION_WITH_NON_CLASS]);
+    verify([source]);
+  }
+
+  void test_annotationWithNotClass_prefixed() {
+    addNamedSource(
+        "/annotations.dart",
+        r'''
+class Property {
+  final int value;
+  const Property(this.value);
+}
+
+const Property property = const Property(42);
+''');
+    Source source = addSource('''
+import 'annotations.dart' as pref;
+@pref.property(123)
+main() {
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [CompileTimeErrorCode.ANNOTATION_WITH_NON_CLASS]);
+    verify([source]);
+  }
+
   void test_async_used_as_identifier_in_annotation() {
     Source source = addSource('''
 const int async = 0;
diff --git a/pkg/analyzer/test/generated/element_test.dart b/pkg/analyzer/test/generated/element_test.dart
index 14485e2..4487fcb 100644
--- a/pkg/analyzer/test/generated/element_test.dart
+++ b/pkg/analyzer/test/generated/element_test.dart
@@ -1889,14 +1889,13 @@
     expect(paramType.prunedTypedefs[0], same(f));
   }
 
-  void test_setTypeArguments() {
+  void test_withTypeArguments() {
     ClassElementImpl enclosingClass = ElementFactory.classElement2("C", ["E"]);
     MethodElementImpl methodElement =
         new MethodElementImpl.forNode(AstFactory.identifier3("m"));
     enclosingClass.methods = <MethodElement>[methodElement];
     FunctionTypeImpl type = new FunctionTypeImpl(methodElement);
     DartType expectedType = enclosingClass.typeParameters[0].type;
-    type.typeArguments = <DartType>[expectedType];
     List<DartType> arguments = type.typeArguments;
     expect(arguments, hasLength(1));
     expect(arguments[0], expectedType);
@@ -1916,7 +1915,6 @@
     functionElement.returnType = parameterType;
     definingClass.methods = <MethodElement>[functionElement];
     FunctionTypeImpl functionType = new FunctionTypeImpl(functionElement);
-    functionType.typeArguments = <DartType>[parameterType];
     InterfaceTypeImpl argumentType = new InterfaceTypeImpl(
         new ClassElementImpl.forNode(AstFactory.identifier3("D")));
     FunctionType result = functionType.substitute2(
@@ -2426,11 +2424,10 @@
     ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
     DartType typeE = classA.type.typeArguments[0];
     String getterName = "g";
-    PropertyAccessorElement getterG =
+    PropertyAccessorElementImpl getterG =
         ElementFactory.getterElement(getterName, false, typeE);
     classA.accessors = <PropertyAccessorElement>[getterG];
-    (getterG.type as FunctionTypeImpl).typeArguments =
-        classA.type.typeArguments;
+    getterG.type = new FunctionTypeImpl(getterG);
     //
     // A<I>
     //
@@ -2753,8 +2750,7 @@
     MethodElementImpl methodM =
         ElementFactory.methodElement(methodName, typeE, [typeE]);
     classA.methods = <MethodElement>[methodM];
-    (methodM.type as FunctionTypeImpl).typeArguments =
-        classA.type.typeArguments;
+    methodM.type = new FunctionTypeImpl(methodM);
     //
     // A<I>
     //
@@ -2858,11 +2854,10 @@
     ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
     DartType typeE = classA.type.typeArguments[0];
     String setterName = "s";
-    PropertyAccessorElement setterS =
+    PropertyAccessorElementImpl setterS =
         ElementFactory.setterElement(setterName, false, typeE);
     classA.accessors = <PropertyAccessorElement>[setterS];
-    (setterS.type as FunctionTypeImpl).typeArguments =
-        classA.type.typeArguments;
+    setterS.type = new FunctionTypeImpl(setterS);
     //
     // A<I>
     //
@@ -3523,8 +3518,7 @@
     MethodElementImpl methodM =
         ElementFactory.methodElement(methodName, typeE, [typeE]);
     classA.methods = <MethodElement>[methodM];
-    (methodM.type as FunctionTypeImpl).typeArguments =
-        classA.type.typeArguments;
+    methodM.type = new FunctionTypeImpl(methodM);
     ClassElementImpl classB = ElementFactory.classElement2("B", ["F"]);
     InterfaceType typeB = classB.type;
     InterfaceTypeImpl typeAF = new InterfaceTypeImpl(classA);
diff --git a/pkg/analyzer/test/generated/engine_test.dart b/pkg/analyzer/test/generated/engine_test.dart
index 7224060..42a5bfc 100644
--- a/pkg/analyzer/test/generated/engine_test.dart
+++ b/pkg/analyzer/test/generated/engine_test.dart
@@ -8,6 +8,7 @@
 import 'dart:collection';
 
 import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/source/embedder.dart';
 import 'package:analyzer/src/cancelable_future.dart';
 import 'package:analyzer/src/context/cache.dart' show CacheEntry;
 import 'package:analyzer/src/generated/ast.dart';
@@ -2351,6 +2352,7 @@
       options.analyzeFunctionBodies = booleanValue;
       options.cacheSize = i;
       options.dart2jsHint = booleanValue;
+      options.enableGenericMethods = booleanValue;
       options.enableStrictCallChecks = booleanValue;
       options.enableSuperMixins = booleanValue;
       options.generateImplicitErrors = booleanValue;
@@ -2396,6 +2398,13 @@
     expect(options.dart2jsHint, value);
   }
 
+  void test_enableGenericMethods() {
+    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+    bool value = !options.enableGenericMethods;
+    options.enableGenericMethods = value;
+    expect(options.enableGenericMethods, value);
+  }
+
   void test_enableSuperMixins() {
     AnalysisOptionsImpl options = new AnalysisOptionsImpl();
     bool value = !options.enableSuperMixins;
@@ -5683,6 +5692,12 @@
   }
 
   @override
+  EmbedderYamlLocator get embedderYamlLocator {
+    fail("Unexpected invocation of get embedderYamlLocator");
+    return null;
+  }
+
+  @override
   void set analysisOptions(AnalysisOptions options) {
     fail("Unexpected invocation of setAnalysisOptions");
   }
@@ -5841,6 +5856,7 @@
   @override
   List<newContext.WorkManager> get workManagers {
     fail("Unexpected invocation of workManagers");
+    return null;
   }
 
   @override
@@ -5854,8 +5870,9 @@
   }
 
   @override
-  void applyChanges(ChangeSet changeSet) {
+  ApplyChangesStatus applyChanges(ChangeSet changeSet) {
     fail("Unexpected invocation of applyChanges");
+    return null;
   }
 
   @override
@@ -5960,6 +5977,7 @@
   @override
   Object getConfigurationData(newContext.ResultDescriptor key) {
     fail("Unexpected invocation of getConfigurationData");
+    return null;
   }
 
   @override
@@ -6223,8 +6241,9 @@
   bool invoked = false;
   TestAnalysisContext_test_applyChanges();
   @override
-  void applyChanges(ChangeSet changeSet) {
+  ApplyChangesStatus applyChanges(ChangeSet changeSet) {
     invoked = true;
+    return new ApplyChangesStatus(false);
   }
 }
 
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index 56aa853..719d159 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -3719,6 +3719,21 @@
     verify([source]);
   }
 
+  void test_nonBoolNegationExpression_dynamic() {
+    Source source = addSource(r'''
+f1(bool dynamic) {
+  !dynamic;
+}
+f2() {
+  bool dynamic = true;
+  !dynamic;
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_nonBoolOperand_and_bool() {
     Source source = addSource(r'''
 bool f(bool left, bool right) {
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 51e4941..42e49e4 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -204,45 +204,16 @@
     expect(argumentList4.arguments, hasLength(1));
   }
 
+  void test_assignableExpression_arguments_normal_chain_typeArgumentComments() {
+    enableGenericMethodComments = true;
+    _validate_assignableExpression_arguments_normal_chain_typeArguments(
+        "a/*<E>*/(b)/*<F>*/(c).d/*<G>*/(e).f");
+  }
+
   void test_assignableExpression_arguments_normal_chain_typeArguments() {
     enableGenericMethods = true;
-    PropertyAccess propertyAccess1 = parseExpression("a<E>(b)<F>(c).d<G>(e).f");
-    expect(propertyAccess1.propertyName.name, "f");
-    //
-    // a<E>(b)<F>(c).d>G?(e)
-    //
-    MethodInvocation invocation2 = EngineTestCase.assertInstanceOf(
-        (obj) => obj is MethodInvocation,
-        MethodInvocation,
-        propertyAccess1.target);
-    expect(invocation2.methodName.name, "d");
-    expect(invocation2.typeArguments, isNotNull);
-    ArgumentList argumentList2 = invocation2.argumentList;
-    expect(argumentList2, isNotNull);
-    expect(argumentList2.arguments, hasLength(1));
-    //
-    // a<E>(b)<F>(c)
-    //
-    FunctionExpressionInvocation invocation3 = EngineTestCase.assertInstanceOf(
-        (obj) => obj is FunctionExpressionInvocation,
-        FunctionExpressionInvocation,
-        invocation2.target);
-    expect(invocation3.typeArguments, isNotNull);
-    ArgumentList argumentList3 = invocation3.argumentList;
-    expect(argumentList3, isNotNull);
-    expect(argumentList3.arguments, hasLength(1));
-    //
-    // a(b)
-    //
-    MethodInvocation invocation4 = EngineTestCase.assertInstanceOf(
-        (obj) => obj is MethodInvocation,
-        MethodInvocation,
-        invocation3.function);
-    expect(invocation4.methodName.name, "a");
-    expect(invocation4.typeArguments, isNotNull);
-    ArgumentList argumentList4 = invocation4.argumentList;
-    expect(argumentList4, isNotNull);
-    expect(argumentList4.arguments, hasLength(1));
+    _validate_assignableExpression_arguments_normal_chain_typeArguments(
+        "a<E>(b)<F>(c).d<G>(e).f");
   }
 
   void test_assignmentExpression_compound() {
@@ -529,6 +500,47 @@
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.leftOperand);
   }
+
+  void _validate_assignableExpression_arguments_normal_chain_typeArguments(
+      String code) {
+    PropertyAccess propertyAccess1 = parseExpression(code);
+    expect(propertyAccess1.propertyName.name, "f");
+    //
+    // a<E>(b)<F>(c).d<G>(e)
+    //
+    MethodInvocation invocation2 = EngineTestCase.assertInstanceOf(
+        (obj) => obj is MethodInvocation,
+        MethodInvocation,
+        propertyAccess1.target);
+    expect(invocation2.methodName.name, "d");
+    expect(invocation2.typeArguments, isNotNull);
+    ArgumentList argumentList2 = invocation2.argumentList;
+    expect(argumentList2, isNotNull);
+    expect(argumentList2.arguments, hasLength(1));
+    //
+    // a<E>(b)<F>(c)
+    //
+    FunctionExpressionInvocation invocation3 = EngineTestCase.assertInstanceOf(
+        (obj) => obj is FunctionExpressionInvocation,
+        FunctionExpressionInvocation,
+        invocation2.target);
+    expect(invocation3.typeArguments, isNotNull);
+    ArgumentList argumentList3 = invocation3.argumentList;
+    expect(argumentList3, isNotNull);
+    expect(argumentList3.arguments, hasLength(1));
+    //
+    // a(b)
+    //
+    MethodInvocation invocation4 = EngineTestCase.assertInstanceOf(
+        (obj) => obj is MethodInvocation,
+        MethodInvocation,
+        invocation3.function);
+    expect(invocation4.methodName.name, "a");
+    expect(invocation4.typeArguments, isNotNull);
+    ArgumentList argumentList4 = invocation4.argumentList;
+    expect(argumentList4, isNotNull);
+    expect(argumentList4.arguments, hasLength(1));
+  }
 }
 
 /**
@@ -1426,6 +1438,44 @@
         "static f() {}", [ParserErrorCode.LOCAL_FUNCTION_DECLARATION_MODIFIER]);
   }
 
+  void test_method_invalidTypeParameterComments() {
+    enableGenericMethodComments = true;
+    MethodDeclaration method = parse3(
+        "parseClassMember",
+        <Object>["C"],
+        "void m/*<E, hello!>*/() {}",
+        [
+          ParserErrorCode.EXPECTED_TOKEN /*>*/,
+          ParserErrorCode.MISSING_IDENTIFIER,
+          ParserErrorCode.EXPECTED_TOKEN /*(*/,
+          ParserErrorCode.EXPECTED_TOKEN /*)*/,
+          ParserErrorCode.MISSING_FUNCTION_BODY
+        ]);
+    expect(method.typeParameters.toString(), '<E, hello>',
+        reason: 'parser recovers what it can');
+  }
+
+  void test_method_invalidTypeParameters() {
+    // TODO(jmesserly): ideally we'd be better at parser recovery here.
+    // It doesn't try to advance past the invalid token `!` to find the
+    // valid `>`. If it did we'd get less cascading errors, at least for this
+    // particular example.
+    enableGenericMethods = true;
+    MethodDeclaration method = parse3(
+        "parseClassMember",
+        <Object>["C"],
+        "void m<E, hello!>() {}",
+        [
+          ParserErrorCode.EXPECTED_TOKEN /*>*/,
+          ParserErrorCode.MISSING_IDENTIFIER,
+          ParserErrorCode.EXPECTED_TOKEN /*(*/,
+          ParserErrorCode.EXPECTED_TOKEN /*)*/,
+          ParserErrorCode.MISSING_FUNCTION_BODY
+        ]);
+    expect(method.typeParameters.toString(), '<E, hello>',
+        reason: 'parser recovers what it can');
+  }
+
   void test_missingAssignableSelector_identifiersAssigned() {
     parseExpression("x.y = y;");
   }
@@ -2596,6 +2646,11 @@
   bool enableGenericMethods = false;
 
   /**
+   * Whether generic method comments should be enabled for the test.
+   */
+  bool enableGenericMethodComments = false;
+
+  /**
    * Return a CommentAndMetadata object with the given values that can be used for testing.
    *
    * @param comment the comment to be wrapped in the object
@@ -2638,6 +2693,7 @@
     //
     Scanner scanner =
         new Scanner(null, new CharSequenceReader(source), listener);
+    scanner.scanGenericMethodComments = enableGenericMethodComments;
     Token tokenStream = scanner.tokenize();
     listener.setLineInfo(new TestSource(), scanner.lineStarts);
     //
@@ -2645,6 +2701,7 @@
     //
     Parser parser = createParser(listener);
     parser.parseGenericMethods = enableGenericMethods;
+    parser.parseGenericMethodComments = enableGenericMethodComments;
     parser.parseFunctionBodies = parseFunctionBodies;
     Object result =
         invokeParserMethodImpl(parser, methodName, objects, tokenStream);
@@ -2772,10 +2829,12 @@
     GatheringErrorListener listener = new GatheringErrorListener();
     Scanner scanner =
         new Scanner(null, new CharSequenceReader(source), listener);
+    scanner.scanGenericMethodComments = enableGenericMethodComments;
     listener.setLineInfo(new TestSource(), scanner.lineStarts);
     Token token = scanner.tokenize();
     Parser parser = createParser(listener);
     parser.parseGenericMethods = enableGenericMethods;
+    parser.parseGenericMethodComments = enableGenericMethodComments;
     Expression expression = parser.parseExpression(token);
     expect(expression, isNotNull);
     listener.assertErrorsWithCodes(errorCodes);
@@ -4641,6 +4700,13 @@
     expect(identifier.offset, 5);
   }
 
+  void fail_parseStatement_functionDeclaration_noReturnType_typeParameters() {
+    enableGenericMethods = true;
+    FunctionDeclarationStatement statement =
+        parse4("parseStatement", "f<E>(a, b) {};");
+    expect(statement.functionDeclaration, isNotNull);
+  }
+
   void test_computeStringValue_emptyInterpolationPrefix() {
     expect(_computeStringValue("'''", true, false), "");
   }
@@ -5110,6 +5176,21 @@
     expect(propertyAccess.propertyName, isNotNull);
   }
 
+  void test_parseAssignableExpression_expression_args_dot_typeParameterComments() {
+    enableGenericMethodComments = true;
+    PropertyAccess propertyAccess =
+        parse("parseAssignableExpression", <Object>[false], "(x)/*<F>*/(y).z");
+    FunctionExpressionInvocation invocation =
+        propertyAccess.target as FunctionExpressionInvocation;
+    expect(invocation.function, isNotNull);
+    expect(invocation.typeArguments, isNotNull);
+    ArgumentList argumentList = invocation.argumentList;
+    expect(argumentList, isNotNull);
+    expect(argumentList.arguments, hasLength(1));
+    expect(propertyAccess.operator, isNotNull);
+    expect(propertyAccess.propertyName, isNotNull);
+  }
+
   void test_parseAssignableExpression_expression_args_dot_typeParameters() {
     enableGenericMethods = true;
     PropertyAccess propertyAccess =
@@ -5169,6 +5250,20 @@
     expect(propertyAccess.propertyName, isNotNull);
   }
 
+  void test_parseAssignableExpression_identifier_args_dot_typeParameterComments() {
+    enableGenericMethodComments = true;
+    PropertyAccess propertyAccess =
+        parse("parseAssignableExpression", <Object>[false], "x/*<E>*/(y).z");
+    MethodInvocation invocation = propertyAccess.target as MethodInvocation;
+    expect(invocation.methodName.name, "x");
+    expect(invocation.typeArguments, isNotNull);
+    ArgumentList argumentList = invocation.argumentList;
+    expect(argumentList, isNotNull);
+    expect(argumentList.arguments, hasLength(1));
+    expect(propertyAccess.operator, isNotNull);
+    expect(propertyAccess.propertyName, isNotNull);
+  }
+
   void test_parseAssignableExpression_identifier_args_dot_typeParameters() {
     enableGenericMethods = true;
     PropertyAccess propertyAccess =
@@ -5391,6 +5486,16 @@
     expect(section.argumentList, isNotNull);
   }
 
+  void test_parseCascadeSection_ia_typeArgumentComments() {
+    enableGenericMethodComments = true;
+    FunctionExpressionInvocation section =
+        parse4("parseCascadeSection", "..[i]/*<E>*/(b)");
+    EngineTestCase.assertInstanceOf(
+        (obj) => obj is IndexExpression, IndexExpression, section.function);
+    expect(section.typeArguments, isNotNull);
+    expect(section.argumentList, isNotNull);
+  }
+
   void test_parseCascadeSection_ia_typeArguments() {
     enableGenericMethods = true;
     FunctionExpressionInvocation section =
@@ -5412,6 +5517,19 @@
     expect(section.argumentList.arguments, hasLength(1));
   }
 
+  void test_parseCascadeSection_ii_typeArgumentComments() {
+    enableGenericMethodComments = true;
+    MethodInvocation section =
+        parse4("parseCascadeSection", "..a/*<E>*/(b).c/*<F>*/(d)");
+    EngineTestCase.assertInstanceOf(
+        (obj) => obj is MethodInvocation, MethodInvocation, section.target);
+    expect(section.operator, isNotNull);
+    expect(section.methodName, isNotNull);
+    expect(section.typeArguments, isNotNull);
+    expect(section.argumentList, isNotNull);
+    expect(section.argumentList.arguments, hasLength(1));
+  }
+
   void test_parseCascadeSection_ii_typeArguments() {
     enableGenericMethods = true;
     MethodInvocation section =
@@ -5450,6 +5568,17 @@
         (obj) => obj is IntegerLiteral, IntegerLiteral, rhs);
   }
 
+  void test_parseCascadeSection_p_assign_withCascade_typeArgumentComments() {
+    enableGenericMethodComments = true;
+    AssignmentExpression section =
+        parse4("parseCascadeSection", "..a = 3..m/*<E>*/()");
+    expect(section.leftHandSide, isNotNull);
+    expect(section.operator, isNotNull);
+    Expression rhs = section.rightHandSide;
+    EngineTestCase.assertInstanceOf(
+        (obj) => obj is IntegerLiteral, IntegerLiteral, rhs);
+  }
+
   void test_parseCascadeSection_p_assign_withCascade_typeArguments() {
     enableGenericMethods = true;
     AssignmentExpression section =
@@ -5478,6 +5607,17 @@
     expect(section.argumentList.arguments, hasLength(1));
   }
 
+  void test_parseCascadeSection_pa_typeArgumentComments() {
+    enableGenericMethodComments = true;
+    MethodInvocation section = parse4("parseCascadeSection", "..a/*<E>*/(b)");
+    expect(section.target, isNull);
+    expect(section.operator, isNotNull);
+    expect(section.methodName, isNotNull);
+    expect(section.typeArguments, isNotNull);
+    expect(section.argumentList, isNotNull);
+    expect(section.argumentList.arguments, hasLength(1));
+  }
+
   void test_parseCascadeSection_pa_typeArguments() {
     enableGenericMethods = true;
     MethodInvocation section = parse4("parseCascadeSection", "..a<E>(b)");
@@ -5499,6 +5639,17 @@
     expect(section.argumentList.arguments, hasLength(1));
   }
 
+  void test_parseCascadeSection_paa_typeArgumentComments() {
+    enableGenericMethodComments = true;
+    FunctionExpressionInvocation section =
+        parse4("parseCascadeSection", "..a/*<E>*/(b)/*<F>*/(c)");
+    EngineTestCase.assertInstanceOf(
+        (obj) => obj is MethodInvocation, MethodInvocation, section.function);
+    expect(section.typeArguments, isNotNull);
+    expect(section.argumentList, isNotNull);
+    expect(section.argumentList.arguments, hasLength(1));
+  }
+
   void test_parseCascadeSection_paa_typeArguments() {
     enableGenericMethods = true;
     FunctionExpressionInvocation section =
@@ -5520,6 +5671,17 @@
     expect(section.argumentList.arguments, hasLength(1));
   }
 
+  void test_parseCascadeSection_paapaa_typeArgumentComments() {
+    enableGenericMethodComments = true;
+    FunctionExpressionInvocation section = parse4(
+        "parseCascadeSection", "..a/*<E>*/(b)/*<F>*/(c).d/*<G>*/(e)/*<H>*/(f)");
+    EngineTestCase.assertInstanceOf(
+        (obj) => obj is MethodInvocation, MethodInvocation, section.function);
+    expect(section.typeArguments, isNotNull);
+    expect(section.argumentList, isNotNull);
+    expect(section.argumentList.arguments, hasLength(1));
+  }
+
   void test_parseCascadeSection_paapaa_typeArguments() {
     enableGenericMethods = true;
     FunctionExpressionInvocation section =
@@ -5538,6 +5700,14 @@
     expect(section.propertyName, isNotNull);
   }
 
+  void test_parseCascadeSection_pap_typeArgumentComments() {
+    enableGenericMethodComments = true;
+    PropertyAccess section = parse4("parseCascadeSection", "..a/*<E>*/(b).c");
+    expect(section.target, isNotNull);
+    expect(section.operator, isNotNull);
+    expect(section.propertyName, isNotNull);
+  }
+
   void test_parseCascadeSection_pap_typeArguments() {
     enableGenericMethods = true;
     PropertyAccess section = parse4("parseCascadeSection", "..a<E>(b).c");
@@ -5867,6 +6037,74 @@
     expect(method.returnType, isNotNull);
   }
 
+  void test_parseClassMember_method_generic_comment_noReturnType() {
+    enableGenericMethodComments = true;
+    MethodDeclaration method =
+        parse("parseClassMember", <Object>["C"], "m/*<T>*/() {}");
+    expect(method.documentationComment, isNull);
+    expect(method.externalKeyword, isNull);
+    expect(method.modifierKeyword, isNull);
+    expect(method.propertyKeyword, isNull);
+    expect(method.returnType, isNull);
+    expect(method.name, isNotNull);
+    expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNotNull);
+    expect(method.parameters, isNotNull);
+    expect(method.body, isNotNull);
+  }
+
+  void test_parseClassMember_method_generic_comment_returnType() {
+    enableGenericMethodComments = true;
+    MethodDeclaration method =
+        parse("parseClassMember", <Object>["C"], "/*=T*/ m/*<T>*/() {}");
+    expect(method.documentationComment, isNull);
+    expect(method.externalKeyword, isNull);
+    expect(method.modifierKeyword, isNull);
+    expect(method.propertyKeyword, isNull);
+    expect(method.returnType.name.name, 'T');
+    expect(method.name, isNotNull);
+    expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNotNull);
+    expect(method.parameters, isNotNull);
+    expect(method.body, isNotNull);
+  }
+
+  void test_parseClassMember_method_generic_comment_returnType_bound() {
+    enableGenericMethodComments = true;
+    MethodDeclaration method = parse("parseClassMember", <Object>["C"],
+        "num/*=T*/ m/*<T extends num>*/() {}");
+    expect(method.documentationComment, isNull);
+    expect(method.externalKeyword, isNull);
+    expect(method.modifierKeyword, isNull);
+    expect(method.propertyKeyword, isNull);
+    expect(method.returnType.name.name, 'T');
+    expect(method.name, isNotNull);
+    expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNotNull);
+    TypeParameter tp = method.typeParameters.typeParameters[0];
+    expect(tp.name.name, 'T');
+    expect(tp.extendsKeyword, isNotNull);
+    expect(tp.bound.name.name, 'num');
+    expect(method.parameters, isNotNull);
+    expect(method.body, isNotNull);
+  }
+
+  void test_parseClassMember_method_generic_comment_void() {
+    enableGenericMethodComments = true;
+    MethodDeclaration method =
+        parse("parseClassMember", <Object>["C"], "void m/*<T>*/() {}");
+    expect(method.documentationComment, isNull);
+    expect(method.externalKeyword, isNull);
+    expect(method.modifierKeyword, isNull);
+    expect(method.propertyKeyword, isNull);
+    expect(method.returnType, isNotNull);
+    expect(method.name, isNotNull);
+    expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNotNull);
+    expect(method.parameters, isNotNull);
+    expect(method.body, isNotNull);
+  }
+
   void test_parseClassMember_method_generic_noReturnType() {
     enableGenericMethods = true;
     MethodDeclaration method =
@@ -6716,6 +6954,14 @@
     expect(declaration.propertyKeyword, isNull);
   }
 
+  void test_parseCompilationUnitMember_function_withTypeParameters() {
+    enableGenericMethods = true;
+    FunctionDeclaration declaration = parse("parseCompilationUnitMember",
+        <Object>[emptyCommentAndMetadata()], "void f<T>(T t) {}");
+    expect(declaration.functionExpression, isNotNull);
+    expect(declaration.propertyKeyword, isNull);
+  }
+
   void test_parseCompilationUnitMember_function_void() {
     FunctionDeclaration declaration = parse("parseCompilationUnitMember",
         <Object>[emptyCommentAndMetadata()], "void f() {}");
@@ -7339,6 +7585,15 @@
     expect(invocation.argumentList, isNotNull);
   }
 
+  void test_parseExpression_superMethodInvocation_typeArgumentComments() {
+    enableGenericMethodComments = true;
+    MethodInvocation invocation = parse4("parseExpression", "super.m/*<E>*/()");
+    expect(invocation.target, isNotNull);
+    expect(invocation.methodName, isNotNull);
+    expect(invocation.typeArguments, isNotNull);
+    expect(invocation.argumentList, isNotNull);
+  }
+
   void test_parseExpression_superMethodInvocation_typeArguments() {
     enableGenericMethods = true;
     MethodInvocation invocation = parse4("parseExpression", "super.m<E>()");
@@ -7386,6 +7641,16 @@
     expect(invocation.argumentList, isNotNull);
   }
 
+  void test_parseExpressionWithoutCascade_superMethodInvocation_typeArgumentComments() {
+    enableGenericMethodComments = true;
+    MethodInvocation invocation =
+        parse4("parseExpressionWithoutCascade", "super.m/*<E>*/()");
+    expect(invocation.target, isNotNull);
+    expect(invocation.methodName, isNotNull);
+    expect(invocation.typeArguments, isNotNull);
+    expect(invocation.argumentList, isNotNull);
+  }
+
   void test_parseExpressionWithoutCascade_superMethodInvocation_typeArguments() {
     enableGenericMethods = true;
     MethodInvocation invocation =
@@ -8148,6 +8413,25 @@
     expect(declaration.propertyKeyword, isNull);
   }
 
+  void test_parseFunctionDeclaration_functionWithTypeParameters_comment() {
+    enableGenericMethodComments = true;
+    Comment comment = Comment.createDocumentationComment(new List<Token>(0));
+    TypeName returnType = new TypeName(new SimpleIdentifier(null), null);
+    FunctionDeclaration declaration = parse(
+        "parseFunctionDeclaration",
+        <Object>[commentAndMetadata(comment), null, returnType],
+        "f/*<E>*/() {}");
+    expect(declaration.documentationComment, comment);
+    expect(declaration.returnType, returnType);
+    expect(declaration.name, isNotNull);
+    FunctionExpression expression = declaration.functionExpression;
+    expect(expression, isNotNull);
+    expect(expression.body, isNotNull);
+    expect(expression.typeParameters, isNotNull);
+    expect(expression.parameters, isNotNull);
+    expect(declaration.propertyKeyword, isNull);
+  }
+
   void test_parseFunctionDeclaration_getter() {
     Comment comment = Comment.createDocumentationComment(new List<Token>(0));
     TypeName returnType = new TypeName(new SimpleIdentifier(null), null);
@@ -8186,11 +8470,26 @@
     expect(statement.functionDeclaration, isNotNull);
   }
 
+  void test_parseFunctionDeclarationStatement_typeParameterComments() {
+    enableGenericMethodComments = true;
+    FunctionDeclarationStatement statement = parse4(
+        "parseFunctionDeclarationStatement",
+        "/*=E*/ f/*<E>*/(/*=E*/ p) => p * 2;");
+    FunctionDeclaration f = statement.functionDeclaration;
+    expect(f, isNotNull);
+    expect(f.functionExpression.typeParameters, isNotNull);
+    expect(f.returnType, isNotNull);
+    SimpleFormalParameter p = f.functionExpression.parameters.parameters[0];
+    expect(p.type, isNotNull);
+  }
+
   void test_parseFunctionDeclarationStatement_typeParameters() {
     enableGenericMethods = true;
     FunctionDeclarationStatement statement =
         parse4("parseFunctionDeclarationStatement", "E f<E>(E p) => p * 2;");
     expect(statement.functionDeclaration, isNotNull);
+    expect(statement.functionDeclaration.functionExpression.typeParameters,
+        isNotNull);
   }
 
   void test_parseFunctionExpression_body_inExpression() {
@@ -8202,6 +8501,18 @@
     expect((expression.body as ExpressionFunctionBody).semicolon, isNull);
   }
 
+  void test_parseFunctionExpression_typeParameterComments() {
+    enableGenericMethodComments = true;
+    FunctionExpression expression =
+        parse4("parseFunctionExpression", "/*<E>*/(/*=E*/ i) => i++");
+    expect(expression.body, isNotNull);
+    expect(expression.typeParameters, isNotNull);
+    expect(expression.parameters, isNotNull);
+    expect((expression.body as ExpressionFunctionBody).semicolon, isNull);
+    SimpleFormalParameter p = expression.parameters.parameters[0];
+    expect(p.type, isNotNull);
+  }
+
   void test_parseFunctionExpression_typeParameters() {
     enableGenericMethods = true;
     FunctionExpression expression =
@@ -8951,6 +9262,16 @@
     expect(parameter.parameters, isNotNull);
   }
 
+  void test_parseNormalFormalParameter_function_noType_typeParameterComments() {
+    enableGenericMethodComments = true;
+    FunctionTypedFormalParameter parameter =
+        parse4("parseNormalFormalParameter", "a/*<E>*/())");
+    expect(parameter.returnType, isNull);
+    expect(parameter.identifier, isNotNull);
+    expect(parameter.typeParameters, isNotNull);
+    expect(parameter.parameters, isNotNull);
+  }
+
   void test_parseNormalFormalParameter_function_noType_typeParameters() {
     enableGenericMethods = true;
     FunctionTypedFormalParameter parameter =
@@ -8970,6 +9291,16 @@
     expect(parameter.parameters, isNotNull);
   }
 
+  void test_parseNormalFormalParameter_function_type_typeParameterComments() {
+    enableGenericMethodComments = true;
+    FunctionTypedFormalParameter parameter =
+        parse4("parseNormalFormalParameter", "A a/*<E>*/())");
+    expect(parameter.returnType, isNotNull);
+    expect(parameter.identifier, isNotNull);
+    expect(parameter.typeParameters, isNotNull);
+    expect(parameter.parameters, isNotNull);
+  }
+
   void test_parseNormalFormalParameter_function_type_typeParameters() {
     enableGenericMethods = true;
     FunctionTypedFormalParameter parameter =
@@ -8989,6 +9320,16 @@
     expect(parameter.parameters, isNotNull);
   }
 
+  void test_parseNormalFormalParameter_function_void_typeParameterComments() {
+    enableGenericMethodComments = true;
+    FunctionTypedFormalParameter parameter =
+        parse4("parseNormalFormalParameter", "void a/*<E>*/())");
+    expect(parameter.returnType, isNotNull);
+    expect(parameter.identifier, isNotNull);
+    expect(parameter.typeParameters, isNotNull);
+    expect(parameter.parameters, isNotNull);
+  }
+
   void test_parseNormalFormalParameter_function_void_typeParameters() {
     enableGenericMethods = true;
     FunctionTypedFormalParameter parameter =
@@ -9125,6 +9466,17 @@
     expect(expression.argumentList, isNotNull);
   }
 
+  void test_parsePostfixExpression_none_methodInvocation_question_dot_typeArgumentComments() {
+    enableGenericMethodComments = true;
+    MethodInvocation expression =
+        parse4('parsePostfixExpression', 'a?.m/*<E>*/()');
+    expect(expression.target, isNotNull);
+    expect(expression.operator.type, TokenType.QUESTION_PERIOD);
+    expect(expression.methodName, isNotNull);
+    expect(expression.typeArguments, isNotNull);
+    expect(expression.argumentList, isNotNull);
+  }
+
   void test_parsePostfixExpression_none_methodInvocation_question_dot_typeArguments() {
     enableGenericMethods = true;
     MethodInvocation expression = parse4('parsePostfixExpression', 'a?.m<E>()');
@@ -9135,6 +9487,17 @@
     expect(expression.argumentList, isNotNull);
   }
 
+  void test_parsePostfixExpression_none_methodInvocation_typeArgumentComments() {
+    enableGenericMethodComments = true;
+    MethodInvocation expression =
+        parse4("parsePostfixExpression", "a.m/*<E>*/()");
+    expect(expression.target, isNotNull);
+    expect(expression.operator.type, TokenType.PERIOD);
+    expect(expression.methodName, isNotNull);
+    expect(expression.typeArguments, isNotNull);
+    expect(expression.argumentList, isNotNull);
+  }
+
   void test_parsePostfixExpression_none_methodInvocation_typeArguments() {
     enableGenericMethods = true;
     MethodInvocation expression = parse4("parsePostfixExpression", "a.m<E>()");
@@ -9488,17 +9851,19 @@
     expect(statement.functionDeclaration, isNotNull);
   }
 
-  void test_parseStatement_functionDeclaration_noReturnType_typeParameters() {
-    enableGenericMethods = true;
+  void test_parseStatement_functionDeclaration_noReturnType_typeParameterComments() {
+    enableGenericMethodComments = true;
     FunctionDeclarationStatement statement =
-        parse4("parseStatement", "f(a, b) {};");
+        parse4("parseStatement", "f/*<E>*/(a, b) {};");
     expect(statement.functionDeclaration, isNotNull);
+    expect(statement.functionDeclaration.functionExpression.typeParameters,
+        isNotNull);
   }
 
   void test_parseStatement_functionDeclaration_returnType() {
     // TODO(brianwilkerson) Implement more tests for this method.
     FunctionDeclarationStatement statement =
-        parse4("parseStatement", "int f(a, b) {};");
+        parse4("parseStatement", "int f(a, b) {};", []);
     expect(statement.functionDeclaration, isNotNull);
   }
 
@@ -10350,6 +10715,16 @@
     expect(declarationList.variables, hasLength(1));
   }
 
+  void test_parseVariableDeclarationListAfterMetadata_final_typeComment() {
+    enableGenericMethodComments = true;
+    VariableDeclarationList decl = parse(
+        "parseVariableDeclarationListAfterMetadata",
+        <Object>[emptyCommentAndMetadata()],
+        "final/*=T*/ x");
+    expect(decl.type.name.name, 'T');
+    expect(decl.isFinal, true);
+  }
+
   void test_parseVariableDeclarationListAfterMetadata_type_multiple() {
     VariableDeclarationList declarationList = parse(
         "parseVariableDeclarationListAfterMetadata",
@@ -10390,6 +10765,16 @@
     expect(declarationList.variables, hasLength(1));
   }
 
+  void test_parseVariableDeclarationListAfterMetadata_var_typeComment() {
+    enableGenericMethodComments = true;
+    VariableDeclarationList decl = parse(
+        "parseVariableDeclarationListAfterMetadata",
+        <Object>[emptyCommentAndMetadata()],
+        "var/*=T*/ x");
+    expect(decl.type.name.name, 'T');
+    expect(decl.keyword, isNull);
+  }
+
   void test_parseVariableDeclarationListAfterType_type() {
     TypeName type = new TypeName(new SimpleIdentifier(null), null);
     VariableDeclarationList declarationList = parse(
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index 1339162..7c6bece 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -201,28 +201,23 @@
       ElementFactory.positionalParameter2("value", provider.dynamicType)
     ];
     futureConstructor.factory = true;
-    (futureConstructor.type as FunctionTypeImpl).typeArguments =
-        futureElement.type.typeArguments;
     futureElement.constructors = <ConstructorElement>[futureConstructor];
     //   Future then(onValue(T value), { Function onError });
     List<ParameterElement> parameters = <ParameterElement>[
       ElementFactory.requiredParameter2(
           "value", futureElement.typeParameters[0].type)
     ];
-    FunctionTypeAliasElementImpl aliasElement =
-        new FunctionTypeAliasElementImpl.forNode(null);
-    aliasElement.synthetic = true;
-    aliasElement.parameters = parameters;
-    aliasElement.returnType = provider.dynamicType;
-    aliasElement.enclosingElement = asyncUnit;
-    FunctionTypeImpl aliasType = new FunctionTypeImpl.forTypedef(aliasElement);
-    aliasElement.shareTypeParameters(futureElement.typeParameters);
-    aliasType.typeArguments = futureElement.type.typeArguments;
+    FunctionElementImpl onValueFunction = new FunctionElementImpl.forNode(null);
+    onValueFunction.synthetic = true;
+    onValueFunction.parameters = parameters;
+    onValueFunction.returnType = provider.dynamicType;
+    onValueFunction.enclosingElement = futureElement;
+    onValueFunction.type = new FunctionTypeImpl(onValueFunction);
     DartType futureDynamicType =
         futureElement.type.substitute4([provider.dynamicType]);
     MethodElement thenMethod = ElementFactory.methodElementWithParameters(
-        "then", futureElement.type.typeArguments, futureDynamicType, [
-      ElementFactory.requiredParameter2("onValue", aliasType),
+        futureElement, "then", futureDynamicType, [
+      ElementFactory.requiredParameter2("onValue", onValueFunction.type),
       ElementFactory.namedParameter2("onError", provider.functionType)
     ]);
     futureElement.methods = <MethodElement>[thenMethod];
@@ -231,8 +226,6 @@
         ElementFactory.classElement2("Completer", ["T"]);
     ConstructorElementImpl completerConstructor =
         ElementFactory.constructorElement2(completerElement, null);
-    (completerConstructor.type as FunctionTypeImpl).typeArguments =
-        completerElement.type.typeArguments;
     completerElement.constructors = <ConstructorElement>[completerConstructor];
     // StreamSubscription
     ClassElementImpl streamSubscriptionElement =
@@ -255,6 +248,13 @@
     MethodElementImpl listenMethod =
         ElementFactory.methodElement('listen', returnType, parameterTypes);
     streamElement.methods = <MethodElement>[listenMethod];
+    listenMethod.type = new FunctionTypeImpl(listenMethod);
+
+    FunctionElementImpl listenParamFunction = parameterTypes[0].element;
+    listenParamFunction.enclosingElement = listenMethod;
+    listenParamFunction.type = new FunctionTypeImpl(listenParamFunction);
+    ParameterElementImpl listenParam = listenMethod.parameters[0];
+    listenParam.type = listenParamFunction.type;
 
     asyncUnit.types = <ClassElement>[
       completerElement,
@@ -2358,6 +2358,61 @@
     verify([source]);
   }
 
+  void test_canBeNullAfterNullAware_false_methodInvocation() {
+    Source source = addSource(r'''
+m(x) {
+  x?.a()?.b();
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_canBeNullAfterNullAware_false_propertyAccess() {
+    Source source = addSource(r'''
+m(x) {
+  x?.a?.b;
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_canBeNullAfterNullAware_methodInvocation() {
+    Source source = addSource(r'''
+m(x) {
+  x?.a.b();
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.CAN_BE_NULL_AFTER_NULL_AWARE]);
+    verify([source]);
+  }
+
+  void test_canBeNullAfterNullAware_parenthesized() {
+    Source source = addSource(r'''
+m(x) {
+  (x?.a).b;
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.CAN_BE_NULL_AFTER_NULL_AWARE]);
+    verify([source]);
+  }
+
+  void test_canBeNullAfterNullAware_propertyAccess() {
+    Source source = addSource(r'''
+m(x) {
+  x?.a.b;
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.CAN_BE_NULL_AFTER_NULL_AWARE]);
+    verify([source]);
+  }
+
   void test_deadCode_deadBlock_conditionalElse() {
     Source source = addSource(r'''
 f() {
@@ -2762,10 +2817,10 @@
     verify([source]);
   }
 
-  void test_deprecatedAnnotationUse_Deprecated() {
+  void test_deprecatedAnnotationUse_deprecated() {
     Source source = addSource(r'''
 class A {
-  @Deprecated('0.9')
+  @deprecated
   m() {}
   n() {m();}
 }''');
@@ -2774,10 +2829,10 @@
     verify([source]);
   }
 
-  void test_deprecatedAnnotationUse_deprecated() {
+  void test_deprecatedAnnotationUse_Deprecated() {
     Source source = addSource(r'''
 class A {
-  @deprecated
+  @Deprecated('0.9')
   m() {}
   n() {m();}
 }''');
@@ -3153,6 +3208,160 @@
     verify([source]);
   }
 
+  void test_nullAwareInCondition_assert() {
+    Source source = addSource(r'''
+m(x) {
+  assert (x?.a);
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+    verify([source]);
+  }
+
+  void test_nullAwareInCondition_conditionalExpression() {
+    Source source = addSource(r'''
+m(x) {
+  return x?.a ? 0 : 1;
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+    verify([source]);
+  }
+
+  void test_nullAwareInCondition_do() {
+    Source source = addSource(r'''
+m(x) {
+  do {} while (x?.a);
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+    verify([source]);
+  }
+
+  void test_nullAwareInCondition_for() {
+    Source source = addSource(r'''
+m(x) {
+  for (var v = x; v?.a; v = v.next) {}
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+    verify([source]);
+  }
+
+  void test_nullAwareInCondition_if() {
+    Source source = addSource(r'''
+m(x) {
+  if (x?.a) {}
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+    verify([source]);
+  }
+
+  void test_nullAwareInCondition_if_conditionalAnd_first() {
+    Source source = addSource(r'''
+m(x) {
+  if (x?.a && x.b) {}
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+    verify([source]);
+  }
+
+  void test_nullAwareInCondition_if_conditionalAnd_second() {
+    Source source = addSource(r'''
+m(x) {
+  if (x.a && x?.b) {}
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+    verify([source]);
+  }
+
+  void test_nullAwareInCondition_if_conditionalAnd_third() {
+    Source source = addSource(r'''
+m(x) {
+  if (x.a && x.b && x?.c) {}
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+    verify([source]);
+  }
+
+  void test_nullAwareInCondition_if_conditionalOr_first() {
+    Source source = addSource(r'''
+m(x) {
+  if (x?.a || x.b) {}
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+    verify([source]);
+  }
+
+  void test_nullAwareInCondition_if_conditionalOr_second() {
+    Source source = addSource(r'''
+m(x) {
+  if (x.a || x?.b) {}
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+    verify([source]);
+  }
+
+  void test_nullAwareInCondition_if_conditionalOr_third() {
+    Source source = addSource(r'''
+m(x) {
+  if (x.a || x.b || x?.c) {}
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+    verify([source]);
+  }
+
+  void test_nullAwareInCondition_if_not() {
+    Source source = addSource(r'''
+m(x) {
+  if (!x?.a) {}
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+    verify([source]);
+  }
+
+  void test_nullAwareInCondition_if_parenthesized() {
+    Source source = addSource(r'''
+m(x) {
+  if ((x?.a)) {}
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+    verify([source]);
+  }
+
+  void test_nullAwareInCondition_while() {
+    Source source = addSource(r'''
+m(x) {
+  while (x?.a) {}
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+    verify([source]);
+  }
+
   void test_overrideOnNonOverridingGetter_invalid() {
     Source source = addSource(r'''
 library dart.core;
@@ -6900,6 +7109,28 @@
     verify([source]);
   }
 
+  void test_nullAwareInCondition_for_noCondition() {
+    Source source = addSource(r'''
+m(x) {
+  for (var v = x; ; v++) {}
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_nullAwareInCondition_if_notTopLevel() {
+    Source source = addSource(r'''
+m(x) {
+  if (x?.y == null) {}
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_overrideEqualsButNotHashCode() {
     Source source = addSource(r'''
 class A {
@@ -11938,6 +12169,82 @@
     expect(declaration.initializer.propagatedType, isNull);
   }
 
+  void test_genericFunction() {
+    if (!AnalysisEngine.instance.useTaskModel) {
+      return;
+    }
+    // TODO(jmesserly): we're missing a case in the parser for the return type,
+    // so "dynamic" must be used to workaround this.
+    _resolveTestUnit(r'''
+dynamic/*=T*/ f/*<T>*/(/*=T*/ x) => null;
+''');
+    SimpleIdentifier f = _findIdentifier('f');
+    FunctionElementImpl e = f.staticElement;
+    expect(e.typeParameters.toString(), '[T]');
+    expect(e.type.typeParameters.toString(), '[T]');
+    expect(e.type.typeParameters[0].type, e.type.typeArguments[0]);
+    expect(e.type.toString(), '(T) → T');
+
+    // Substitute for T
+    DartType t = e.typeParameters[0].type;
+    FunctionType ft = e.type.substitute2([typeProvider.stringType], [t]);
+    expect(ft.toString(), '(String) → String');
+  }
+
+  void test_genericMethod() {
+    if (!AnalysisEngine.instance.useTaskModel) {
+      return;
+    }
+    _resolveTestUnit(r'''
+class C<E> {
+  List/*<T>*/ f/*<T>*/(E e) => null;
+}
+main() {
+  C<String> cOfString;
+}
+''');
+    SimpleIdentifier f = _findIdentifier('f');
+    MethodElementImpl e = f.staticElement;
+    expect(e.typeParameters.toString(), '[T]');
+    expect(e.type.typeParameters.toString(), '[T, E]');
+    expect(e.type.typeArguments.toString(), '[T, E]');
+    expect(e.type.toString(), '(E) → List<T>');
+
+    SimpleIdentifier c = _findIdentifier('cOfString');
+    FunctionType ft = (c.staticType as InterfaceType).getMethod('f').type;
+    expect(ft.toString(), '(String) → List<T>');
+    DartType t = e.typeParameters[0].type;
+    ft = ft.substitute2([typeProvider.intType], [t]);
+    expect(ft.toString(), '(String) → List<int>');
+  }
+
+  void test_genericMethod_functionTypedParameter() {
+    if (!AnalysisEngine.instance.useTaskModel) {
+      return;
+    }
+    _resolveTestUnit(r'''
+class C<E> {
+  List/*<T>*/ f/*<T>*/(/*=T*/ f(E e)) => null;
+}
+main() {
+  C<String> cOfString;
+}
+''');
+    SimpleIdentifier f = _findIdentifier('f');
+    MethodElementImpl e = f.staticElement;
+    expect(e.typeParameters.toString(), '[T]');
+    expect(e.type.typeParameters.toString(), '[T, E]');
+    expect(e.type.typeArguments.toString(), '[T, E]');
+    expect(e.type.toString(), '((E) → T) → List<T>');
+
+    SimpleIdentifier c = _findIdentifier('cOfString');
+    FunctionType ft = (c.staticType as InterfaceType).getMethod('f').type;
+    expect(ft.toString(), '((String) → T) → List<T>');
+    DartType t = e.typeParameters[0].type;
+    ft = ft.substitute2([typeProvider.intType], [t]);
+    expect(ft.toString(), '((String) → int) → List<int>');
+  }
+
   void test_pseudoGeneric_max_doubleDouble() {
     String code = r'''
 import 'dart:math';
@@ -12936,6 +13243,39 @@
     }
   }
 
+  void test_forEach_async_inheritedStream() {
+    // From https://github.com/dart-lang/sdk/issues/24191, this ensures that
+    // `await for` works for types where the generic parameter doesn't
+    // correspond to the type of the Stream's data.
+    String code = r'''
+import 'dart:async';
+abstract class MyCustomStream<T> implements Stream<List<T>> {}
+f(MyCustomStream<String> stream) async {
+  await for (var e in stream) {
+    e;
+  }
+}''';
+    Source source = addSource(code);
+    LibraryElement library = resolve2(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = resolveCompilationUnit(source, library);
+    InterfaceType listOfStringType =
+        typeProvider.listType.substitute4([typeProvider.stringType]);
+    // in the declaration
+    {
+      SimpleIdentifier identifier = EngineTestCase.findNode(
+          unit, code, "e in", (node) => node is SimpleIdentifier);
+      expect(identifier.propagatedType, equals(listOfStringType));
+    }
+    // in the loop body
+    {
+      SimpleIdentifier identifier = EngineTestCase.findNode(
+          unit, code, "e;", (node) => node is SimpleIdentifier);
+      expect(identifier.propagatedType, equals(listOfStringType));
+    }
+  }
+
   void test_functionExpression_asInvocationArgument() {
     String code = r'''
 class MyMap<K, V> {
diff --git a/pkg/analyzer/test/generated/scanner_test.dart b/pkg/analyzer/test/generated/scanner_test.dart
index 119d4aa..a0c7355 100644
--- a/pkg/analyzer/test/generated/scanner_test.dart
+++ b/pkg/analyzer/test/generated/scanner_test.dart
@@ -264,6 +264,18 @@
     expect(token.precedingComments, isNull);
   }
 
+  void test_comment_generic_method_type_assign() {
+    _assertComment(TokenType.MULTI_LINE_COMMENT, "/*=comment*/");
+    _assertComment(TokenType.GENERIC_METHOD_TYPE_ASSIGN, "/*=comment*/",
+        genericMethodComments: true);
+  }
+
+  void test_comment_generic_method_type_list() {
+    _assertComment(TokenType.MULTI_LINE_COMMENT, "/*<comment>*/");
+    _assertComment(TokenType.GENERIC_METHOD_TYPE_LIST, "/*<comment>*/",
+        genericMethodComments: true);
+  }
+
   void test_comment_multi() {
     _assertComment(TokenType.MULTI_LINE_COMMENT, "/* comment */");
   }
@@ -1048,11 +1060,12 @@
     _scanWithListener("'\${(}'", listener);
   }
 
-  void _assertComment(TokenType commentType, String source) {
+  void _assertComment(TokenType commentType, String source,
+      {bool genericMethodComments: false}) {
     //
     // Test without a trailing end-of-line marker
     //
-    Token token = _scan(source);
+    Token token = _scan(source, genericMethodComments: genericMethodComments);
     expect(token, isNotNull);
     expect(token.type, TokenType.EOF);
     Token comment = token.precedingComments;
@@ -1064,7 +1077,7 @@
     //
     // Test with a trailing end-of-line marker
     //
-    token = _scan("$source\n");
+    token = _scan("$source\n", genericMethodComments: genericMethodComments);
     expect(token, isNotNull);
     expect(token.type, TokenType.EOF);
     comment = token.precedingComments;
@@ -1233,16 +1246,21 @@
     expect(token.type, TokenType.EOF);
   }
 
-  Token _scan(String source) {
+  Token _scan(String source, {bool genericMethodComments: false}) {
     GatheringErrorListener listener = new GatheringErrorListener();
-    Token token = _scanWithListener(source, listener);
+    Token token = _scanWithListener(source, listener,
+        genericMethodComments: genericMethodComments);
     listener.assertNoErrors();
     return token;
   }
 
-  Token _scanWithListener(String source, GatheringErrorListener listener) {
+  Token _scanWithListener(String source, GatheringErrorListener listener,
+      {bool genericMethodComments: false}) {
     Scanner scanner =
         new Scanner(null, new CharSequenceReader(source), listener);
+    if (genericMethodComments) {
+      scanner.scanGenericMethodComments = true;
+    }
     Token result = scanner.tokenize();
     listener.setLineInfo(new TestSource(), scanner.lineStarts);
     return result;
diff --git a/pkg/analyzer/test/generated/static_type_warning_code_test.dart b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
index 99ab84c..d98f837 100644
--- a/pkg/analyzer/test/generated/static_type_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
@@ -1600,6 +1600,19 @@
     assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
   }
 
+  void test_undefinedMethodWithConstructor() {
+    Source source = addSource(r'''
+class C {
+  C.m();
+}
+f() {
+  C c = C.m();
+}''');
+    computeLibrarySourceErrors(source);
+    assertErrors(
+        source, [StaticTypeWarningCode.UNDEFINED_METHOD_WITH_CONSTRUCTOR]);
+  }
+
   void test_undefinedOperator_indexBoth() {
     Source source = addSource(r'''
 class A {}
diff --git a/pkg/analyzer/test/generated/type_system_test.dart b/pkg/analyzer/test/generated/type_system_test.dart
index d49c75c..289249a 100644
--- a/pkg/analyzer/test/generated/type_system_test.dart
+++ b/pkg/analyzer/test/generated/type_system_test.dart
@@ -23,6 +23,564 @@
 }
 
 @reflectiveTest
+class StrongAssignabilityTest {
+  TypeProvider typeProvider;
+  TypeSystem typeSystem;
+
+  DartType get bottomType => typeProvider.bottomType;
+  InterfaceType get doubleType => typeProvider.doubleType;
+  DartType get dynamicType => typeProvider.dynamicType;
+  InterfaceType get functionType => typeProvider.functionType;
+  InterfaceType get intType => typeProvider.intType;
+  InterfaceType get listType => typeProvider.listType;
+  InterfaceType get numType => typeProvider.numType;
+  InterfaceType get objectType => typeProvider.objectType;
+  InterfaceType get stringType => typeProvider.stringType;
+  DartType get voidType => VoidTypeImpl.instance;
+
+  void setUp() {
+    typeProvider = new TestTypeProvider();
+    typeSystem = new StrongTypeSystemImpl();
+  }
+
+  void test_isAssignableTo_bottom_isBottom() {
+    DartType interfaceType = ElementFactory.classElement2('A', []).type;
+    List<DartType> interassignable = <DartType>[
+      dynamicType,
+      objectType,
+      intType,
+      doubleType,
+      numType,
+      stringType,
+      interfaceType,
+      bottomType
+    ];
+
+    _checkGroups(bottomType, interassignable: interassignable);
+  }
+
+  void test_isAssignableTo_call_method() {
+    ClassElementImpl classBottom = ElementFactory.classElement2("B");
+    MethodElement methodBottom =
+        ElementFactory.methodElement("call", objectType, <DartType>[intType]);
+    classBottom.methods = <MethodElement>[methodBottom];
+
+    DartType top = TypeBuilder.functionType(<DartType>[intType], objectType);
+    InterfaceType bottom = classBottom.type;
+
+    _checkIsStrictAssignableTo(bottom, top);
+  }
+
+  void test_isAssignableTo_classes() {
+    ClassElement classTop = ElementFactory.classElement2("A");
+    ClassElement classLeft = ElementFactory.classElement("B", classTop.type);
+    ClassElement classRight = ElementFactory.classElement("C", classTop.type);
+    ClassElement classBottom = ElementFactory.classElement("D", classLeft.type)
+      ..interfaces = <InterfaceType>[classRight.type];
+    InterfaceType top = classTop.type;
+    InterfaceType left = classLeft.type;
+    InterfaceType right = classRight.type;
+    InterfaceType bottom = classBottom.type;
+
+    _checkLattice(top, left, right, bottom);
+  }
+
+  void test_isAssignableTo_double() {
+    DartType interfaceType = ElementFactory.classElement2('A', []).type;
+    List<DartType> interassignable = <DartType>[
+      dynamicType,
+      objectType,
+      doubleType,
+      numType,
+      bottomType
+    ];
+    List<DartType> unrelated = <DartType>[intType, stringType, interfaceType,];
+
+    _checkGroups(doubleType,
+        interassignable: interassignable, unrelated: unrelated);
+  }
+
+  void test_isAssignableTo_dynamic_isTop() {
+    DartType interfaceType = ElementFactory.classElement2('A', []).type;
+    List<DartType> interassignable = <DartType>[
+      dynamicType,
+      objectType,
+      intType,
+      doubleType,
+      numType,
+      stringType,
+      interfaceType,
+      bottomType
+    ];
+    _checkGroups(dynamicType, interassignable: interassignable);
+  }
+
+  void test_isAssignableTo_fuzzy_arrows() {
+    FunctionType top =
+        TypeBuilder.functionType(<DartType>[dynamicType], objectType);
+    FunctionType left =
+        TypeBuilder.functionType(<DartType>[objectType], objectType);
+    FunctionType right =
+        TypeBuilder.functionType(<DartType>[dynamicType], bottomType);
+    FunctionType bottom =
+        TypeBuilder.functionType(<DartType>[objectType], bottomType);
+
+    _checkCrossLattice(top, left, right, bottom);
+  }
+
+  void test_isAssignableTo_generics() {
+    ClassElementImpl LClass = ElementFactory.classElement2('L', ["T"]);
+    InterfaceType LType = LClass.type;
+    ClassElementImpl MClass = ElementFactory.classElement2('M', ["T"]);
+    DartType typeParam = MClass.typeParameters[0].type;
+    InterfaceType superType = LType.substitute4(<DartType>[typeParam]);
+    MClass.interfaces = <InterfaceType>[superType];
+    InterfaceType MType = MClass.type;
+
+    InterfaceType top = LType.substitute4(<DartType>[dynamicType]);
+    InterfaceType left = MType.substitute4(<DartType>[dynamicType]);
+    InterfaceType right = LType.substitute4(<DartType>[intType]);
+    InterfaceType bottom = MType.substitute4(<DartType>[intType]);
+
+    _checkCrossLattice(top, left, right, bottom);
+  }
+
+  void test_isAssignableTo_int() {
+    DartType interfaceType = ElementFactory.classElement2('A', []).type;
+    List<DartType> interassignable = <DartType>[
+      dynamicType,
+      objectType,
+      intType,
+      numType,
+      bottomType
+    ];
+    List<DartType> unrelated = <DartType>[
+      doubleType,
+      stringType,
+      interfaceType,
+    ];
+
+    _checkGroups(intType,
+        interassignable: interassignable, unrelated: unrelated);
+  }
+
+  void test_isAssignableTo_named_optional() {
+    DartType r = TypeBuilder.functionType(<DartType>[intType], intType);
+    DartType o = TypeBuilder.functionType(<DartType>[], intType,
+        optional: <DartType>[intType]);
+    DartType n = TypeBuilder.functionType(<DartType>[], intType,
+        named: <String, DartType>{'x': intType});
+    DartType rr =
+        TypeBuilder.functionType(<DartType>[intType, intType], intType);
+    DartType ro = TypeBuilder.functionType(<DartType>[intType], intType,
+        optional: <DartType>[intType]);
+    DartType rn = TypeBuilder.functionType(<DartType>[intType], intType,
+        named: <String, DartType>{'x': intType});
+    DartType oo = TypeBuilder.functionType(<DartType>[], intType,
+        optional: <DartType>[intType, intType]);
+    DartType nn = TypeBuilder.functionType(<DartType>[], intType,
+        named: <String, DartType>{'x': intType, 'y': intType});
+    DartType nnn = TypeBuilder.functionType(<DartType>[], intType,
+        named: <String, DartType>{'x': intType, 'y': intType, 'z': intType});
+
+    _checkGroups(r,
+        interassignable: [r, o, ro, rn, oo], unrelated: [n, rr, nn, nnn]);
+    _checkGroups(o,
+        interassignable: [o, oo], unrelated: [n, rr, ro, rn, nn, nnn]);
+    _checkGroups(n,
+        interassignable: [n, nn, nnn], unrelated: [r, o, rr, ro, rn, oo]);
+    _checkGroups(rr,
+        interassignable: [rr, ro, oo], unrelated: [r, o, n, rn, nn, nnn]);
+    _checkGroups(ro, interassignable: [ro, oo], unrelated: [o, n, rn, nn, nnn]);
+    _checkGroups(rn,
+        interassignable: [rn], unrelated: [o, n, rr, ro, oo, nn, nnn]);
+    _checkGroups(oo, interassignable: [oo], unrelated: [n, rn, nn, nnn]);
+    _checkGroups(nn,
+        interassignable: [nn, nnn], unrelated: [r, o, rr, ro, rn, oo]);
+    _checkGroups(nnn,
+        interassignable: [nnn], unrelated: [r, o, rr, ro, rn, oo]);
+  }
+
+  void test_isAssignableTo_num() {
+    DartType interfaceType = ElementFactory.classElement2('A', []).type;
+    List<DartType> interassignable = <DartType>[
+      dynamicType,
+      objectType,
+      numType,
+      intType,
+      doubleType,
+      bottomType
+    ];
+    List<DartType> unrelated = <DartType>[stringType, interfaceType,];
+
+    _checkGroups(numType,
+        interassignable: interassignable, unrelated: unrelated);
+  }
+
+  void test_isAssignableTo_simple_function() {
+    FunctionType top =
+        TypeBuilder.functionType(<DartType>[intType], objectType);
+    FunctionType left = TypeBuilder.functionType(<DartType>[intType], intType);
+    FunctionType right =
+        TypeBuilder.functionType(<DartType>[objectType], objectType);
+    FunctionType bottom =
+        TypeBuilder.functionType(<DartType>[objectType], intType);
+
+    _checkCrossLattice(top, left, right, bottom);
+  }
+
+  void test_isAssignableTo_void_functions() {
+    FunctionType top = TypeBuilder.functionType(<DartType>[intType], voidType);
+    FunctionType bottom =
+        TypeBuilder.functionType(<DartType>[objectType], intType);
+
+    _checkEquivalent(bottom, top);
+  }
+
+  void _checkCrossLattice(
+      DartType top, DartType left, DartType right, DartType bottom) {
+    _checkGroups(top, interassignable: <DartType>[top, left, right, bottom]);
+    _checkGroups(left, interassignable: <DartType>[top, left, right, bottom]);
+    _checkGroups(right, interassignable: <DartType>[top, left, right, bottom]);
+    _checkGroups(bottom, interassignable: <DartType>[top, left, right, bottom]);
+  }
+
+  void _checkEquivalent(DartType type1, DartType type2) {
+    _checkIsAssignableTo(type1, type2);
+    _checkIsAssignableTo(type2, type1);
+  }
+
+  void _checkGroups(DartType t1,
+      {List<DartType> interassignable, List<DartType> unrelated}) {
+    if (interassignable != null) {
+      for (DartType t2 in interassignable) {
+        _checkEquivalent(t1, t2);
+      }
+    }
+    if (unrelated != null) {
+      for (DartType t2 in unrelated) {
+        _checkUnrelated(t1, t2);
+      }
+    }
+  }
+
+  void _checkIsAssignableTo(DartType type1, DartType type2) {
+    expect(typeSystem.isAssignableTo(type1, type2), true);
+  }
+
+  void _checkIsNotAssignableTo(DartType type1, DartType type2) {
+    expect(typeSystem.isAssignableTo(type1, type2), false);
+  }
+
+  void _checkIsStrictAssignableTo(DartType type1, DartType type2) {
+    _checkIsAssignableTo(type1, type2);
+    _checkIsNotAssignableTo(type2, type1);
+  }
+
+  void _checkLattice(
+      DartType top, DartType left, DartType right, DartType bottom) {
+    _checkGroups(top, interassignable: <DartType>[top, left, right, bottom]);
+    _checkGroups(left,
+        interassignable: <DartType>[top, left, bottom],
+        unrelated: <DartType>[right]);
+    _checkGroups(right,
+        interassignable: <DartType>[top, right, bottom],
+        unrelated: <DartType>[left]);
+    _checkGroups(bottom, interassignable: <DartType>[top, left, right, bottom]);
+  }
+
+  void _checkUnrelated(DartType type1, DartType type2) {
+    _checkIsNotAssignableTo(type1, type2);
+    _checkIsNotAssignableTo(type2, type1);
+  }
+}
+
+@reflectiveTest
+class StrongSubtypingTest {
+  TypeProvider typeProvider;
+  TypeSystem typeSystem;
+
+  DartType get bottomType => typeProvider.bottomType;
+  InterfaceType get doubleType => typeProvider.doubleType;
+  DartType get dynamicType => typeProvider.dynamicType;
+  InterfaceType get functionType => typeProvider.functionType;
+  InterfaceType get intType => typeProvider.intType;
+  InterfaceType get listType => typeProvider.listType;
+  InterfaceType get numType => typeProvider.numType;
+  InterfaceType get objectType => typeProvider.objectType;
+  InterfaceType get stringType => typeProvider.stringType;
+  DartType get voidType => VoidTypeImpl.instance;
+
+  void setUp() {
+    typeProvider = new TestTypeProvider();
+    typeSystem = new StrongTypeSystemImpl();
+  }
+
+  void test_isSubtypeOf_bottom_isBottom() {
+    DartType interfaceType = ElementFactory.classElement2('A', []).type;
+    List<DartType> equivalents = <DartType>[bottomType];
+    List<DartType> supertypes = <DartType>[
+      dynamicType,
+      objectType,
+      intType,
+      doubleType,
+      numType,
+      stringType,
+      functionType,
+      interfaceType
+    ];
+    _checkGroups(bottomType, equivalents: equivalents, supertypes: supertypes);
+  }
+
+  void test_isSubtypeOf_call_method() {
+    ClassElementImpl classBottom = ElementFactory.classElement2("Bottom");
+    MethodElement methodBottom =
+        ElementFactory.methodElement("call", objectType, <DartType>[intType]);
+    classBottom.methods = <MethodElement>[methodBottom];
+
+    DartType top = TypeBuilder.functionType(<DartType>[intType], objectType);
+    InterfaceType bottom = classBottom.type;
+
+    _checkIsStrictSubtypeOf(bottom, top);
+  }
+
+  void test_isSubtypeOf_classes() {
+    ClassElement classTop = ElementFactory.classElement2("A");
+    ClassElement classLeft = ElementFactory.classElement("B", classTop.type);
+    ClassElement classRight = ElementFactory.classElement("C", classTop.type);
+    ClassElement classBottom = ElementFactory.classElement("D", classLeft.type)
+      ..interfaces = <InterfaceType>[classRight.type];
+    InterfaceType top = classTop.type;
+    InterfaceType left = classLeft.type;
+    InterfaceType right = classRight.type;
+    InterfaceType bottom = classBottom.type;
+
+    _checkLattice(top, left, right, bottom);
+  }
+
+  void test_isSubtypeOf_double() {
+    List<DartType> equivalents = <DartType>[doubleType];
+    List<DartType> supertypes = <DartType>[numType];
+    List<DartType> unrelated = <DartType>[intType];
+    _checkGroups(doubleType,
+        equivalents: equivalents, supertypes: supertypes, unrelated: unrelated);
+  }
+
+  void test_isSubtypeOf_dynamic_isTop() {
+    DartType interfaceType = ElementFactory.classElement2('A', []).type;
+    List<DartType> equivalents = <DartType>[dynamicType, objectType];
+    List<DartType> subtypes = <DartType>[
+      intType,
+      doubleType,
+      numType,
+      stringType,
+      functionType,
+      interfaceType,
+      bottomType
+    ];
+    _checkGroups(dynamicType, equivalents: equivalents, subtypes: subtypes);
+  }
+
+  void test_isSubtypeOf_fuzzy_arrows() {
+    FunctionType top =
+        TypeBuilder.functionType(<DartType>[dynamicType], objectType);
+    FunctionType left =
+        TypeBuilder.functionType(<DartType>[objectType], objectType);
+    FunctionType right =
+        TypeBuilder.functionType(<DartType>[dynamicType], bottomType);
+    FunctionType bottom =
+        TypeBuilder.functionType(<DartType>[objectType], bottomType);
+
+    _checkLattice(top, left, right, bottom);
+  }
+
+  void test_isSubtypeOf_generics() {
+    ClassElementImpl LClass = ElementFactory.classElement2('L', ["T"]);
+    InterfaceType LType = LClass.type;
+    ClassElementImpl MClass = ElementFactory.classElement2('M', ["T"]);
+    DartType typeParam = MClass.typeParameters[0].type;
+    InterfaceType superType = LType.substitute4(<DartType>[typeParam]);
+    MClass.interfaces = <InterfaceType>[superType];
+    InterfaceType MType = MClass.type;
+
+    InterfaceType top = LType.substitute4(<DartType>[dynamicType]);
+    InterfaceType left = MType.substitute4(<DartType>[dynamicType]);
+    InterfaceType right = LType.substitute4(<DartType>[intType]);
+    InterfaceType bottom = MType.substitute4(<DartType>[intType]);
+
+    _checkLattice(top, left, right, bottom);
+  }
+
+  void test_isSubtypeOf_int() {
+    List<DartType> equivalents = <DartType>[intType];
+    List<DartType> supertypes = <DartType>[numType];
+    List<DartType> unrelated = <DartType>[doubleType];
+    _checkGroups(intType,
+        equivalents: equivalents, supertypes: supertypes, unrelated: unrelated);
+  }
+
+  void test_isSubtypeOf_named_optional() {
+    DartType r = TypeBuilder.functionType(<DartType>[intType], intType);
+    DartType o = TypeBuilder.functionType(<DartType>[], intType,
+        optional: <DartType>[intType]);
+    DartType n = TypeBuilder.functionType(<DartType>[], intType,
+        named: <String, DartType>{'x': intType});
+    DartType rr =
+        TypeBuilder.functionType(<DartType>[intType, intType], intType);
+    DartType ro = TypeBuilder.functionType(<DartType>[intType], intType,
+        optional: <DartType>[intType]);
+    DartType rn = TypeBuilder.functionType(<DartType>[intType], intType,
+        named: <String, DartType>{'x': intType});
+    DartType oo = TypeBuilder.functionType(<DartType>[], intType,
+        optional: <DartType>[intType, intType]);
+    DartType nn = TypeBuilder.functionType(<DartType>[], intType,
+        named: <String, DartType>{'x': intType, 'y': intType});
+    DartType nnn = TypeBuilder.functionType(<DartType>[], intType,
+        named: <String, DartType>{'x': intType, 'y': intType, 'z': intType});
+
+    _checkGroups(r,
+        equivalents: [r],
+        subtypes: [o, ro, rn, oo],
+        unrelated: [n, rr, nn, nnn]);
+    _checkGroups(o,
+        equivalents: [o], subtypes: [oo], unrelated: [n, rr, ro, rn, nn, nnn]);
+    _checkGroups(n,
+        equivalents: [n],
+        subtypes: [nn, nnn],
+        unrelated: [r, o, rr, ro, rn, oo]);
+    _checkGroups(rr,
+        equivalents: [rr],
+        subtypes: [ro, oo],
+        unrelated: [r, o, n, rn, nn, nnn]);
+    _checkGroups(ro,
+        equivalents: [ro], subtypes: [oo], unrelated: [o, n, rn, nn, nnn]);
+    _checkGroups(rn,
+        equivalents: [rn],
+        subtypes: [],
+        unrelated: [o, n, rr, ro, oo, nn, nnn]);
+    _checkGroups(oo,
+        equivalents: [oo], subtypes: [], unrelated: [n, rn, nn, nnn]);
+    _checkGroups(nn,
+        equivalents: [nn], subtypes: [nnn], unrelated: [r, o, rr, ro, rn, oo]);
+    _checkGroups(nnn,
+        equivalents: [nnn], subtypes: [], unrelated: [r, o, rr, ro, rn, oo]);
+  }
+
+  void test_isSubtypeOf_num() {
+    List<DartType> equivalents = <DartType>[numType];
+    List<DartType> supertypes = <DartType>[];
+    List<DartType> unrelated = <DartType>[stringType];
+    List<DartType> subtypes = <DartType>[intType, doubleType];
+    _checkGroups(numType,
+        equivalents: equivalents,
+        supertypes: supertypes,
+        unrelated: unrelated,
+        subtypes: subtypes);
+  }
+
+  void test_isSubtypeOf_simple_function() {
+    FunctionType top =
+        TypeBuilder.functionType(<DartType>[intType], objectType);
+    FunctionType left = TypeBuilder.functionType(<DartType>[intType], intType);
+    FunctionType right =
+        TypeBuilder.functionType(<DartType>[objectType], objectType);
+    FunctionType bottom =
+        TypeBuilder.functionType(<DartType>[objectType], intType);
+
+    _checkLattice(top, left, right, bottom);
+  }
+
+  void test_isSubtypeOf_void_functions() {
+    FunctionType top = TypeBuilder.functionType(<DartType>[intType], voidType);
+    FunctionType bottom =
+        TypeBuilder.functionType(<DartType>[objectType], intType);
+
+    _checkIsStrictSubtypeOf(bottom, top);
+  }
+
+  void _checkEquivalent(DartType type1, DartType type2) {
+    _checkIsSubtypeOf(type1, type2);
+    _checkIsSubtypeOf(type2, type1);
+  }
+
+  void _checkGroups(DartType t1,
+      {List<DartType> equivalents,
+      List<DartType> unrelated,
+      List<DartType> subtypes,
+      List<DartType> supertypes}) {
+    if (equivalents != null) {
+      for (DartType t2 in equivalents) {
+        _checkEquivalent(t1, t2);
+      }
+    }
+    if (unrelated != null) {
+      for (DartType t2 in unrelated) {
+        _checkUnrelated(t1, t2);
+      }
+    }
+    if (subtypes != null) {
+      for (DartType t2 in subtypes) {
+        _checkIsStrictSubtypeOf(t2, t1);
+      }
+    }
+    if (supertypes != null) {
+      for (DartType t2 in supertypes) {
+        _checkIsStrictSubtypeOf(t1, t2);
+      }
+    }
+  }
+
+  void _checkIsNotSubtypeOf(DartType type1, DartType type2) {
+    expect(typeSystem.isSubtypeOf(type1, type2), false);
+  }
+
+  void _checkIsStrictSubtypeOf(DartType type1, DartType type2) {
+    _checkIsSubtypeOf(type1, type2);
+    _checkIsNotSubtypeOf(type2, type1);
+  }
+
+  void _checkIsSubtypeOf(DartType type1, DartType type2) {
+    expect(typeSystem.isSubtypeOf(type1, type2), true);
+  }
+
+  void _checkLattice(
+      DartType top, DartType left, DartType right, DartType bottom) {
+    _checkGroups(top,
+        equivalents: <DartType>[top],
+        subtypes: <DartType>[left, right, bottom]);
+    _checkGroups(left,
+        equivalents: <DartType>[left],
+        subtypes: <DartType>[bottom],
+        unrelated: <DartType>[right],
+        supertypes: <DartType>[top]);
+    _checkGroups(right,
+        equivalents: <DartType>[right],
+        subtypes: <DartType>[bottom],
+        unrelated: <DartType>[left],
+        supertypes: <DartType>[top]);
+    _checkGroups(bottom,
+        equivalents: <DartType>[bottom],
+        supertypes: <DartType>[top, left, right]);
+  }
+
+  void _checkUnrelated(DartType type1, DartType type2) {
+    _checkIsNotSubtypeOf(type1, type2);
+    _checkIsNotSubtypeOf(type2, type1);
+  }
+}
+
+class TypeBuilder {
+  static FunctionType functionType(
+      List<DartType> parameters, DartType returnType,
+      {List<DartType> optional, Map<String, DartType> named}) {
+    return ElementFactory
+        .functionElement8(parameters, returnType,
+            optional: optional, named: named)
+        .type;
+  }
+}
+
+@reflectiveTest
 class TypeSystemTest {
   TypeProvider typeProvider;
   TypeSystem typeSystem;
@@ -368,561 +926,3 @@
         expectedResult);
   }
 }
-
-class TypeBuilder {
-  static FunctionType functionType(
-      List<DartType> parameters, DartType returnType,
-      {List<DartType> optional, Map<String, DartType> named}) {
-    return ElementFactory
-        .functionElement8(parameters, returnType,
-            optional: optional, named: named)
-        .type;
-  }
-}
-
-@reflectiveTest
-class StrongSubtypingTest {
-  TypeProvider typeProvider;
-  TypeSystem typeSystem;
-
-  DartType get bottomType => typeProvider.bottomType;
-  InterfaceType get doubleType => typeProvider.doubleType;
-  DartType get dynamicType => typeProvider.dynamicType;
-  InterfaceType get functionType => typeProvider.functionType;
-  InterfaceType get intType => typeProvider.intType;
-  InterfaceType get listType => typeProvider.listType;
-  InterfaceType get numType => typeProvider.numType;
-  InterfaceType get objectType => typeProvider.objectType;
-  InterfaceType get stringType => typeProvider.stringType;
-  DartType get voidType => VoidTypeImpl.instance;
-
-  void setUp() {
-    typeProvider = new TestTypeProvider();
-    typeSystem = new StrongTypeSystemImpl();
-  }
-
-  void test_isSubtypeOf_dynamic_isTop() {
-    DartType interfaceType = ElementFactory.classElement2('A', []).type;
-    List<DartType> equivalents = <DartType>[dynamicType, objectType];
-    List<DartType> subtypes = <DartType>[
-      intType,
-      doubleType,
-      numType,
-      stringType,
-      functionType,
-      interfaceType,
-      bottomType
-    ];
-    _checkGroups(dynamicType, equivalents: equivalents, subtypes: subtypes);
-  }
-
-  void test_isSubtypeOf_bottom_isBottom() {
-    DartType interfaceType = ElementFactory.classElement2('A', []).type;
-    List<DartType> equivalents = <DartType>[bottomType];
-    List<DartType> supertypes = <DartType>[
-      dynamicType,
-      objectType,
-      intType,
-      doubleType,
-      numType,
-      stringType,
-      functionType,
-      interfaceType
-    ];
-    _checkGroups(bottomType, equivalents: equivalents, supertypes: supertypes);
-  }
-
-  void test_isSubtypeOf_int() {
-    List<DartType> equivalents = <DartType>[intType];
-    List<DartType> supertypes = <DartType>[numType];
-    List<DartType> unrelated = <DartType>[doubleType];
-    _checkGroups(intType,
-        equivalents: equivalents, supertypes: supertypes, unrelated: unrelated);
-  }
-
-  void test_isSubtypeOf_double() {
-    List<DartType> equivalents = <DartType>[doubleType];
-    List<DartType> supertypes = <DartType>[numType];
-    List<DartType> unrelated = <DartType>[intType];
-    _checkGroups(doubleType,
-        equivalents: equivalents, supertypes: supertypes, unrelated: unrelated);
-  }
-
-  void test_isSubtypeOf_num() {
-    List<DartType> equivalents = <DartType>[numType];
-    List<DartType> supertypes = <DartType>[];
-    List<DartType> unrelated = <DartType>[stringType];
-    List<DartType> subtypes = <DartType>[intType, doubleType];
-    _checkGroups(numType,
-        equivalents: equivalents,
-        supertypes: supertypes,
-        unrelated: unrelated,
-        subtypes: subtypes);
-  }
-
-  void test_isSubtypeOf_classes() {
-    ClassElement classTop = ElementFactory.classElement2("A");
-    ClassElement classLeft = ElementFactory.classElement("B", classTop.type);
-    ClassElement classRight = ElementFactory.classElement("C", classTop.type);
-    ClassElement classBottom = ElementFactory.classElement("D", classLeft.type)
-      ..interfaces = <InterfaceType>[classRight.type];
-    InterfaceType top = classTop.type;
-    InterfaceType left = classLeft.type;
-    InterfaceType right = classRight.type;
-    InterfaceType bottom = classBottom.type;
-
-    _checkLattice(top, left, right, bottom);
-  }
-
-  void test_isSubtypeOf_simple_function() {
-    FunctionType top =
-        TypeBuilder.functionType(<DartType>[intType], objectType);
-    FunctionType left = TypeBuilder.functionType(<DartType>[intType], intType);
-    FunctionType right =
-        TypeBuilder.functionType(<DartType>[objectType], objectType);
-    FunctionType bottom =
-        TypeBuilder.functionType(<DartType>[objectType], intType);
-
-    _checkLattice(top, left, right, bottom);
-  }
-
-  void test_isSubtypeOf_call_method() {
-    ClassElementImpl classBottom = ElementFactory.classElement2("Bottom");
-    MethodElement methodBottom =
-        ElementFactory.methodElement("call", objectType, <DartType>[intType]);
-    classBottom.methods = <MethodElement>[methodBottom];
-
-    DartType top = TypeBuilder.functionType(<DartType>[intType], objectType);
-    InterfaceType bottom = classBottom.type;
-
-    _checkIsStrictSubtypeOf(bottom, top);
-  }
-
-  void test_isSubtypeOf_fuzzy_arrows() {
-    FunctionType top =
-        TypeBuilder.functionType(<DartType>[dynamicType], objectType);
-    FunctionType left =
-        TypeBuilder.functionType(<DartType>[objectType], objectType);
-    FunctionType right =
-        TypeBuilder.functionType(<DartType>[dynamicType], bottomType);
-    FunctionType bottom =
-        TypeBuilder.functionType(<DartType>[objectType], bottomType);
-
-    _checkLattice(top, left, right, bottom);
-  }
-
-  void test_isSubtypeOf_void_functions() {
-    FunctionType top = TypeBuilder.functionType(<DartType>[intType], voidType);
-    FunctionType bottom =
-        TypeBuilder.functionType(<DartType>[objectType], intType);
-
-    _checkIsStrictSubtypeOf(bottom, top);
-  }
-
-  void test_isSubtypeOf_named_optional() {
-    DartType r = TypeBuilder.functionType(<DartType>[intType], intType);
-    DartType o = TypeBuilder.functionType(<DartType>[], intType,
-        optional: <DartType>[intType]);
-    DartType n = TypeBuilder.functionType(<DartType>[], intType,
-        named: <String, DartType>{'x': intType});
-    DartType rr =
-        TypeBuilder.functionType(<DartType>[intType, intType], intType);
-    DartType ro = TypeBuilder.functionType(<DartType>[intType], intType,
-        optional: <DartType>[intType]);
-    DartType rn = TypeBuilder.functionType(<DartType>[intType], intType,
-        named: <String, DartType>{'x': intType});
-    DartType oo = TypeBuilder.functionType(<DartType>[], intType,
-        optional: <DartType>[intType, intType]);
-    DartType nn = TypeBuilder.functionType(<DartType>[], intType,
-        named: <String, DartType>{'x': intType, 'y': intType});
-    DartType nnn = TypeBuilder.functionType(<DartType>[], intType,
-        named: <String, DartType>{'x': intType, 'y': intType, 'z': intType});
-
-    _checkGroups(r,
-        equivalents: [r],
-        subtypes: [o, ro, rn, oo],
-        unrelated: [n, rr, nn, nnn]);
-    _checkGroups(o,
-        equivalents: [o], subtypes: [oo], unrelated: [n, rr, ro, rn, nn, nnn]);
-    _checkGroups(n,
-        equivalents: [n],
-        subtypes: [nn, nnn],
-        unrelated: [r, o, rr, ro, rn, oo]);
-    _checkGroups(rr,
-        equivalents: [rr],
-        subtypes: [ro, oo],
-        unrelated: [r, o, n, rn, nn, nnn]);
-    _checkGroups(ro,
-        equivalents: [ro], subtypes: [oo], unrelated: [o, n, rn, nn, nnn]);
-    _checkGroups(rn,
-        equivalents: [rn],
-        subtypes: [],
-        unrelated: [o, n, rr, ro, oo, nn, nnn]);
-    _checkGroups(oo,
-        equivalents: [oo], subtypes: [], unrelated: [n, rn, nn, nnn]);
-    _checkGroups(nn,
-        equivalents: [nn], subtypes: [nnn], unrelated: [r, o, rr, ro, rn, oo]);
-    _checkGroups(nnn,
-        equivalents: [nnn], subtypes: [], unrelated: [r, o, rr, ro, rn, oo]);
-  }
-
-  void test_isSubtypeOf_generics() {
-    ClassElementImpl LClass = ElementFactory.classElement2('L', ["T"]);
-    InterfaceType LType = LClass.type;
-    ClassElementImpl MClass = ElementFactory.classElement2('M', ["T"]);
-    DartType typeParam = MClass.typeParameters[0].type;
-    InterfaceType superType = LType.substitute4(<DartType>[typeParam]);
-    MClass.interfaces = <InterfaceType>[superType];
-    InterfaceType MType = MClass.type;
-
-    InterfaceType top = LType.substitute4(<DartType>[dynamicType]);
-    InterfaceType left = MType.substitute4(<DartType>[dynamicType]);
-    InterfaceType right = LType.substitute4(<DartType>[intType]);
-    InterfaceType bottom = MType.substitute4(<DartType>[intType]);
-
-    _checkLattice(top, left, right, bottom);
-  }
-
-  void _checkLattice(
-      DartType top, DartType left, DartType right, DartType bottom) {
-    _checkGroups(top,
-        equivalents: <DartType>[top],
-        subtypes: <DartType>[left, right, bottom]);
-    _checkGroups(left,
-        equivalents: <DartType>[left],
-        subtypes: <DartType>[bottom],
-        unrelated: <DartType>[right],
-        supertypes: <DartType>[top]);
-    _checkGroups(right,
-        equivalents: <DartType>[right],
-        subtypes: <DartType>[bottom],
-        unrelated: <DartType>[left],
-        supertypes: <DartType>[top]);
-    _checkGroups(bottom,
-        equivalents: <DartType>[bottom],
-        supertypes: <DartType>[top, left, right]);
-  }
-
-  void _checkGroups(DartType t1,
-      {List<DartType> equivalents,
-      List<DartType> unrelated,
-      List<DartType> subtypes,
-      List<DartType> supertypes}) {
-    if (equivalents != null) {
-      for (DartType t2 in equivalents) {
-        _checkEquivalent(t1, t2);
-      }
-    }
-    if (unrelated != null) {
-      for (DartType t2 in unrelated) {
-        _checkUnrelated(t1, t2);
-      }
-    }
-    if (subtypes != null) {
-      for (DartType t2 in subtypes) {
-        _checkIsStrictSubtypeOf(t2, t1);
-      }
-    }
-    if (supertypes != null) {
-      for (DartType t2 in supertypes) {
-        _checkIsStrictSubtypeOf(t1, t2);
-      }
-    }
-  }
-
-  void _checkUnrelated(DartType type1, DartType type2) {
-    _checkIsNotSubtypeOf(type1, type2);
-    _checkIsNotSubtypeOf(type2, type1);
-  }
-
-  void _checkEquivalent(DartType type1, DartType type2) {
-    _checkIsSubtypeOf(type1, type2);
-    _checkIsSubtypeOf(type2, type1);
-  }
-
-  void _checkIsStrictSubtypeOf(DartType type1, DartType type2) {
-    _checkIsSubtypeOf(type1, type2);
-    _checkIsNotSubtypeOf(type2, type1);
-  }
-
-  void _checkIsSubtypeOf(DartType type1, DartType type2) {
-    expect(typeSystem.isSubtypeOf(type1, type2), true);
-  }
-
-  void _checkIsNotSubtypeOf(DartType type1, DartType type2) {
-    expect(typeSystem.isSubtypeOf(type1, type2), false);
-  }
-}
-
-@reflectiveTest
-class StrongAssignabilityTest {
-  TypeProvider typeProvider;
-  TypeSystem typeSystem;
-
-  DartType get bottomType => typeProvider.bottomType;
-  InterfaceType get doubleType => typeProvider.doubleType;
-  DartType get dynamicType => typeProvider.dynamicType;
-  InterfaceType get functionType => typeProvider.functionType;
-  InterfaceType get intType => typeProvider.intType;
-  InterfaceType get listType => typeProvider.listType;
-  InterfaceType get numType => typeProvider.numType;
-  InterfaceType get objectType => typeProvider.objectType;
-  InterfaceType get stringType => typeProvider.stringType;
-  DartType get voidType => VoidTypeImpl.instance;
-
-  void setUp() {
-    typeProvider = new TestTypeProvider();
-    typeSystem = new StrongTypeSystemImpl();
-  }
-
-  void test_isAssignableTo_dynamic_isTop() {
-    DartType interfaceType = ElementFactory.classElement2('A', []).type;
-    List<DartType> interassignable = <DartType>[
-      dynamicType,
-      objectType,
-      intType,
-      doubleType,
-      numType,
-      stringType,
-      interfaceType,
-      bottomType
-    ];
-    _checkGroups(dynamicType, interassignable: interassignable);
-  }
-
-  void test_isAssignableTo_bottom_isBottom() {
-    DartType interfaceType = ElementFactory.classElement2('A', []).type;
-    List<DartType> interassignable = <DartType>[
-      dynamicType,
-      objectType,
-      intType,
-      doubleType,
-      numType,
-      stringType,
-      interfaceType,
-      bottomType
-    ];
-
-    _checkGroups(bottomType, interassignable: interassignable);
-  }
-
-  void test_isAssignableTo_int() {
-    DartType interfaceType = ElementFactory.classElement2('A', []).type;
-    List<DartType> interassignable = <DartType>[
-      dynamicType,
-      objectType,
-      intType,
-      numType,
-      bottomType
-    ];
-    List<DartType> unrelated = <DartType>[
-      doubleType,
-      stringType,
-      interfaceType,
-    ];
-
-    _checkGroups(intType,
-        interassignable: interassignable, unrelated: unrelated);
-  }
-
-  void test_isAssignableTo_double() {
-    DartType interfaceType = ElementFactory.classElement2('A', []).type;
-    List<DartType> interassignable = <DartType>[
-      dynamicType,
-      objectType,
-      doubleType,
-      numType,
-      bottomType
-    ];
-    List<DartType> unrelated = <DartType>[intType, stringType, interfaceType,];
-
-    _checkGroups(doubleType,
-        interassignable: interassignable, unrelated: unrelated);
-  }
-
-  void test_isAssignableTo_num() {
-    DartType interfaceType = ElementFactory.classElement2('A', []).type;
-    List<DartType> interassignable = <DartType>[
-      dynamicType,
-      objectType,
-      numType,
-      intType,
-      doubleType,
-      bottomType
-    ];
-    List<DartType> unrelated = <DartType>[stringType, interfaceType,];
-
-    _checkGroups(numType,
-        interassignable: interassignable, unrelated: unrelated);
-  }
-
-  void test_isAssignableTo_classes() {
-    ClassElement classTop = ElementFactory.classElement2("A");
-    ClassElement classLeft = ElementFactory.classElement("B", classTop.type);
-    ClassElement classRight = ElementFactory.classElement("C", classTop.type);
-    ClassElement classBottom = ElementFactory.classElement("D", classLeft.type)
-      ..interfaces = <InterfaceType>[classRight.type];
-    InterfaceType top = classTop.type;
-    InterfaceType left = classLeft.type;
-    InterfaceType right = classRight.type;
-    InterfaceType bottom = classBottom.type;
-
-    _checkLattice(top, left, right, bottom);
-  }
-
-  void test_isAssignableTo_simple_function() {
-    FunctionType top =
-        TypeBuilder.functionType(<DartType>[intType], objectType);
-    FunctionType left = TypeBuilder.functionType(<DartType>[intType], intType);
-    FunctionType right =
-        TypeBuilder.functionType(<DartType>[objectType], objectType);
-    FunctionType bottom =
-        TypeBuilder.functionType(<DartType>[objectType], intType);
-
-    _checkCrossLattice(top, left, right, bottom);
-  }
-
-  void test_isAssignableTo_call_method() {
-    ClassElementImpl classBottom = ElementFactory.classElement2("B");
-    MethodElement methodBottom =
-        ElementFactory.methodElement("call", objectType, <DartType>[intType]);
-    classBottom.methods = <MethodElement>[methodBottom];
-
-    DartType top = TypeBuilder.functionType(<DartType>[intType], objectType);
-    InterfaceType bottom = classBottom.type;
-
-    _checkIsStrictAssignableTo(bottom, top);
-  }
-
-  void test_isAssignableTo_fuzzy_arrows() {
-    FunctionType top =
-        TypeBuilder.functionType(<DartType>[dynamicType], objectType);
-    FunctionType left =
-        TypeBuilder.functionType(<DartType>[objectType], objectType);
-    FunctionType right =
-        TypeBuilder.functionType(<DartType>[dynamicType], bottomType);
-    FunctionType bottom =
-        TypeBuilder.functionType(<DartType>[objectType], bottomType);
-
-    _checkCrossLattice(top, left, right, bottom);
-  }
-
-  void test_isAssignableTo_void_functions() {
-    FunctionType top = TypeBuilder.functionType(<DartType>[intType], voidType);
-    FunctionType bottom =
-        TypeBuilder.functionType(<DartType>[objectType], intType);
-
-    _checkEquivalent(bottom, top);
-  }
-
-  void test_isAssignableTo_named_optional() {
-    DartType r = TypeBuilder.functionType(<DartType>[intType], intType);
-    DartType o = TypeBuilder.functionType(<DartType>[], intType,
-        optional: <DartType>[intType]);
-    DartType n = TypeBuilder.functionType(<DartType>[], intType,
-        named: <String, DartType>{'x': intType});
-    DartType rr =
-        TypeBuilder.functionType(<DartType>[intType, intType], intType);
-    DartType ro = TypeBuilder.functionType(<DartType>[intType], intType,
-        optional: <DartType>[intType]);
-    DartType rn = TypeBuilder.functionType(<DartType>[intType], intType,
-        named: <String, DartType>{'x': intType});
-    DartType oo = TypeBuilder.functionType(<DartType>[], intType,
-        optional: <DartType>[intType, intType]);
-    DartType nn = TypeBuilder.functionType(<DartType>[], intType,
-        named: <String, DartType>{'x': intType, 'y': intType});
-    DartType nnn = TypeBuilder.functionType(<DartType>[], intType,
-        named: <String, DartType>{'x': intType, 'y': intType, 'z': intType});
-
-    _checkGroups(r,
-        interassignable: [r, o, ro, rn, oo], unrelated: [n, rr, nn, nnn]);
-    _checkGroups(o,
-        interassignable: [o, oo], unrelated: [n, rr, ro, rn, nn, nnn]);
-    _checkGroups(n,
-        interassignable: [n, nn, nnn], unrelated: [r, o, rr, ro, rn, oo]);
-    _checkGroups(rr,
-        interassignable: [rr, ro, oo], unrelated: [r, o, n, rn, nn, nnn]);
-    _checkGroups(ro, interassignable: [ro, oo], unrelated: [o, n, rn, nn, nnn]);
-    _checkGroups(rn,
-        interassignable: [rn], unrelated: [o, n, rr, ro, oo, nn, nnn]);
-    _checkGroups(oo, interassignable: [oo], unrelated: [n, rn, nn, nnn]);
-    _checkGroups(nn,
-        interassignable: [nn, nnn], unrelated: [r, o, rr, ro, rn, oo]);
-    _checkGroups(nnn,
-        interassignable: [nnn], unrelated: [r, o, rr, ro, rn, oo]);
-  }
-
-  void test_isAssignableTo_generics() {
-    ClassElementImpl LClass = ElementFactory.classElement2('L', ["T"]);
-    InterfaceType LType = LClass.type;
-    ClassElementImpl MClass = ElementFactory.classElement2('M', ["T"]);
-    DartType typeParam = MClass.typeParameters[0].type;
-    InterfaceType superType = LType.substitute4(<DartType>[typeParam]);
-    MClass.interfaces = <InterfaceType>[superType];
-    InterfaceType MType = MClass.type;
-
-    InterfaceType top = LType.substitute4(<DartType>[dynamicType]);
-    InterfaceType left = MType.substitute4(<DartType>[dynamicType]);
-    InterfaceType right = LType.substitute4(<DartType>[intType]);
-    InterfaceType bottom = MType.substitute4(<DartType>[intType]);
-
-    _checkCrossLattice(top, left, right, bottom);
-  }
-
-  void _checkCrossLattice(
-      DartType top, DartType left, DartType right, DartType bottom) {
-    _checkGroups(top, interassignable: <DartType>[top, left, right, bottom]);
-    _checkGroups(left, interassignable: <DartType>[top, left, right, bottom]);
-    _checkGroups(right, interassignable: <DartType>[top, left, right, bottom]);
-    _checkGroups(bottom, interassignable: <DartType>[top, left, right, bottom]);
-  }
-
-  void _checkLattice(
-      DartType top, DartType left, DartType right, DartType bottom) {
-    _checkGroups(top, interassignable: <DartType>[top, left, right, bottom]);
-    _checkGroups(left,
-        interassignable: <DartType>[top, left, bottom],
-        unrelated: <DartType>[right]);
-    _checkGroups(right,
-        interassignable: <DartType>[top, right, bottom],
-        unrelated: <DartType>[left]);
-    _checkGroups(bottom, interassignable: <DartType>[top, left, right, bottom]);
-  }
-
-  void _checkGroups(DartType t1,
-      {List<DartType> interassignable, List<DartType> unrelated}) {
-    if (interassignable != null) {
-      for (DartType t2 in interassignable) {
-        _checkEquivalent(t1, t2);
-      }
-    }
-    if (unrelated != null) {
-      for (DartType t2 in unrelated) {
-        _checkUnrelated(t1, t2);
-      }
-    }
-  }
-
-  void _checkUnrelated(DartType type1, DartType type2) {
-    _checkIsNotAssignableTo(type1, type2);
-    _checkIsNotAssignableTo(type2, type1);
-  }
-
-  void _checkEquivalent(DartType type1, DartType type2) {
-    _checkIsAssignableTo(type1, type2);
-    _checkIsAssignableTo(type2, type1);
-  }
-
-  void _checkIsStrictAssignableTo(DartType type1, DartType type2) {
-    _checkIsAssignableTo(type1, type2);
-    _checkIsNotAssignableTo(type2, type1);
-  }
-
-  void _checkIsAssignableTo(DartType type1, DartType type2) {
-    expect(typeSystem.isAssignableTo(type1, type2), true);
-  }
-
-  void _checkIsNotAssignableTo(DartType type1, DartType type2) {
-    expect(typeSystem.isAssignableTo(type1, type2), false);
-  }
-}
diff --git a/pkg/analyzer/test/generated/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index 24263e7..c156aac 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -4566,6 +4566,21 @@
 
 @reflectiveTest
 class StringUtilitiesTest {
+  void test_computeLineStarts_n() {
+    List<int> starts = StringUtilities.computeLineStarts('a\nbb\nccc');
+    expect(starts, <int>[0, 2, 5]);
+  }
+
+  void test_computeLineStarts_r() {
+    List<int> starts = StringUtilities.computeLineStarts('a\rbb\rccc');
+    expect(starts, <int>[0, 2, 5]);
+  }
+
+  void test_computeLineStarts_rn() {
+    List<int> starts = StringUtilities.computeLineStarts('a\r\nbb\r\nccc');
+    expect(starts, <int>[0, 3, 7]);
+  }
+
   void test_EMPTY() {
     expect(StringUtilities.EMPTY, "");
     expect(StringUtilities.EMPTY.isEmpty, isTrue);
diff --git a/pkg/analyzer/test/instrumentation/instrumentation_test.dart b/pkg/analyzer/test/instrumentation/instrumentation_test.dart
index 290b71a..ac8755e 100644
--- a/pkg/analyzer/test/instrumentation/instrumentation_test.dart
+++ b/pkg/analyzer/test/instrumentation/instrumentation_test.dart
@@ -4,6 +4,8 @@
 
 library test.instrumentation;
 
+import 'dart:async';
+
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:unittest/unittest.dart';
 
@@ -174,7 +176,7 @@
   }
 
   @override
-  void shutdown() {
+  Future shutdown() async {
     // Ignored
   }
 }
diff --git a/pkg/analyzer/test/source/analysis_options_provider_test.dart b/pkg/analyzer/test/source/analysis_options_provider_test.dart
index 4cf41fd..92b8cfc 100644
--- a/pkg/analyzer/test/source/analysis_options_provider_test.dart
+++ b/pkg/analyzer/test/source/analysis_options_provider_test.dart
@@ -13,6 +13,60 @@
 
 main() {
   initializeTestEnvironment();
+
+  group('AnalysisOptionsProvider', () {
+    void expectMergesTo(String defaults, String overrides, String expected) {
+      var optionsProvider = new AnalysisOptionsProvider();
+      var defaultOptions = optionsProvider.getOptionsFromString(defaults);
+      var overrideOptions = optionsProvider.getOptionsFromString(overrides);
+      var merged = optionsProvider.merge(defaultOptions, overrideOptions);
+      expect(merged, optionsProvider.getOptionsFromString(expected));
+    }
+
+    group('merging', () {
+      test('integration', () {
+        expectMergesTo(
+            '''
+analyzer:
+  plugins:
+    - p1
+    - p2
+  errors:
+    unused_local_variable : error
+linter:
+  rules:
+    - camel_case_types
+    - one_member_abstracts
+''',
+            '''
+analyzer:
+  plugins:
+    - p3
+  errors:
+    unused_local_variable : ignore # overrides error
+linter:
+  rules:
+    one_member_abstracts: false # promotes and disables
+    always_specify_return_types: true
+''',
+            '''
+analyzer:
+  plugins:
+    - p1
+    - p2
+    - p3
+  errors:
+    unused_local_variable : ignore
+linter:
+  rules:
+    camel_case_types: true
+    one_member_abstracts: false
+    always_specify_return_types: true
+''');
+      });
+    });
+  });
+
   group('AnalysisOptionsProvider', () {
     setUp(() {
       buildResourceProvider();
@@ -24,21 +78,21 @@
       var optionsProvider = new AnalysisOptionsProvider();
       Map<String, YamlNode> options =
           optionsProvider.getOptions(resourceProvider.getFolder('/'));
-      expect(options.length, equals(1));
+      expect(options, hasLength(1));
       expect(options['analyzer'], isNotNull);
       YamlMap analyzer = options['analyzer'];
-      expect(analyzer.length, equals(1));
+      expect(analyzer, hasLength(1));
       expect(analyzer['ignore'], isNotNull);
       YamlList ignore = analyzer['ignore'];
-      expect(ignore.length, equals(2));
-      expect(ignore[0], equals('ignoreme.dart'));
-      expect(ignore[1], equals('sdk_ext/**'));
+      expect(ignore, hasLength(2));
+      expect(ignore[0], 'ignoreme.dart');
+      expect(ignore[1], 'sdk_ext/**');
     });
     test('test_doesnotexist', () {
       var optionsProvider = new AnalysisOptionsProvider();
       Map<String, YamlNode> options =
           optionsProvider.getOptions(resourceProvider.getFolder('/empty'));
-      expect(options.length, equals(0));
+      expect(options, isEmpty);
     });
   });
   group('AnalysisOptionsProvider', () {
@@ -75,12 +129,37 @@
       expect(exceptionCaught, isTrue);
     });
   });
+  group('AnalysisOptionsProvider', () {
+    test('test_bad_yaml (1)', () {
+      var src = '''
+    analyzer: # <= bang
+strong-mode: true
+''';
+
+      var optionsProvider = new AnalysisOptionsProvider();
+      expect(() => optionsProvider.getOptionsFromString(src),
+          throwsA(new isInstanceOf<OptionsFormatException>()));
+    });
+
+    test('test_bad_yaml (2)', () {
+      var src = '''
+analyzer:
+  strong-mode:true # missing space (sdk/issues/24885)
+''';
+
+      var optionsProvider = new AnalysisOptionsProvider();
+      // Should not throw an exception.
+      var options = optionsProvider.getOptionsFromString(src);
+      // Should return a non-null options list.
+      expect(options, isNotNull);
+    });
+  });
 }
 
 MemoryResourceProvider resourceProvider;
 
-buildResourceProvider({bool emptyAnalysisOptions : false,
-                       bool badAnalysisOptions : false}) {
+buildResourceProvider(
+    {bool emptyAnalysisOptions: false, bool badAnalysisOptions: false}) {
   resourceProvider = new MemoryResourceProvider();
   resourceProvider.newFolder('/empty');
   resourceProvider.newFolder('/tmp');
@@ -90,8 +169,8 @@
     resourceProvider.newFile('/.analysis_options', r'''#empty''');
   } else {
     resourceProvider.newFile(
-      '/.analysis_options',
-      r'''
+        '/.analysis_options',
+        r'''
 analyzer:
   ignore:
     - ignoreme.dart
diff --git a/pkg/analyzer/test/source/embedder_test.dart b/pkg/analyzer/test/source/embedder_test.dart
new file mode 100644
index 0000000..ee50643
--- /dev/null
+++ b/pkg/analyzer/test/source/embedder_test.dart
@@ -0,0 +1,88 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.source.embedder;
+
+import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/source/embedder.dart';
+import 'package:unittest/unittest.dart';
+
+import '../utils.dart';
+
+main() {
+  initializeTestEnvironment();
+  group('EmbedderUriResolverTest', () {
+    setUp(() {
+      buildResourceProvider();
+    });
+    tearDown(() {
+      clearResourceProvider();
+    });
+    test('test_NullEmbedderYamls', () {
+      var resolver = new EmbedderUriResolver(null);
+      expect(resolver.length, equals(0));
+    });
+    test('test_NoEmbedderYamls', () {
+      var locator = new EmbedderYamlLocator({
+        'fox': [resourceProvider.getResource('/empty')]
+      });
+      expect(locator.embedderYamls.length, equals(0));
+    });
+    test('test_EmbedderYaml', () {
+      var locator = new EmbedderYamlLocator({
+        'fox': [resourceProvider.getResource('/tmp')]
+      });
+      var resolver = new EmbedderUriResolver(locator.embedderYamls);
+      // We have four mappings.
+      expect(resolver.length, equals(4));
+      // Check that they map to the correct paths.
+      expect(resolver['dart:fox'], equals("/tmp/slippy.dart"));
+      expect(resolver['dart:bear'], equals("/tmp/grizzly.dart"));
+      expect(resolver['dart:relative'], equals("/relative.dart"));
+      expect(resolver['dart:deep'], equals("/tmp/deep/directory/file.dart"));
+    });
+    test('test_BadYAML', () {
+      var locator = new EmbedderYamlLocator(null);
+      locator.addEmbedderYaml(null, r'''{{{,{{}}},}}''');
+      expect(locator.embedderYamls.length, equals(0));
+    });
+    test('test_restoreAbsolute', () {
+      var locator = new EmbedderYamlLocator({
+        'fox': [resourceProvider.getResource('/tmp')]
+      });
+      var resolver = new EmbedderUriResolver(locator.embedderYamls);
+      var source = resolver.resolveAbsolute(Uri.parse('dart:fox'));
+      expect(source, isNotNull);
+      // Restore source's uri.
+      var restoreUri = resolver.restoreAbsolute(source);
+      expect(restoreUri, isNotNull);
+      // Verify that it is 'dart:fox'.
+      expect(restoreUri.toString(), equals('dart:fox'));
+      expect(restoreUri.scheme, equals('dart'));
+      expect(restoreUri.path, equals('fox'));
+    });
+  });
+}
+
+MemoryResourceProvider resourceProvider;
+
+buildResourceProvider() {
+  resourceProvider = new MemoryResourceProvider();
+  resourceProvider.newFolder('/empty');
+  resourceProvider.newFolder('/tmp');
+  resourceProvider.newFile(
+      '/tmp/_embedder.yaml',
+      r'''
+embedder_libs:
+  "dart:fox": "slippy.dart"
+  "dart:bear": "grizzly.dart"
+  "dart:relative": "../relative.dart"
+  "dart:deep": "deep/directory/file.dart"
+  "fart:loudly": "nomatter.dart"
+''');
+}
+
+clearResourceProvider() {
+  resourceProvider = null;
+}
diff --git a/pkg/analyzer/test/source/test_all.dart b/pkg/analyzer/test/source/test_all.dart
index 6930bce..c47b329 100644
--- a/pkg/analyzer/test/source/test_all.dart
+++ b/pkg/analyzer/test/source/test_all.dart
@@ -8,6 +8,7 @@
 
 import '../utils.dart';
 import 'analysis_options_provider_test.dart' as analysis_options_provider_test;
+import 'embedder_test.dart' as embedder_test;
 import 'package_map_provider_test.dart' as package_map_provider_test;
 import 'package_map_resolver_test.dart' as package_map_resolver_test;
 import 'path_filter_test.dart' as path_filter_test;
@@ -18,9 +19,10 @@
   initializeTestEnvironment();
   group('source', () {
     analysis_options_provider_test.main();
+    embedder_test.main();
     package_map_provider_test.main();
     package_map_resolver_test.main();
-    sdk_ext_test.main();
     path_filter_test.main();
+    sdk_ext_test.main();
   });
 }
diff --git a/pkg/analyzer/test/src/context/context_test.dart b/pkg/analyzer/test/src/context/context_test.dart
index 4d68fd3..5fd7926 100644
--- a/pkg/analyzer/test/src/context/context_test.dart
+++ b/pkg/analyzer/test/src/context/context_test.dart
@@ -25,6 +25,7 @@
         AnalysisOptions,
         AnalysisOptionsImpl,
         AnalysisResult,
+        ApplyChangesStatus,
         CacheState,
         ChangeNotice,
         ChangeSet,
@@ -152,6 +153,19 @@
     });
   }
 
+  void test_applyChanges_add_makesExplicit() {
+    Source source = newSource('/test.dart');
+    // get the entry, it's not explicit
+    CacheEntry entry = context.getCacheEntry(source);
+    expect(entry.explicitlyAdded, isFalse);
+    // add the source
+    ChangeSet changeSet = new ChangeSet();
+    changeSet.addedSource(source);
+    context.applyChanges(changeSet);
+    // now the entry is explicit
+    expect(entry.explicitlyAdded, isTrue);
+  }
+
   Future test_applyChanges_change() {
     SourcesChangedListener listener = new SourcesChangedListener();
     context.onSourcesChanged.listen(listener.onData);
@@ -283,8 +297,9 @@
   }
 
   void test_applyChanges_overriddenSource() {
-    // Note: addSource adds the source to the contentCache.
-    Source source = addSource("/test.dart", "library test;");
+    String content = "library test;";
+    Source source = addSource("/test.dart", content);
+    context.setContents(source, content);
     context.computeErrors(source);
     while (!context.sourcesNeedingProcessing.isEmpty) {
       context.performAnalysisTask();
@@ -293,7 +308,8 @@
     // it is already overridden in the content cache.
     ChangeSet changeSet = new ChangeSet();
     changeSet.changedSource(source);
-    context.applyChanges(changeSet);
+    ApplyChangesStatus changesStatus = context.applyChanges(changeSet);
+    expect(changesStatus.hasChanges, isFalse);
     expect(context.sourcesNeedingProcessing, hasLength(0));
   }
 
@@ -708,12 +724,12 @@
   }
 
   void test_configurationData() {
-    var key = new ResultDescriptor('test_key', '');
+    var key = new ResultDescriptor('test_key', 'TEST_DEFAULT');
     var testData = ['test', 'data'];
     context.setConfigurationData(key, testData);
     expect(context.getConfigurationData(key), testData);
-    var unusedKey = new ResultDescriptor('unused_key', '');
-    expect(context.getConfigurationData(unusedKey), null);
+    var unusedKey = new ResultDescriptor('unused_key', 'UNUSED_DEFAULT');
+    expect(context.getConfigurationData(unusedKey), 'UNUSED_DEFAULT');
   }
 
   void test_dispose() {
diff --git a/pkg/analyzer/test/src/summary/summary_test.dart b/pkg/analyzer/test/src/summary/summary_test.dart
new file mode 100644
index 0000000..e0cfbca
--- /dev/null
+++ b/pkg/analyzer/test/src/summary/summary_test.dart
@@ -0,0 +1,1853 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.src.serialization.elements_test;
+
+import 'dart:typed_data';
+
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/java_engine_io.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/summary/builder.dart';
+import 'package:analyzer/src/summary/format.dart';
+import 'package:analyzer/src/summary/summarize_elements.dart'
+    as summarize_elements;
+import 'package:unittest/unittest.dart';
+
+import '../../generated/resolver_test.dart';
+import '../../reflective_tests.dart';
+
+main() {
+  groupSep = ' | ';
+  runReflectiveTests(SummarizeElementsTest);
+}
+
+/**
+ * Override of [SummaryTest] which creates summaries from the element model.
+ */
+@reflectiveTest
+class SummarizeElementsTest extends ResolverTestCase with SummaryTest {
+  @override
+  bool get checkAstDerivedData => false;
+
+  /**
+   * Serialize the library containing the given class [element], then
+   * deserialize it and return the summary of the class.
+   */
+  UnlinkedClass serializeClassElement(ClassElement element) {
+    serializeLibraryElement(element.library);
+    return findClass(element.name, failIfAbsent: true);
+  }
+
+  /**
+   * Serialize the given [library] element, then deserialize it and store the
+   * resulting summary in [lib].
+   */
+  void serializeLibraryElement(LibraryElement library) {
+    BuilderContext builderContext = new BuilderContext();
+    PrelinkedLibraryBuilder serializedLib = summarize_elements.serializeLibrary(
+        builderContext, library, typeProvider);
+    List<int> encodedLib = serializedLib.toBuffer();
+    lib = new PrelinkedLibrary.fromBuffer(encodedLib);
+  }
+
+  @override
+  void serializeLibraryText(String text, {bool allowErrors: false}) {
+    Source source = addSource(text);
+    LibraryElement library = resolve2(source);
+    if (!allowErrors) {
+      assertNoErrors(source);
+    }
+    serializeLibraryElement(library);
+    expect(unlinked.imports.length, lib.importDependencies.length);
+    expect(unlinked.references.length, lib.references.length);
+  }
+
+  @override
+  void setUp() {
+    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+    options.enableGenericMethods = true;
+    resetWithOptions(options);
+  }
+
+  test_class_no_superclass() {
+    UnlinkedClass cls = serializeClassElement(typeProvider.objectType.element);
+    expect(cls.supertype, isNull);
+  }
+}
+
+/**
+ * Base class containing most summary tests.  This allows summary tests to be
+ * re-used to exercise all the different ways in which summaries can be
+ * generated (e.g. direct from the AST, from the element model, from a
+ * "relinking" process, etc.)
+ */
+abstract class SummaryTest {
+  /**
+   * The result of serializing and then deserializing the library under test.
+   */
+  PrelinkedLibrary lib;
+
+  /**
+   * `true` if the summary was created directly from the AST (and hence
+   * contains information that is not obtainable from the element model alone).
+   * TODO(paulberry): modify the element model so that it contains all the data
+   * that summaries need, so that this flag is no longer needed.
+   */
+  bool get checkAstDerivedData;
+
+  /**
+   * Get access to the "unlinked" section of the summary.
+   */
+  UnlinkedLibrary get unlinked => lib.unlinked;
+
+  /**
+   * Convert [path] to a suitably formatted absolute path URI for the current
+   * platform.
+   */
+  String absUri(String path) {
+    return FileUtilities2.createFile(path).toURI().toString();
+  }
+
+  /**
+   * Add the given source file so that it may be referenced by the file under
+   * test.
+   */
+  addNamedSource(String filePath, String contents);
+
+  /**
+   * Verify that the [combinatorName] correctly represents the given [expected]
+   * name.
+   */
+  void checkCombinatorName(
+      UnlinkedCombinatorName combinatorName, String expected) {
+    expect(combinatorName, new isInstanceOf<UnlinkedCombinatorName>());
+    expect(combinatorName.name, expected);
+  }
+
+  /**
+   * Verify that the [dependency]th element of the dependency table represents
+   * a file reachable via the given [absoluteUri] and [relativeUri].
+   */
+  void checkDependency(int dependency, String absoluteUri, String relativeUri) {
+    if (!checkAstDerivedData) {
+      // The element model doesn't (yet) store enough information to recover
+      // relative URIs, so we have to use the absolute URI.
+      // TODO(paulberry): fix this.
+      relativeUri = absoluteUri;
+    }
+    expect(dependency, new isInstanceOf<int>());
+    expect(lib.dependencies[dependency].uri, relativeUri);
+  }
+
+  /**
+   * Verify that the given [typeRef] represents the type `dynamic`.
+   */
+  void checkDynamicTypeRef(UnlinkedTypeRef typeRef) {
+    checkTypeRef(typeRef, null, null, null);
+  }
+
+  /**
+   * Verify that the dependency table contains an entry for a file reachable
+   * via the given [absoluteUri] and [relativeUri].
+   */
+  void checkHasDependency(String absoluteUri, String relativeUri) {
+    if (!checkAstDerivedData) {
+      // The element model doesn't (yet) store enough information to recover
+      // relative URIs, so we have to use the absolute URI.
+      // TODO(paulberry): fix this.
+      relativeUri = absoluteUri;
+    }
+    for (PrelinkedDependency dep in lib.dependencies) {
+      if (dep.uri == relativeUri) {
+        return;
+      }
+    }
+    fail('Did not find dependency $absoluteUri');
+  }
+
+  /**
+   * Verify that the dependency table *does not* contain any entries for a file
+   * reachable via the given [absoluteUri] and [relativeUri].
+   */
+  void checkLacksDependency(String absoluteUri, String relativeUri) {
+    if (!checkAstDerivedData) {
+      // The element model doesn't (yet) store enough information to recover
+      // relative URIs, so we have to use the absolute URI.
+      // TODO(paulberry): fix this.
+      relativeUri = absoluteUri;
+    }
+    for (PrelinkedDependency dep in lib.dependencies) {
+      if (dep.uri == relativeUri) {
+        fail('Unexpected dependency found: $relativeUri');
+      }
+    }
+  }
+
+  /**
+   * Verify that the given [typeRef] represents a reference to a type parameter
+   * having the given [deBruijnIndex].
+   */
+  void checkParamTypeRef(UnlinkedTypeRef typeRef, int deBruijnIndex) {
+    expect(typeRef, new isInstanceOf<UnlinkedTypeRef>());
+    expect(typeRef.reference, 0);
+    expect(typeRef.typeArguments, isEmpty);
+    expect(typeRef.paramReference, deBruijnIndex);
+  }
+
+  /**
+   * Verify that the given [typeRef] represents a reference to a type declared
+   * in a file reachable via [absoluteUri] and [relativeUri], having name
+   * [expectedName].  If [expectedPrefix] is supplied, verify that the type is
+   * reached via the given prefix.  If [allowTypeParameters] is true, allow the
+   * type reference to supply type parameters.  [expectedKind] is the kind of
+   * object referenced.
+   */
+  void checkTypeRef(UnlinkedTypeRef typeRef, String absoluteUri,
+      String relativeUri, String expectedName,
+      {String expectedPrefix,
+      bool allowTypeParameters: false,
+      PrelinkedReferenceKind expectedKind:
+          PrelinkedReferenceKind.classOrEnum}) {
+    expect(typeRef, new isInstanceOf<UnlinkedTypeRef>());
+    expect(typeRef.paramReference, 0);
+    int index = typeRef.reference;
+    UnlinkedReference reference = unlinked.references[index];
+    PrelinkedReference referenceResolution = lib.references[index];
+    if (absoluteUri == null) {
+      expect(referenceResolution.dependency, 0);
+    } else {
+      checkDependency(referenceResolution.dependency, absoluteUri, relativeUri);
+    }
+    if (!allowTypeParameters) {
+      expect(typeRef.typeArguments, isEmpty);
+    }
+    if (expectedName == null) {
+      expect(reference.name, isEmpty);
+    } else {
+      expect(reference.name, expectedName);
+    }
+    if (checkAstDerivedData) {
+      if (expectedPrefix == null) {
+        expect(reference.prefix, 0);
+        expect(unlinked.prefixes[reference.prefix].name, isEmpty);
+      } else {
+        expect(reference.prefix, isNot(0));
+        expect(unlinked.prefixes[reference.prefix].name, expectedPrefix);
+      }
+    }
+    expect(referenceResolution.kind, expectedKind);
+  }
+
+  /**
+   * Verify that the given [typeRef] represents a reference to an unresolved
+   * type.
+   */
+  void checkUnresolvedTypeRef(
+      UnlinkedTypeRef typeRef, String expectedPrefix, String expectedName) {
+    // When serializing from the element model, unresolved type refs lose their
+    // name.
+    checkTypeRef(typeRef, null, null, checkAstDerivedData ? expectedName : null,
+        expectedPrefix: expectedPrefix,
+        expectedKind: PrelinkedReferenceKind.unresolved);
+  }
+
+  fail_test_import_missing() {
+    // TODO(paulberry): At the moment unresolved imports are not included in
+    // the element model, so we can't pass this test.
+    // Unresolved imports are included since this is necessary for proper
+    // dependency tracking.
+    serializeLibraryText('import "foo.dart";', allowErrors: true);
+    // Second import is the implicit import of dart:core
+    expect(unlinked.imports, hasLength(2));
+    checkDependency(lib.importDependencies[0], absUri('/foo.dart'), 'foo.dart');
+  }
+
+  /**
+   * Find the class with the given [className] in the summary, and return its
+   * [UnlinkedClass] data structure.
+   */
+  UnlinkedClass findClass(String className, {bool failIfAbsent: false}) {
+    UnlinkedClass result;
+    for (UnlinkedClass cls in unlinked.classes) {
+      if (cls.name == className) {
+        if (result != null) {
+          fail('Duplicate class $className');
+        }
+        result = cls;
+      }
+    }
+    if (result == null && failIfAbsent) {
+      fail('Class $className not found in serialized output');
+    }
+    return result;
+  }
+
+  /**
+   * Find the enum with the given [enumName] in the summary, and return its
+   * [UnlinkedEnum] data structure.
+   */
+  UnlinkedEnum findEnum(String enumName, {bool failIfAbsent: false}) {
+    UnlinkedEnum result;
+    for (UnlinkedEnum e in unlinked.enums) {
+      if (e.name == enumName) {
+        if (result != null) {
+          fail('Duplicate enum $enumName');
+        }
+        result = e;
+      }
+    }
+    if (result == null && failIfAbsent) {
+      fail('Enum $enumName not found in serialized output');
+    }
+    return result;
+  }
+
+  /**
+   * Find the executable with the given [executableName] in the summary, and
+   * return its [UnlinkedExecutable] data structure.
+   */
+  UnlinkedExecutable findExecutable(String executableName,
+      {UnlinkedClass cls, bool failIfAbsent: false}) {
+    List<UnlinkedExecutable> executables;
+    if (cls == null) {
+      executables = unlinked.executables;
+    } else {
+      executables = cls.executables;
+    }
+    UnlinkedExecutable result;
+    for (UnlinkedExecutable executable in executables) {
+      if (executable.name == executableName) {
+        if (result != null) {
+          fail('Duplicate executable $executableName');
+        }
+        result = executable;
+      }
+    }
+    if (result == null && failIfAbsent) {
+      fail('Executable $executableName not found in serialized output');
+    }
+    return result;
+  }
+
+  /**
+   * Find the typedef with the given [typedefName] in the summary, and return
+   * its [UnlinkedTypedef] data structure.
+   */
+  UnlinkedTypedef findTypedef(String typedefName, {bool failIfAbsent: false}) {
+    UnlinkedTypedef result;
+    for (UnlinkedTypedef type in unlinked.typedefs) {
+      if (type.name == typedefName) {
+        if (result != null) {
+          fail('Duplicate typedef $typedefName');
+        }
+        result = type;
+      }
+    }
+    if (result == null && failIfAbsent) {
+      fail('Typedef $typedefName not found in serialized output');
+    }
+    return result;
+  }
+
+  /**
+   * Find the top level variable with the given [variableName] in the summary,
+   * and return its [UnlinkedVariable] data structure.
+   */
+  UnlinkedVariable findVariable(String variableName,
+      {UnlinkedClass cls, bool failIfAbsent: false}) {
+    List<UnlinkedVariable> variables;
+    if (cls == null) {
+      variables = unlinked.variables;
+    } else {
+      variables = cls.fields;
+    }
+    UnlinkedVariable result;
+    for (UnlinkedVariable variable in variables) {
+      if (variable.name == variableName) {
+        if (result != null) {
+          fail('Duplicate variable $variableName');
+        }
+        result = variable;
+      }
+    }
+    if (result == null && failIfAbsent) {
+      fail('Variable $variableName not found in serialized output');
+    }
+    return result;
+  }
+
+  /**
+   * Serialize the given library [text] and return the summary of the class
+   * with the given [className].
+   */
+  UnlinkedClass serializeClassText(String text, [String className = 'C']) {
+    serializeLibraryText(text);
+    return findClass(className, failIfAbsent: true);
+  }
+
+  /**
+   * Serialize the given library [text] and return the summary of the enum with
+   * the given [enumName].
+   */
+  UnlinkedEnum serializeEnumText(String text, [String enumName = 'E']) {
+    serializeLibraryText(text);
+    return findEnum(enumName, failIfAbsent: true);
+  }
+
+  /**
+   * Serialize the given library [text] and return the summary of the
+   * executable with the given [executableName].
+   */
+  UnlinkedExecutable serializeExecutableText(String text,
+      [String executableName = 'f']) {
+    serializeLibraryText(text);
+    return findExecutable(executableName, failIfAbsent: true);
+  }
+
+  /**
+   * Serialize the given library [text], then deserialize it and store its
+   * summary in [lib].
+   */
+  void serializeLibraryText(String text, {bool allowErrors: false});
+
+  /**
+   * Serialize the given method [text] and return the summary of the executable
+   * with the given [executableName].
+   */
+  UnlinkedExecutable serializeMethodText(String text,
+      [String executableName = 'f']) {
+    serializeLibraryText('class C { $text }');
+    return findExecutable(executableName,
+        cls: findClass('C', failIfAbsent: true), failIfAbsent: true);
+  }
+
+  /**
+   * Serialize the given library [text] and return the summary of the typedef
+   * with the given [typedefName].
+   */
+  UnlinkedTypedef serializeTypedefText(String text,
+      [String typedefName = 'F']) {
+    serializeLibraryText(text);
+    return findTypedef(typedefName, failIfAbsent: true);
+  }
+
+  /**
+   * Serialize a type declaration using the given [text] as a type name, and
+   * return a summary of the corresponding [UnlinkedTypeRef].  If the type
+   * declaration needs to refer to types that are not available in core, those
+   * types may be declared in [otherDeclarations].
+   */
+  UnlinkedTypeRef serializeTypeText(String text,
+      {String otherDeclarations: '', bool allowErrors: false}) {
+    return serializeVariableText('$otherDeclarations\n$text v;',
+        allowErrors: allowErrors).type;
+  }
+
+  /**
+   * Serialize the given library [text] and return the summary of the variable
+   * with the given [variableName].
+   */
+  UnlinkedVariable serializeVariableText(String text,
+      {String variableName: 'v', bool allowErrors: false}) {
+    serializeLibraryText(text, allowErrors: allowErrors);
+    return findVariable(variableName, failIfAbsent: true);
+  }
+
+  test_cascaded_export_hide_hide() {
+    addNamedSource('/lib1.dart', 'export "lib2.dart" hide C hide B, C;');
+    addNamedSource('/lib2.dart', 'class A {} class B {} class C {}');
+    serializeLibraryText(
+        '''
+import 'lib1.dart';
+A a;
+B b;
+C c;
+    ''',
+        allowErrors: true);
+    checkTypeRef(
+        findVariable('a').type, absUri('/lib2.dart'), 'lib2.dart', 'A');
+    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
+    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
+  }
+
+  test_cascaded_export_hide_show() {
+    addNamedSource('/lib1.dart', 'export "lib2.dart" hide C show A, C;');
+    addNamedSource('/lib2.dart', 'class A {} class B {} class C {}');
+    serializeLibraryText(
+        '''
+import 'lib1.dart';
+A a;
+B b;
+C c;
+    ''',
+        allowErrors: true);
+    checkTypeRef(
+        findVariable('a').type, absUri('/lib2.dart'), 'lib2.dart', 'A');
+    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
+    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
+  }
+
+  test_cascaded_export_show_hide() {
+    addNamedSource('/lib1.dart', 'export "lib2.dart" show A, B hide B, C;');
+    addNamedSource('/lib2.dart', 'class A {} class B {} class C {}');
+    serializeLibraryText(
+        '''
+import 'lib1.dart';
+A a;
+B b;
+C c;
+    ''',
+        allowErrors: true);
+    checkTypeRef(
+        findVariable('a').type, absUri('/lib2.dart'), 'lib2.dart', 'A');
+    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
+    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
+  }
+
+  test_cascaded_export_show_show() {
+    addNamedSource('/lib1.dart', 'export "lib2.dart" show A, B show A, C;');
+    addNamedSource('/lib2.dart', 'class A {} class B {} class C {}');
+    serializeLibraryText(
+        '''
+import 'lib1.dart';
+A a;
+B b;
+C c;
+    ''',
+        allowErrors: true);
+    checkTypeRef(
+        findVariable('a').type, absUri('/lib2.dart'), 'lib2.dart', 'A');
+    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
+    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
+  }
+
+  test_cascaded_import_hide_hide() {
+    addNamedSource('/lib.dart', 'class A {} class B {} class C {}');
+    serializeLibraryText(
+        '''
+import 'lib.dart' hide C hide B, C;
+A a;
+B b;
+C c;
+    ''',
+        allowErrors: true);
+    checkTypeRef(findVariable('a').type, absUri('/lib.dart'), 'lib.dart', 'A');
+    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
+    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
+  }
+
+  test_cascaded_import_hide_show() {
+    addNamedSource('/lib.dart', 'class A {} class B {} class C {}');
+    serializeLibraryText(
+        '''
+import 'lib.dart' hide C show A, C;
+A a;
+B b;
+C c;
+    ''',
+        allowErrors: true);
+    checkTypeRef(findVariable('a').type, absUri('/lib.dart'), 'lib.dart', 'A');
+    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
+    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
+  }
+
+  test_cascaded_import_show_hide() {
+    addNamedSource('/lib.dart', 'class A {} class B {} class C {}');
+    serializeLibraryText(
+        '''
+import 'lib.dart' show A, B hide B, C;
+A a;
+B b;
+C c;
+    ''',
+        allowErrors: true);
+    checkTypeRef(findVariable('a').type, absUri('/lib.dart'), 'lib.dart', 'A');
+    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
+    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
+  }
+
+  test_cascaded_import_show_show() {
+    addNamedSource('/lib.dart', 'class A {} class B {} class C {}');
+    serializeLibraryText(
+        '''
+import 'lib.dart' show A, B show A, C;
+A a;
+B b;
+C c;
+    ''',
+        allowErrors: true);
+    checkTypeRef(findVariable('a').type, absUri('/lib.dart'), 'lib.dart', 'A');
+    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
+    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
+  }
+
+  test_class_abstract() {
+    UnlinkedClass cls = serializeClassText('abstract class C {}');
+    expect(cls.isAbstract, true);
+  }
+
+  test_class_alias_abstract() {
+    UnlinkedClass cls = serializeClassText(
+        'abstract class C = D with E; class D {} class E {}');
+    expect(cls.isAbstract, true);
+  }
+
+  test_class_alias_concrete() {
+    UnlinkedClass cls =
+        serializeClassText('class C = D with E; class D {} class E {}');
+    expect(cls.isAbstract, false);
+  }
+
+  test_class_alias_flag() {
+    UnlinkedClass cls =
+        serializeClassText('class C = D with E; class D {} class E {}');
+    expect(cls.isMixinApplication, true);
+  }
+
+  test_class_alias_mixin_order() {
+    UnlinkedClass cls = serializeClassText('''
+class C = D with E, F;
+class D {}
+class E {}
+class F {}
+''');
+    expect(cls.mixins, hasLength(2));
+    checkTypeRef(cls.mixins[0], null, null, 'E');
+    checkTypeRef(cls.mixins[1], null, null, 'F');
+  }
+
+  test_class_alias_no_implicit_constructors() {
+    UnlinkedClass cls = serializeClassText('''
+class C = D with E;
+class D {
+  D.foo();
+  D.bar();
+}
+class E {}
+''');
+    expect(cls.executables, isEmpty);
+  }
+
+  test_class_alias_supertype() {
+    UnlinkedClass cls =
+        serializeClassText('class C = D with E; class D {} class E {}');
+    checkTypeRef(cls.supertype, null, null, 'D');
+  }
+
+  test_class_concrete() {
+    UnlinkedClass cls = serializeClassText('class C {}');
+    expect(cls.isAbstract, false);
+  }
+
+  test_class_interface() {
+    UnlinkedClass cls = serializeClassText('''
+class C implements D {}
+class D {}
+''');
+    expect(cls.interfaces, hasLength(1));
+    checkTypeRef(cls.interfaces[0], null, null, 'D');
+  }
+
+  test_class_interface_order() {
+    UnlinkedClass cls = serializeClassText('''
+class C implements D, E {}
+class D {}
+class E {}
+''');
+    expect(cls.interfaces, hasLength(2));
+    checkTypeRef(cls.interfaces[0], null, null, 'D');
+    checkTypeRef(cls.interfaces[1], null, null, 'E');
+  }
+
+  test_class_mixin() {
+    UnlinkedClass cls = serializeClassText('''
+class C extends Object with D {}
+class D {}
+''');
+    expect(cls.mixins, hasLength(1));
+    checkTypeRef(cls.mixins[0], null, null, 'D');
+  }
+
+  test_class_mixin_order() {
+    UnlinkedClass cls = serializeClassText('''
+class C extends Object with D, E {}
+class D {}
+class E {}
+''');
+    expect(cls.mixins, hasLength(2));
+    checkTypeRef(cls.mixins[0], null, null, 'D');
+    checkTypeRef(cls.mixins[1], null, null, 'E');
+  }
+
+  test_class_name() {
+    var classText = 'class C {}';
+    UnlinkedClass cls = serializeClassText(classText);
+    expect(cls.name, 'C');
+    expect(cls.unit, 0);
+  }
+
+  test_class_no_flags() {
+    UnlinkedClass cls = serializeClassText('class C {}');
+    expect(cls.isAbstract, false);
+    expect(cls.isMixinApplication, false);
+  }
+
+  test_class_no_interface() {
+    UnlinkedClass cls = serializeClassText('class C {}');
+    expect(cls.interfaces, isEmpty);
+  }
+
+  test_class_no_mixins() {
+    UnlinkedClass cls = serializeClassText('class C {}');
+    expect(cls.mixins, isEmpty);
+  }
+
+  test_class_no_type_param() {
+    UnlinkedClass cls = serializeClassText('class C {}');
+    expect(cls.typeParameters, isEmpty);
+  }
+
+  test_class_non_alias_flag() {
+    UnlinkedClass cls = serializeClassText('class C {}');
+    expect(cls.isMixinApplication, false);
+  }
+
+  test_class_superclass() {
+    UnlinkedClass cls = serializeClassText('class C {}');
+    expect(cls.supertype, isNull);
+  }
+
+  test_class_superclass_explicit() {
+    UnlinkedClass cls = serializeClassText('class C extends D {} class D {}');
+    expect(cls.supertype, isNotNull);
+    checkTypeRef(cls.supertype, null, null, 'D');
+  }
+
+  test_class_type_param_bound() {
+    UnlinkedClass cls = serializeClassText('class C<T extends List> {}');
+    expect(cls.typeParameters, hasLength(1));
+    expect(cls.typeParameters[0].name, 'T');
+    expect(cls.typeParameters[0].bound, isNotNull);
+    checkTypeRef(cls.typeParameters[0].bound, 'dart:core', 'dart:core', 'List',
+        allowTypeParameters: true);
+  }
+
+  test_class_type_param_f_bound() {
+    UnlinkedClass cls = serializeClassText('class C<T, U extends List<T>> {}');
+    UnlinkedTypeRef typeArgument = cls.typeParameters[1].bound.typeArguments[0];
+    checkParamTypeRef(typeArgument, 2);
+  }
+
+  test_class_type_param_f_bound_self_ref() {
+    UnlinkedClass cls = serializeClassText('class C<T, U extends List<U>> {}');
+    UnlinkedTypeRef typeArgument = cls.typeParameters[1].bound.typeArguments[0];
+    checkParamTypeRef(typeArgument, 1);
+  }
+
+  test_class_type_param_no_bound() {
+    UnlinkedClass cls = serializeClassText('class C<T> {}');
+    expect(cls.typeParameters, hasLength(1));
+    expect(cls.typeParameters[0].name, 'T');
+    expect(cls.typeParameters[0].bound, isNull);
+  }
+
+  test_constructor() {
+    UnlinkedExecutable executable =
+        findExecutable('', cls: serializeClassText('class C { C(); }'));
+    expect(executable.kind, UnlinkedExecutableKind.constructor);
+  }
+
+  test_constructor_anonymous() {
+    UnlinkedExecutable executable =
+        findExecutable('', cls: serializeClassText('class C { C(); }'));
+    expect(executable.name, isEmpty);
+  }
+
+  test_constructor_const() {
+    UnlinkedExecutable executable =
+        findExecutable('', cls: serializeClassText('class C { const C(); }'));
+    expect(executable.isConst, isTrue);
+  }
+
+  test_constructor_factory() {
+    UnlinkedExecutable executable = findExecutable('',
+        cls: serializeClassText('class C { factory C() => null; }'));
+    expect(executable.isFactory, isTrue);
+  }
+
+  test_constructor_implicit() {
+    // Implicit constructors are not serialized.
+    UnlinkedExecutable executable = findExecutable(null,
+        cls: serializeClassText('class C { C(); }'), failIfAbsent: false);
+    expect(executable, isNull);
+  }
+
+  test_constructor_initializing_formal() {
+    UnlinkedExecutable executable = findExecutable('',
+        cls: serializeClassText('class C { C(this.x); final x; }'));
+    UnlinkedParam parameter = executable.parameters[0];
+    expect(parameter.isInitializingFormal, isTrue);
+  }
+
+  test_constructor_initializing_formal_explicit_type() {
+    UnlinkedExecutable executable = findExecutable('',
+        cls: serializeClassText('class C { C(int this.x); final x; }'));
+    UnlinkedParam parameter = executable.parameters[0];
+    checkTypeRef(parameter.type, 'dart:core', 'dart:core', 'int');
+  }
+
+  test_constructor_initializing_formal_function_typed() {
+    UnlinkedExecutable executable = findExecutable('',
+        cls: serializeClassText('class C { C(this.x()); final x; }'));
+    UnlinkedParam parameter = executable.parameters[0];
+    expect(parameter.isFunctionTyped, isTrue);
+  }
+
+  test_constructor_initializing_formal_function_typed_explicit_return_type() {
+    UnlinkedExecutable executable = findExecutable('',
+        cls: serializeClassText('class C { C(int this.x()); Function x; }'));
+    UnlinkedParam parameter = executable.parameters[0];
+    checkTypeRef(parameter.type, 'dart:core', 'dart:core', 'int');
+  }
+
+  test_constructor_initializing_formal_function_typed_implicit_return_type() {
+    UnlinkedExecutable executable = findExecutable('',
+        cls: serializeClassText('class C { C(this.x()); Function x; }'));
+    UnlinkedParam parameter = executable.parameters[0];
+    checkDynamicTypeRef(parameter.type);
+  }
+
+  test_constructor_initializing_formal_function_typed_no_prameters() {
+    UnlinkedExecutable executable = findExecutable('',
+        cls: serializeClassText('class C { C(this.x()); final x; }'));
+    UnlinkedParam parameter = executable.parameters[0];
+    expect(parameter.parameters, isEmpty);
+  }
+
+  test_constructor_initializing_formal_function_typed_prameter() {
+    UnlinkedExecutable executable = findExecutable('',
+        cls: serializeClassText('class C { C(this.x(a)); final x; }'));
+    UnlinkedParam parameter = executable.parameters[0];
+    expect(parameter.parameters, hasLength(1));
+  }
+
+  test_constructor_initializing_formal_function_typed_prameter_order() {
+    UnlinkedExecutable executable = findExecutable('',
+        cls: serializeClassText('class C { C(this.x(a, b)); final x; }'));
+    UnlinkedParam parameter = executable.parameters[0];
+    expect(parameter.parameters, hasLength(2));
+    expect(parameter.parameters[0].name, 'a');
+    expect(parameter.parameters[1].name, 'b');
+  }
+
+  test_constructor_initializing_formal_implicit_type() {
+    // Note: the implicit type of an initializing formal is the type of the
+    // field.
+    UnlinkedExecutable executable = findExecutable('',
+        cls: serializeClassText('class C { C(this.x); int x; }'));
+    UnlinkedParam parameter = executable.parameters[0];
+    checkTypeRef(parameter.type, 'dart:core', 'dart:core', 'int');
+  }
+
+  test_constructor_initializing_formal_name() {
+    UnlinkedExecutable executable = findExecutable('',
+        cls: serializeClassText('class C { C(this.x); final x; }'));
+    UnlinkedParam parameter = executable.parameters[0];
+    expect(parameter.name, 'x');
+  }
+
+  test_constructor_initializing_formal_named() {
+    // TODO(paulberry): also test default value
+    UnlinkedExecutable executable = findExecutable('',
+        cls: serializeClassText('class C { C({this.x}); final x; }'));
+    UnlinkedParam parameter = executable.parameters[0];
+    expect(parameter.kind, UnlinkedParamKind.named);
+  }
+
+  test_constructor_initializing_formal_non_function_typed() {
+    UnlinkedExecutable executable = findExecutable('',
+        cls: serializeClassText('class C { C(this.x); final x; }'));
+    UnlinkedParam parameter = executable.parameters[0];
+    expect(parameter.isFunctionTyped, isFalse);
+  }
+
+  test_constructor_initializing_formal_positional() {
+    // TODO(paulberry): also test default value
+    UnlinkedExecutable executable = findExecutable('',
+        cls: serializeClassText('class C { C([this.x]); final x; }'));
+    UnlinkedParam parameter = executable.parameters[0];
+    expect(parameter.kind, UnlinkedParamKind.positional);
+  }
+
+  test_constructor_initializing_formal_required() {
+    UnlinkedExecutable executable = findExecutable('',
+        cls: serializeClassText('class C { C(this.x); final x; }'));
+    UnlinkedParam parameter = executable.parameters[0];
+    expect(parameter.kind, UnlinkedParamKind.required);
+  }
+
+  test_constructor_named() {
+    UnlinkedExecutable executable =
+        findExecutable('foo', cls: serializeClassText('class C { C.foo(); }'));
+    expect(executable.name, 'foo');
+  }
+
+  test_constructor_non_const() {
+    UnlinkedExecutable executable =
+        findExecutable('', cls: serializeClassText('class C { C(); }'));
+    expect(executable.isConst, isFalse);
+  }
+
+  test_constructor_non_factory() {
+    UnlinkedExecutable executable =
+        findExecutable('', cls: serializeClassText('class C { C(); }'));
+    expect(executable.isFactory, isFalse);
+  }
+
+  test_constructor_return_type() {
+    UnlinkedExecutable executable =
+        findExecutable('', cls: serializeClassText('class C { C(); }'));
+    checkTypeRef(executable.returnType, null, null, 'C');
+  }
+
+  test_constructor_return_type_parameterized() {
+    UnlinkedExecutable executable =
+        findExecutable('', cls: serializeClassText('class C<T, U> { C(); }'));
+    checkTypeRef(executable.returnType, null, null, 'C',
+        allowTypeParameters: true);
+    expect(executable.returnType.typeArguments, hasLength(2));
+    {
+      UnlinkedTypeRef typeRef = executable.returnType.typeArguments[0];
+      checkParamTypeRef(typeRef, 2);
+    }
+    {
+      UnlinkedTypeRef typeRef = executable.returnType.typeArguments[1];
+      checkParamTypeRef(typeRef, 1);
+    }
+  }
+
+  test_dependencies_export_none() {
+    // Exports are not listed as dependencies since no change to the exported
+    // file can change the summary of the exporting file.
+    addNamedSource('/a.dart', 'library a; export "b.dart";');
+    addNamedSource('/b.dart', 'library b;');
+    serializeLibraryText('export "a.dart";');
+    checkLacksDependency(absUri('/a.dart'), 'a.dart');
+    checkLacksDependency(absUri('/b.dart'), 'b.dart');
+  }
+
+  test_dependencies_import_to_export() {
+    addNamedSource('/a.dart', 'library a; export "b.dart"; class A {}');
+    addNamedSource('/b.dart', 'library b;');
+    serializeLibraryText('import "a.dart"; A a;');
+    checkHasDependency(absUri('/a.dart'), 'a.dart');
+    // The main test library depends on b.dart, because names defined in
+    // b.dart are exported by a.dart.
+    checkHasDependency(absUri('/b.dart'), 'b.dart');
+  }
+
+  test_dependencies_import_to_export_in_subdirs_absolute_export() {
+    addNamedSource('/a/a.dart',
+        'library a; export "${absUri('/a/b/b.dart')}"; class A {}');
+    addNamedSource('/a/b/b.dart', 'library b;');
+    serializeLibraryText('import "a/a.dart"; A a;');
+    checkHasDependency(absUri('/a/a.dart'), 'a/a.dart');
+    // The main test library depends on b.dart, because names defined in
+    // b.dart are exported by a.dart.
+    checkHasDependency(absUri('/a/b/b.dart'), '/a/b/b.dart');
+  }
+
+  test_dependencies_import_to_export_in_subdirs_absolute_import() {
+    addNamedSource('/a/a.dart', 'library a; export "b/b.dart"; class A {}');
+    addNamedSource('/a/b/b.dart', 'library b;');
+    serializeLibraryText('import "${absUri('/a/a.dart')}"; A a;');
+    checkHasDependency(absUri('/a/a.dart'), '/a/a.dart');
+    // The main test library depends on b.dart, because names defined in
+    // b.dart are exported by a.dart.
+    checkHasDependency(absUri('/a/b/b.dart'), '/a/b/b.dart');
+  }
+
+  test_dependencies_import_to_export_in_subdirs_relative() {
+    addNamedSource('/a/a.dart', 'library a; export "b/b.dart"; class A {}');
+    addNamedSource('/a/b/b.dart', 'library b;');
+    serializeLibraryText('import "a/a.dart"; A a;');
+    checkHasDependency(absUri('/a/a.dart'), 'a/a.dart');
+    // The main test library depends on b.dart, because names defined in
+    // b.dart are exported by a.dart.
+    checkHasDependency(absUri('/a/b/b.dart'), 'a/b/b.dart');
+  }
+
+  test_dependencies_import_to_export_loop() {
+    addNamedSource('/a.dart', 'library a; export "b.dart"; class A {}');
+    addNamedSource('/b.dart', 'library b; export "a.dart";');
+    serializeLibraryText('import "a.dart"; A a;');
+    checkHasDependency(absUri('/a.dart'), 'a.dart');
+    // Serialization should have been able to walk the transitive export
+    // dependencies to b.dart without going into an infinite loop.
+    checkHasDependency(absUri('/b.dart'), 'b.dart');
+  }
+
+  test_dependencies_import_to_export_transitive_closure() {
+    addNamedSource('/a.dart', 'library a; export "b.dart"; class A {}');
+    addNamedSource('/b.dart', 'library b; export "c.dart";');
+    addNamedSource('/c.dart', 'library c;');
+    serializeLibraryText('import "a.dart"; A a;');
+    checkHasDependency(absUri('/a.dart'), 'a.dart');
+    // The main test library depends on c.dart, because names defined in
+    // c.dart are exported by b.dart and then re-exported by a.dart.
+    checkHasDependency(absUri('/c.dart'), 'c.dart');
+  }
+
+  test_dependencies_import_transitive_closure() {
+    addNamedSource(
+        '/a.dart', 'library a; import "b.dart"; class A extends B {}');
+    addNamedSource('/b.dart', 'library b; class B {}');
+    serializeLibraryText('import "a.dart"; A a;');
+    checkHasDependency(absUri('/a.dart'), 'a.dart');
+    // The main test library doesn't depend on b.dart, because no change to
+    // b.dart can possibly affect the serialized element model for it.
+    checkLacksDependency(absUri('/b.dart'), 'b.dart');
+  }
+
+  test_elements_in_part() {
+    addNamedSource(
+        '/part1.dart',
+        '''
+part of my.lib;
+
+class C {}
+enum E { v }
+var v;
+f() {}
+typedef F();
+''');
+    serializeLibraryText('library my.lib; part "part1.dart";');
+    expect(findClass('C', failIfAbsent: true).unit, 1);
+    expect(findEnum('E', failIfAbsent: true).unit, 1);
+    expect(findVariable('v', failIfAbsent: true).unit, 1);
+    expect(findExecutable('f', failIfAbsent: true).unit, 1);
+    expect(findTypedef('F', failIfAbsent: true).unit, 1);
+  }
+
+  test_enum() {
+    UnlinkedEnum e = serializeEnumText('enum E { v1 }');
+    expect(e.name, 'E');
+    expect(e.values, hasLength(1));
+    expect(e.values[0].name, 'v1');
+    expect(e.unit, 0);
+  }
+
+  test_enum_order() {
+    UnlinkedEnum e = serializeEnumText('enum E { v1, v2 }');
+    expect(e.values, hasLength(2));
+    expect(e.values[0].name, 'v1');
+    expect(e.values[1].name, 'v2');
+  }
+
+  test_executable_abstract() {
+    UnlinkedExecutable executable =
+        serializeClassText('abstract class C { f(); }').executables[0];
+    expect(executable.isAbstract, isTrue);
+  }
+
+  test_executable_concrete() {
+    UnlinkedExecutable executable =
+        serializeClassText('abstract class C { f() {} }').executables[0];
+    expect(executable.isAbstract, isFalse);
+  }
+
+  test_executable_function() {
+    UnlinkedExecutable executable = serializeExecutableText('f() {}');
+    expect(executable.kind, UnlinkedExecutableKind.functionOrMethod);
+    expect(executable.unit, 0);
+  }
+
+  test_executable_getter() {
+    UnlinkedExecutable executable = serializeExecutableText('int get f => 1;');
+    expect(executable.kind, UnlinkedExecutableKind.getter);
+    expect(findVariable('f'), isNull);
+    expect(findExecutable('f='), isNull);
+  }
+
+  test_executable_getter_type() {
+    UnlinkedExecutable executable = serializeExecutableText('int get f => 1;');
+    checkTypeRef(executable.returnType, 'dart:core', 'dart:core', 'int');
+    expect(executable.parameters, isEmpty);
+  }
+
+  test_executable_getter_type_implicit() {
+    UnlinkedExecutable executable = serializeExecutableText('get f => 1;');
+    checkDynamicTypeRef(executable.returnType);
+    expect(executable.parameters, isEmpty);
+  }
+
+  test_executable_member_function() {
+    UnlinkedExecutable executable =
+        findExecutable('f', cls: serializeClassText('class C { f() {} }'));
+    expect(executable.kind, UnlinkedExecutableKind.functionOrMethod);
+  }
+
+  test_executable_member_getter() {
+    UnlinkedClass cls = serializeClassText('class C { int get f => 1; }');
+    UnlinkedExecutable executable =
+        findExecutable('f', cls: cls, failIfAbsent: true);
+    expect(executable.kind, UnlinkedExecutableKind.getter);
+    expect(findVariable('f', cls: cls), isNull);
+    expect(findExecutable('f=', cls: cls), isNull);
+  }
+
+  test_executable_member_setter() {
+    UnlinkedClass cls = serializeClassText('class C { void set f(value) {} }');
+    UnlinkedExecutable executable =
+        findExecutable('f=', cls: cls, failIfAbsent: true);
+    expect(executable.kind, UnlinkedExecutableKind.setter);
+    expect(findVariable('f', cls: cls), isNull);
+    expect(findExecutable('f', cls: cls), isNull);
+  }
+
+  test_executable_name() {
+    UnlinkedExecutable executable = serializeExecutableText('f() {}');
+    expect(executable.name, 'f');
+  }
+
+  test_executable_no_flags() {
+    UnlinkedExecutable executable = serializeExecutableText('f() {}');
+    expect(executable.isAbstract, isFalse);
+    expect(executable.isConst, isFalse);
+    expect(executable.isFactory, isFalse);
+    expect(executable.isStatic, isFalse);
+  }
+
+  test_executable_non_static() {
+    UnlinkedExecutable executable =
+        serializeClassText('class C { f() {} }').executables[0];
+    expect(executable.isStatic, isFalse);
+  }
+
+  test_executable_non_static_top_level() {
+    // Top level executables are considered non-static.
+    UnlinkedExecutable executable = serializeExecutableText('f() {}');
+    expect(executable.isStatic, isFalse);
+  }
+
+  test_executable_param_function_typed() {
+    UnlinkedExecutable executable = serializeExecutableText('f(g()) {}');
+    expect(executable.parameters[0].isFunctionTyped, isTrue);
+  }
+
+  test_executable_param_function_typed_param() {
+    UnlinkedExecutable executable = serializeExecutableText('f(g(x)) {}');
+    expect(executable.parameters[0].parameters, hasLength(1));
+  }
+
+  test_executable_param_function_typed_param_none() {
+    UnlinkedExecutable executable = serializeExecutableText('f(g()) {}');
+    expect(executable.parameters[0].parameters, isEmpty);
+  }
+
+  test_executable_param_function_typed_param_order() {
+    UnlinkedExecutable executable = serializeExecutableText('f(g(x, y)) {}');
+    expect(executable.parameters[0].parameters, hasLength(2));
+    expect(executable.parameters[0].parameters[0].name, 'x');
+    expect(executable.parameters[0].parameters[1].name, 'y');
+  }
+
+  test_executable_param_function_typed_return_type() {
+    UnlinkedExecutable executable = serializeExecutableText('f(int g()) {}');
+    checkTypeRef(
+        executable.parameters[0].type, 'dart:core', 'dart:core', 'int');
+  }
+
+  test_executable_param_function_typed_return_type_implicit() {
+    UnlinkedExecutable executable = serializeExecutableText('f(g()) {}');
+    checkDynamicTypeRef(executable.parameters[0].type);
+  }
+
+  test_executable_param_function_typed_return_type_void() {
+    UnlinkedExecutable executable = serializeExecutableText('f(void g()) {}');
+    expect(executable.parameters[0].type, isNull);
+  }
+
+  test_executable_param_kind_named() {
+    UnlinkedExecutable executable = serializeExecutableText('f({x}) {}');
+    expect(executable.parameters[0].kind, UnlinkedParamKind.named);
+  }
+
+  test_executable_param_kind_positional() {
+    UnlinkedExecutable executable = serializeExecutableText('f([x]) {}');
+    expect(executable.parameters[0].kind, UnlinkedParamKind.positional);
+  }
+
+  test_executable_param_kind_required() {
+    UnlinkedExecutable executable = serializeExecutableText('f(x) {}');
+    expect(executable.parameters[0].kind, UnlinkedParamKind.required);
+  }
+
+  test_executable_param_name() {
+    UnlinkedExecutable executable = serializeExecutableText('f(x) {}');
+    expect(executable.parameters, hasLength(1));
+    expect(executable.parameters[0].name, 'x');
+  }
+
+  test_executable_param_no_flags() {
+    UnlinkedExecutable executable = serializeExecutableText('f(x) {}');
+    expect(executable.parameters[0].isFunctionTyped, isFalse);
+    expect(executable.parameters[0].isInitializingFormal, isFalse);
+  }
+
+  test_executable_param_non_function_typed() {
+    UnlinkedExecutable executable = serializeExecutableText('f(g) {}');
+    expect(executable.parameters[0].isFunctionTyped, isFalse);
+  }
+
+  test_executable_param_none() {
+    UnlinkedExecutable executable = serializeExecutableText('f() {}');
+    expect(executable.parameters, isEmpty);
+  }
+
+  test_executable_param_order() {
+    UnlinkedExecutable executable = serializeExecutableText('f(x, y) {}');
+    expect(executable.parameters, hasLength(2));
+    expect(executable.parameters[0].name, 'x');
+    expect(executable.parameters[1].name, 'y');
+  }
+
+  test_executable_param_type_implicit() {
+    UnlinkedExecutable executable = serializeExecutableText('f(x) {}');
+    checkDynamicTypeRef(executable.parameters[0].type);
+  }
+
+  test_executable_return_type() {
+    UnlinkedExecutable executable = serializeExecutableText('int f() => 1;');
+    checkTypeRef(executable.returnType, 'dart:core', 'dart:core', 'int');
+  }
+
+  test_executable_return_type_implicit() {
+    UnlinkedExecutable executable = serializeExecutableText('f() {}');
+    checkDynamicTypeRef(executable.returnType);
+  }
+
+  test_executable_return_type_void() {
+    UnlinkedExecutable executable = serializeExecutableText('void f() {}');
+    expect(executable.returnType, isNull);
+  }
+
+  test_executable_setter() {
+    UnlinkedExecutable executable =
+        serializeExecutableText('void set f(value) {}', 'f=');
+    expect(executable.kind, UnlinkedExecutableKind.setter);
+    expect(findVariable('f'), isNull);
+    expect(findExecutable('f'), isNull);
+  }
+
+  test_executable_setter_type() {
+    UnlinkedExecutable executable =
+        serializeExecutableText('void set f(int value) {}', 'f=');
+    expect(executable.returnType, isNull);
+    expect(executable.parameters, hasLength(1));
+    expect(executable.parameters[0].name, 'value');
+    checkTypeRef(
+        executable.parameters[0].type, 'dart:core', 'dart:core', 'int');
+  }
+
+  test_executable_static() {
+    UnlinkedExecutable executable =
+        serializeClassText('class C { static f() {} }').executables[0];
+    expect(executable.isStatic, isTrue);
+  }
+
+  test_executable_type_param_f_bound() {
+    // TODO(paulberry): also test top level executables.
+    UnlinkedExecutable ex =
+        serializeMethodText('void f<T, U extends List<T>>() {}');
+    UnlinkedTypeRef typeArgument = ex.typeParameters[1].bound.typeArguments[0];
+    checkParamTypeRef(typeArgument, 2);
+  }
+
+  test_executable_type_param_f_bound_self_ref() {
+    // TODO(paulberry): also test top level executables.
+    UnlinkedExecutable ex =
+        serializeMethodText('void f<T, U extends List<U>>() {}');
+    UnlinkedTypeRef typeArgument = ex.typeParameters[1].bound.typeArguments[0];
+    checkParamTypeRef(typeArgument, 1);
+  }
+
+  test_executable_type_param_in_parameter() {
+    // TODO(paulberry): also test top level executables.
+    UnlinkedExecutable ex = serializeMethodText('void f<T>(T t) {}');
+    checkParamTypeRef(ex.parameters[0].type, 1);
+  }
+
+  test_executable_type_param_in_return_type() {
+    // TODO(paulberry): also test top level executables.
+    UnlinkedExecutable ex = serializeMethodText('T f<T>() => null;');
+    checkParamTypeRef(ex.returnType, 1);
+  }
+
+  test_export_hide_order() {
+    serializeLibraryText('export "dart:async" hide Future, Stream;');
+    expect(unlinked.exports, hasLength(1));
+    expect(unlinked.exports[0].combinators, hasLength(1));
+    expect(unlinked.exports[0].combinators[0].shows, isEmpty);
+    expect(unlinked.exports[0].combinators[0].hides, hasLength(2));
+    checkCombinatorName(unlinked.exports[0].combinators[0].hides[0], 'Future');
+    checkCombinatorName(unlinked.exports[0].combinators[0].hides[1], 'Stream');
+  }
+
+  test_export_no_combinators() {
+    serializeLibraryText('export "dart:async";');
+    expect(unlinked.exports, hasLength(1));
+    expect(unlinked.exports[0].combinators, isEmpty);
+  }
+
+  test_export_show_order() {
+    serializeLibraryText('export "dart:async" show Future, Stream;');
+    expect(unlinked.exports, hasLength(1));
+    expect(unlinked.exports[0].combinators, hasLength(1));
+    expect(unlinked.exports[0].combinators[0].shows, hasLength(2));
+    expect(unlinked.exports[0].combinators[0].hides, isEmpty);
+    checkCombinatorName(unlinked.exports[0].combinators[0].shows[0], 'Future');
+    checkCombinatorName(unlinked.exports[0].combinators[0].shows[1], 'Stream');
+  }
+
+  test_export_uri() {
+    addNamedSource('/a.dart', 'library my.lib;');
+    String uriString = '"a.dart"';
+    String libraryText = 'export $uriString;';
+    serializeLibraryText(libraryText);
+    expect(unlinked.exports, hasLength(1));
+    expect(unlinked.exports[0].uri, 'a.dart');
+  }
+
+  test_field() {
+    UnlinkedClass cls = serializeClassText('class C { int i; }');
+    expect(findVariable('i', cls: cls), isNotNull);
+    expect(findExecutable('i', cls: cls), isNull);
+    expect(findExecutable('i=', cls: cls), isNull);
+  }
+
+  test_field_final() {
+    UnlinkedVariable variable =
+        serializeClassText('class C { final int i = 0; }').fields[0];
+    expect(variable.isFinal, isTrue);
+  }
+
+  test_field_non_final() {
+    UnlinkedVariable variable =
+        serializeClassText('class C { int i; }').fields[0];
+    expect(variable.isFinal, isFalse);
+  }
+
+  test_generic_method_in_generic_class() {
+    UnlinkedClass cls = serializeClassText(
+        'class C<T, U> { void m<V, W>(T t, U u, V v, W w) {} }');
+    List<UnlinkedParam> params = cls.executables[0].parameters;
+    checkParamTypeRef(params[0].type, 4);
+    checkParamTypeRef(params[1].type, 3);
+    checkParamTypeRef(params[2].type, 2);
+    checkParamTypeRef(params[3].type, 1);
+  }
+
+  test_import_deferred() {
+    serializeLibraryText(
+        'import "dart:async" deferred as a; main() { print(a.Future); }');
+    expect(unlinked.imports[0].isDeferred, isTrue);
+  }
+
+  test_import_dependency() {
+    serializeLibraryText('import "dart:async"; Future x;');
+    // Second import is the implicit import of dart:core
+    expect(unlinked.imports, hasLength(2));
+    checkDependency(lib.importDependencies[0], 'dart:async', 'dart:async');
+  }
+
+  test_import_explicit() {
+    serializeLibraryText('import "dart:core"; int i;');
+    expect(unlinked.imports, hasLength(1));
+    expect(unlinked.imports[0].isImplicit, isFalse);
+  }
+
+  test_import_hide_order() {
+    serializeLibraryText(
+        'import "dart:async" hide Future, Stream; Completer c;');
+    // Second import is the implicit import of dart:core
+    expect(unlinked.imports, hasLength(2));
+    expect(unlinked.imports[0].combinators, hasLength(1));
+    expect(unlinked.imports[0].combinators[0].shows, isEmpty);
+    expect(unlinked.imports[0].combinators[0].hides, hasLength(2));
+    checkCombinatorName(unlinked.imports[0].combinators[0].hides[0], 'Future');
+    checkCombinatorName(unlinked.imports[0].combinators[0].hides[1], 'Stream');
+  }
+
+  test_import_implicit() {
+    // The implicit import of dart:core is represented in the model.
+    serializeLibraryText('');
+    expect(unlinked.imports, hasLength(1));
+    checkDependency(lib.importDependencies[0], 'dart:core', 'dart:core');
+    expect(unlinked.imports[0].uri, isEmpty);
+    expect(unlinked.imports[0].prefix, 0);
+    expect(unlinked.imports[0].combinators, isEmpty);
+    expect(unlinked.imports[0].isImplicit, isTrue);
+  }
+
+  test_import_no_combinators() {
+    serializeLibraryText('import "dart:async"; Future x;');
+    // Second import is the implicit import of dart:core
+    expect(unlinked.imports, hasLength(2));
+    expect(unlinked.imports[0].combinators, isEmpty);
+  }
+
+  test_import_no_flags() {
+    serializeLibraryText('import "dart:async"; Future x;');
+    expect(unlinked.imports[0].isImplicit, isFalse);
+    expect(unlinked.imports[0].isDeferred, isFalse);
+  }
+
+  test_import_non_deferred() {
+    serializeLibraryText(
+        'import "dart:async" as a; main() { print(a.Future); }');
+    expect(unlinked.imports[0].isDeferred, isFalse);
+  }
+
+  test_import_of_file_with_missing_part() {
+    // Other references in foo.dart should be resolved even though foo.dart's
+    // part declaration for bar.dart refers to a non-existent file.
+    addNamedSource('/foo.dart', 'part "bar.dart"; class C {}');
+    serializeLibraryText('import "foo.dart"; C x;');
+    checkTypeRef(findVariable('x').type, absUri('/foo.dart'), 'foo.dart', 'C');
+  }
+
+  test_import_of_missing_export() {
+    // Other references in foo.dart should be resolved even though foo.dart's
+    // re-export of bar.dart refers to a non-existent file.
+    addNamedSource('/foo.dart', 'export "bar.dart"; class C {}');
+    serializeLibraryText('import "foo.dart"; C x;');
+    checkTypeRef(findVariable('x').type, absUri('/foo.dart'), 'foo.dart', 'C');
+  }
+
+  test_import_offset() {
+    String libraryText = '    import "dart:async"; Future x;';
+    serializeLibraryText(libraryText);
+    expect(unlinked.imports[0].offset, libraryText.indexOf('import'));
+  }
+
+  test_import_prefix_name() {
+    String libraryText = 'import "dart:async" as a; a.Future x;';
+    serializeLibraryText(libraryText);
+    // Second import is the implicit import of dart:core
+    expect(unlinked.imports, hasLength(2));
+    expect(unlinked.imports[0].prefix, isNot(0));
+    expect(unlinked.prefixes[unlinked.imports[0].prefix].name, 'a');
+  }
+
+  test_import_prefix_none() {
+    serializeLibraryText('import "dart:async"; Future x;');
+    // Second import is the implicit import of dart:core
+    expect(unlinked.imports, hasLength(2));
+    expect(unlinked.imports[0].prefix, 0);
+    expect(unlinked.prefixes[unlinked.imports[0].prefix].name, isEmpty);
+  }
+
+  test_import_prefix_reference() {
+    UnlinkedVariable variable =
+        serializeVariableText('import "dart:async" as a; a.Future v;');
+    checkTypeRef(variable.type, 'dart:async', 'dart:async', 'Future',
+        expectedPrefix: 'a');
+  }
+
+  test_import_reference() {
+    UnlinkedVariable variable =
+        serializeVariableText('import "dart:async"; Future v;');
+    checkTypeRef(variable.type, 'dart:async', 'dart:async', 'Future');
+  }
+
+  test_import_reference_merged_no_prefix() {
+    serializeLibraryText('''
+import "dart:async" show Future;
+import "dart:async" show Stream;
+
+Future f;
+Stream s;
+''');
+    checkTypeRef(findVariable('f').type, 'dart:async', 'dart:async', 'Future');
+    checkTypeRef(findVariable('s').type, 'dart:async', 'dart:async', 'Stream');
+  }
+
+  test_import_reference_merged_prefixed() {
+    serializeLibraryText('''
+import "dart:async" as a show Future;
+import "dart:async" as a show Stream;
+
+a.Future f;
+a.Stream s;
+''');
+    checkTypeRef(findVariable('f').type, 'dart:async', 'dart:async', 'Future',
+        expectedPrefix: 'a');
+    checkTypeRef(findVariable('s').type, 'dart:async', 'dart:async', 'Stream',
+        expectedPrefix: 'a');
+  }
+
+  test_import_show_order() {
+    String libraryText =
+        'import "dart:async" show Future, Stream; Future x; Stream y;';
+    serializeLibraryText(libraryText);
+    // Second import is the implicit import of dart:core
+    expect(unlinked.imports, hasLength(2));
+    expect(unlinked.imports[0].combinators, hasLength(1));
+    expect(unlinked.imports[0].combinators[0].shows, hasLength(2));
+    expect(unlinked.imports[0].combinators[0].hides, isEmpty);
+    checkCombinatorName(unlinked.imports[0].combinators[0].shows[0], 'Future');
+    checkCombinatorName(unlinked.imports[0].combinators[0].shows[1], 'Stream');
+  }
+
+  test_import_uri() {
+    String uriString = '"dart:async"';
+    String libraryText = 'import $uriString; Future x;';
+    serializeLibraryText(libraryText);
+    // Second import is the implicit import of dart:core
+    expect(unlinked.imports, hasLength(2));
+    expect(unlinked.imports[0].uri, 'dart:async');
+  }
+
+  test_library_named() {
+    String text = 'library foo.bar;';
+    serializeLibraryText(text);
+    expect(unlinked.name, 'foo.bar');
+  }
+
+  test_library_unnamed() {
+    serializeLibraryText('');
+    expect(unlinked.name, isEmpty);
+  }
+
+  test_nested_elements_have_no_part() {
+    addNamedSource(
+        '/part1.dart',
+        '''
+part of my.lib;
+
+class C {
+  var v;
+  f() {}
+}
+''');
+    serializeLibraryText('library my.lib; part "part1.dart";');
+    UnlinkedClass cls = findClass('C');
+    expect(findVariable('v', cls: cls).unit, 0);
+    expect(findExecutable('f', cls: cls).unit, 0);
+  }
+
+  test_parts_defining_compilation_unit() {
+    serializeLibraryText('');
+    expect(unlinked.units, hasLength(1));
+    expect(unlinked.units[0].uri, isEmpty);
+  }
+
+  test_parts_included() {
+    addNamedSource('/part1.dart', 'part of my.lib;');
+    String partString = '"part1.dart"';
+    String libraryText = 'library my.lib; part $partString;';
+    serializeLibraryText(libraryText);
+    expect(unlinked.units, hasLength(2));
+    expect(unlinked.units[1].uri, 'part1.dart');
+  }
+
+  test_type_arguments_explicit() {
+    UnlinkedTypeRef typeRef = serializeTypeText('List<int>');
+    checkTypeRef(typeRef, 'dart:core', 'dart:core', 'List',
+        allowTypeParameters: true);
+    expect(typeRef.typeArguments, hasLength(1));
+    checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'int');
+  }
+
+  test_type_arguments_explicit_dynamic() {
+    UnlinkedTypeRef typeRef = serializeTypeText('List<dynamic>');
+    checkTypeRef(typeRef, 'dart:core', 'dart:core', 'List',
+        allowTypeParameters: true);
+    expect(typeRef.typeArguments, isEmpty);
+  }
+
+  test_type_arguments_explicit_dynamic_typedef() {
+    UnlinkedTypeRef typeRef =
+        serializeTypeText('F<dynamic>', otherDeclarations: 'typedef T F<T>();');
+    checkTypeRef(typeRef, null, null, 'F',
+        allowTypeParameters: true,
+        expectedKind: PrelinkedReferenceKind.typedef);
+    expect(typeRef.typeArguments, isEmpty);
+  }
+
+  test_type_arguments_explicit_typedef() {
+    UnlinkedTypeRef typeRef =
+        serializeTypeText('F<int>', otherDeclarations: 'typedef T F<T>();');
+    checkTypeRef(typeRef, null, null, 'F',
+        allowTypeParameters: true,
+        expectedKind: PrelinkedReferenceKind.typedef);
+    expect(typeRef.typeArguments, hasLength(1));
+    checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'int');
+  }
+
+  test_type_arguments_implicit() {
+    UnlinkedTypeRef typeRef = serializeTypeText('List');
+    checkTypeRef(typeRef, 'dart:core', 'dart:core', 'List',
+        allowTypeParameters: true);
+    expect(typeRef.typeArguments, isEmpty);
+  }
+
+  test_type_arguments_implicit_typedef() {
+    UnlinkedTypeRef typeRef =
+        serializeTypeText('F', otherDeclarations: 'typedef T F<T>();');
+    checkTypeRef(typeRef, null, null, 'F',
+        allowTypeParameters: true,
+        expectedKind: PrelinkedReferenceKind.typedef);
+    expect(typeRef.typeArguments, isEmpty);
+  }
+
+  test_type_arguments_order() {
+    UnlinkedTypeRef typeRef = serializeTypeText('Map<int, Object>');
+    checkTypeRef(typeRef, 'dart:core', 'dart:core', 'Map',
+        allowTypeParameters: true);
+    expect(typeRef.typeArguments, hasLength(2));
+    checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'int');
+    checkTypeRef(typeRef.typeArguments[1], 'dart:core', 'dart:core', 'Object');
+  }
+
+  test_type_dynamic() {
+    checkDynamicTypeRef(serializeTypeText('dynamic'));
+  }
+
+  test_type_reference_to_class_argument() {
+    UnlinkedClass cls = serializeClassText('class C<T, U> { T t; U u; }');
+    {
+      UnlinkedTypeRef typeRef =
+          findVariable('t', cls: cls, failIfAbsent: true).type;
+      checkParamTypeRef(typeRef, 2);
+    }
+    {
+      UnlinkedTypeRef typeRef =
+          findVariable('u', cls: cls, failIfAbsent: true).type;
+      checkParamTypeRef(typeRef, 1);
+    }
+  }
+
+  test_type_reference_to_import_of_export() {
+    addNamedSource('/a.dart', 'library a; export "b.dart";');
+    addNamedSource('/b.dart', 'library b; class C {}');
+    checkTypeRef(serializeTypeText('C', otherDeclarations: 'import "a.dart";'),
+        absUri('/b.dart'), 'b.dart', 'C');
+  }
+
+  test_type_reference_to_import_of_export_via_prefix() {
+    addNamedSource('/a.dart', 'library a; export "b.dart";');
+    addNamedSource('/b.dart', 'library b; class C {}');
+    checkTypeRef(
+        serializeTypeText('p.C', otherDeclarations: 'import "a.dart" as p;'),
+        absUri('/b.dart'),
+        'b.dart',
+        'C',
+        expectedPrefix: 'p');
+  }
+
+  test_type_reference_to_imported_part() {
+    addNamedSource('/a.dart', 'library my.lib; part "b.dart";');
+    addNamedSource('/b.dart', 'part of my.lib; class C {}');
+    checkTypeRef(
+        serializeTypeText('C',
+            otherDeclarations: 'library my.lib; import "a.dart";'),
+        absUri('/a.dart'),
+        'a.dart',
+        'C');
+  }
+
+  test_type_reference_to_imported_part_with_prefix() {
+    addNamedSource('/a.dart', 'library my.lib; part "b.dart";');
+    addNamedSource('/b.dart', 'part of my.lib; class C {}');
+    checkTypeRef(
+        serializeTypeText('p.C',
+            otherDeclarations: 'library my.lib; import "a.dart" as p;'),
+        absUri('/a.dart'),
+        'a.dart',
+        'C',
+        expectedPrefix: 'p');
+  }
+
+  test_type_reference_to_internal_class() {
+    checkTypeRef(serializeTypeText('C', otherDeclarations: 'class C {}'), null,
+        null, 'C');
+  }
+
+  test_type_reference_to_internal_class_alias() {
+    checkTypeRef(
+        serializeTypeText('C',
+            otherDeclarations: 'class C = D with E; class D {} class E {}'),
+        null,
+        null,
+        'C');
+  }
+
+  test_type_reference_to_internal_enum() {
+    checkTypeRef(serializeTypeText('E', otherDeclarations: 'enum E { value }'),
+        null, null, 'E');
+  }
+
+  test_type_reference_to_local_part() {
+    addNamedSource('/a.dart', 'part of my.lib; class C {}');
+    checkTypeRef(
+        serializeTypeText('C',
+            otherDeclarations: 'library my.lib; part "a.dart";'),
+        null,
+        null,
+        'C');
+  }
+
+  test_type_reference_to_nonexistent_file_via_prefix() {
+    UnlinkedTypeRef typeRef = serializeTypeText('p.C',
+        otherDeclarations: 'import "foo.dart" as p;', allowErrors: true);
+    checkUnresolvedTypeRef(typeRef, 'p', 'C');
+  }
+
+  test_type_reference_to_typedef() {
+    checkTypeRef(serializeTypeText('F', otherDeclarations: 'typedef void F();'),
+        null, null, 'F',
+        expectedKind: PrelinkedReferenceKind.typedef);
+  }
+
+  test_type_unit_counts_unreferenced_units() {
+    addNamedSource('/a.dart', 'library a; part "b.dart"; part "c.dart";');
+    addNamedSource('/b.dart', 'part of a;');
+    addNamedSource('/c.dart', 'part of a; class C {}');
+    UnlinkedTypeRef typeRef =
+        serializeTypeText('C', otherDeclarations: 'import "a.dart";');
+    // The referenced unit should be 2, since unit 0 is a.dart and unit 1 is
+    // b.dart.  a.dart and b.dart are counted even though nothing is imported
+    // from them.
+    checkTypeRef(typeRef, absUri('/a.dart'), 'a.dart', 'C');
+  }
+
+  test_type_unresolved() {
+    UnlinkedTypeRef typeRef = serializeTypeText('Foo', allowErrors: true);
+    checkUnresolvedTypeRef(typeRef, null, 'Foo');
+  }
+
+  test_typedef_name() {
+    UnlinkedTypedef type = serializeTypedefText('typedef F();');
+    expect(type.name, 'F');
+    expect(type.unit, 0);
+  }
+
+  test_typedef_param_none() {
+    UnlinkedTypedef type = serializeTypedefText('typedef F();');
+    expect(type.parameters, isEmpty);
+  }
+
+  test_typedef_param_order() {
+    UnlinkedTypedef type = serializeTypedefText('typedef F(x, y);');
+    expect(type.parameters, hasLength(2));
+    expect(type.parameters[0].name, 'x');
+    expect(type.parameters[1].name, 'y');
+  }
+
+  test_typedef_return_type_explicit() {
+    UnlinkedTypedef type = serializeTypedefText('typedef int F();');
+    checkTypeRef(type.returnType, 'dart:core', 'dart:core', 'int');
+  }
+
+  test_typedef_type_param_in_parameter() {
+    UnlinkedTypedef type = serializeTypedefText('typedef F<T>(T t);');
+    checkParamTypeRef(type.parameters[0].type, 1);
+  }
+
+  test_typedef_type_param_in_return_type() {
+    UnlinkedTypedef type = serializeTypedefText('typedef T F<T>();');
+    checkParamTypeRef(type.returnType, 1);
+  }
+
+  test_typedef_type_param_none() {
+    UnlinkedTypedef type = serializeTypedefText('typedef F();');
+    expect(type.typeParameters, isEmpty);
+  }
+
+  test_typedef_type_param_order() {
+    UnlinkedTypedef type = serializeTypedefText('typedef F<T, U>();');
+    expect(type.typeParameters, hasLength(2));
+    expect(type.typeParameters[0].name, 'T');
+    expect(type.typeParameters[1].name, 'U');
+  }
+
+  test_variable() {
+    serializeVariableText('int i;', variableName: 'i');
+    expect(findExecutable('i'), isNull);
+    expect(findExecutable('i='), isNull);
+  }
+
+  test_variable_const() {
+    UnlinkedVariable variable =
+        serializeVariableText('const int i = 0;', variableName: 'i');
+    expect(variable.isConst, isTrue);
+  }
+
+  test_variable_final_top_level() {
+    UnlinkedVariable variable =
+        serializeVariableText('final int i = 0;', variableName: 'i');
+    expect(variable.isFinal, isTrue);
+  }
+
+  test_variable_implicit_dynamic() {
+    UnlinkedVariable variable = serializeVariableText('var v;');
+    checkDynamicTypeRef(variable.type);
+  }
+
+  test_variable_name() {
+    UnlinkedVariable variable =
+        serializeVariableText('int i;', variableName: 'i');
+    expect(variable.name, 'i');
+    expect(variable.unit, 0);
+  }
+
+  test_variable_no_flags() {
+    UnlinkedVariable variable =
+        serializeVariableText('int i;', variableName: 'i');
+    expect(variable.isStatic, isFalse);
+    expect(variable.isConst, isFalse);
+    expect(variable.isFinal, isFalse);
+  }
+
+  test_variable_non_const() {
+    UnlinkedVariable variable =
+        serializeVariableText('int i = 0;', variableName: 'i');
+    expect(variable.isConst, isFalse);
+  }
+
+  test_variable_non_final() {
+    UnlinkedVariable variable =
+        serializeVariableText('int i;', variableName: 'i');
+    expect(variable.isFinal, isFalse);
+  }
+
+  test_variable_non_static() {
+    UnlinkedVariable variable =
+        serializeClassText('class C { int i; }').fields[0];
+    expect(variable.isStatic, isFalse);
+  }
+
+  test_variable_non_static_top_level() {
+    // Top level variables are considered non-static.
+    UnlinkedVariable variable =
+        serializeVariableText('int i;', variableName: 'i');
+    expect(variable.isStatic, isFalse);
+  }
+
+  test_variable_static() {
+    UnlinkedVariable variable =
+        serializeClassText('class C { static int i; }').fields[0];
+    expect(variable.isStatic, isTrue);
+  }
+
+  test_variable_type() {
+    UnlinkedVariable variable =
+        serializeVariableText('int i;', variableName: 'i');
+    checkTypeRef(variable.type, 'dart:core', 'dart:core', 'int');
+  }
+}
diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
index a60b879..c0ad43b 100644
--- a/pkg/analyzer/test/src/task/dart_test.dart
+++ b/pkg/analyzer/test/src/task/dart_test.dart
@@ -46,6 +46,7 @@
   runReflectiveTests(ComputeLibraryCycleTaskTest);
   runReflectiveTests(ContainingLibrariesTaskTest);
   runReflectiveTests(DartErrorsTaskTest);
+  runReflectiveTests(ErrorFilterTest);
   runReflectiveTests(EvaluateUnitConstantsTaskTest);
   runReflectiveTests(GatherUsedImportedElementsTaskTest);
   runReflectiveTests(GatherUsedLocalElementsTaskTest);
@@ -1645,7 +1646,7 @@
     List<CompilationUnitElement> dep3 = results[3][LIBRARY_CYCLE_DEPENDENCIES];
     expect(dep0, hasLength(1)); // dart:core
     expect(dep1, hasLength(1)); // dart:core
-    expect(dep3, hasLength(3)); // dart:core, a.dart, b.dart
+    expect(dep2, hasLength(3)); // dart:core, a.dart, b.dart
     expect(dep3, hasLength(3)); // dart:core, a.dart, b.dart
   }
 
@@ -2240,6 +2241,30 @@
 }
 
 @reflectiveTest
+class ErrorFilterTest extends _AbstractDartTaskTest {
+  @override
+  setUp() {
+    super.setUp();
+    context.setConfigurationData(CONFIGURED_ERROR_FILTERS, [
+      (AnalysisError error) => error.errorCode.name == 'INVALID_ASSIGNMENT'
+    ]);
+  }
+
+  test_error_filters() {
+    AnalysisTarget library = newSource('/test.dart', '''
+main() {
+  int x = ""; // INVALID_ASSIGNMENT (suppressed)
+  // UNUSED_LOCAL_VARIABLE
+}''');
+    computeResult(library, DART_ERRORS, matcher: isDartErrorsTask);
+    expect(outputs, hasLength(1));
+    List<AnalysisError> errors = outputs[DART_ERRORS];
+    expect(errors, hasLength(1));
+    expect(errors.first.errorCode, HintCode.UNUSED_LOCAL_VARIABLE);
+  }
+}
+
+@reflectiveTest
 class GenerateLintsTaskTest extends _AbstractDartTaskTest {
   void enableLints() {
     AnalysisOptionsImpl options = context.analysisOptions;
@@ -3008,7 +3033,6 @@
 
     computeResult(
         new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT7);
-    CompilationUnit unit2 = outputs[RESOLVED_UNIT7];
 
     // A.a2 should now be fully resolved and inferred.
     assertVariableDeclarationTypes(
@@ -3042,7 +3066,6 @@
           }
     '''
     });
-    InterfaceType intType = context.typeProvider.intType;
     DartType dynamicType = context.typeProvider.dynamicType;
 
     computeResult(
@@ -3055,7 +3078,6 @@
 
     computeResult(
         new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT7);
-    CompilationUnit unit2 = outputs[RESOLVED_UNIT7];
 
     // A.a2 should now be fully resolved and inferred.
     assertVariableDeclarationTypes(
@@ -3117,7 +3139,6 @@
 
     computeResult(
         new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT7);
-    CompilationUnit unit2 = outputs[RESOLVED_UNIT7];
 
     assertVariableDeclarationTypes(
         getFieldInClass(unit0, "A", "a1"), intType, intType);
@@ -3169,7 +3190,6 @@
 
     computeResult(
         new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT7);
-    CompilationUnit unit1 = outputs[RESOLVED_UNIT7];
 
     // A.a2 should now be fully resolved and inferred.
     assertVariableDeclarationTypes(
@@ -3653,7 +3673,6 @@
     List<dynamic> units =
         computeLibraryResults(sources, RESOLVED_UNIT9).toList();
     CompilationUnit unit0 = units[0];
-    CompilationUnit unit1 = units[1];
     CompilationUnit unit2 = units[2];
 
     InterfaceType intType = context.typeProvider.intType;
diff --git a/pkg/analyzer/test/src/task/driver_test.dart b/pkg/analyzer/test/src/task/driver_test.dart
index aed091c..9560dc8 100644
--- a/pkg/analyzer/test/src/task/driver_test.dart
+++ b/pkg/analyzer/test/src/task/driver_test.dart
@@ -350,7 +350,7 @@
         'task', (context, target) => task, (target) => {}, [result]);
     task = new TestAnalysisTask(context, target,
         descriptor: descriptor, value: 42);
-    WorkItem item = new WorkItem(context, target, descriptor, null);
+    WorkItem item = new WorkItem(context, target, descriptor, null, null);
 
     bool streamNotified = false;
     analysisDriver.onResultComputed(result).listen((event) {
@@ -374,7 +374,7 @@
         'task', (context, target) => task, (target) => {}, [result]);
     task = new TestAnalysisTask(context, target,
         descriptor: descriptor, exception: exception);
-    WorkItem item = new WorkItem(context, target, descriptor, null);
+    WorkItem item = new WorkItem(context, target, descriptor, null, null);
 
     analysisDriver.performWorkItem(item);
     CacheEntry targetEntry = context.getCacheEntry(item.target);
@@ -389,7 +389,7 @@
     TaskDescriptor descriptor = new TaskDescriptor(
         'task', (context, target) => task, (target) => {}, [result]);
     task = new TestAnalysisTask(context, target, descriptor: descriptor);
-    WorkItem item = new WorkItem(context, target, descriptor, null);
+    WorkItem item = new WorkItem(context, target, descriptor, null, null);
 
     analysisDriver.performWorkItem(item);
     CacheEntry targetEntry = context.getCacheEntry(item.target);
@@ -407,7 +407,7 @@
         [result]);
     CaughtException exception =
         new CaughtException(new AnalysisException(), null);
-    WorkItem item = new WorkItem(context, target, descriptor, null);
+    WorkItem item = new WorkItem(context, target, descriptor, null, null);
     item.exception = exception;
 
     analysisDriver.performWorkItem(item);
@@ -423,8 +423,8 @@
         (context, target) => new TestAnalysisTask(context, target),
         (target) => {'one': inputResult.of(target)},
         [new ResultDescriptor('output', null)]);
-    analysisDriver.currentWorkOrder =
-        new WorkOrder(taskManager, new WorkItem(null, null, descriptor, null));
+    analysisDriver.currentWorkOrder = new WorkOrder(
+        taskManager, new WorkItem(null, null, descriptor, null, null));
 
     analysisDriver.reset();
     expect(analysisDriver.currentWorkOrder, isNull);
@@ -622,7 +622,7 @@
         (context, target) => new TestAnalysisTask(context, target),
         (target) => {},
         [new ResultDescriptor('output', null)]);
-    WorkItem item = new WorkItem(context, target, descriptor, null);
+    WorkItem item = new WorkItem(context, target, descriptor, null, null);
     AnalysisTask task = item.buildTask();
     expect(task, isNotNull);
   }
@@ -639,7 +639,7 @@
             new TestAnalysisTask(context, target, results: outputResults),
         (target) => {'one': inputResult.of(target)},
         outputResults);
-    WorkItem item = new WorkItem(context, target, descriptor, null);
+    WorkItem item = new WorkItem(context, target, descriptor, null, null);
     expect(() => item.buildTask(), throwsStateError);
   }
 
@@ -647,7 +647,7 @@
     AnalysisTarget target = new TestSource();
     TaskDescriptor descriptor = new TaskDescriptor(
         'task', null, (target) => {}, [new ResultDescriptor('result', null)]);
-    WorkItem item = new WorkItem(context, target, descriptor, null);
+    WorkItem item = new WorkItem(context, target, descriptor, null, null);
     expect(item, isNotNull);
     expect(item.context, context);
     expect(item.descriptor, descriptor);
@@ -661,7 +661,7 @@
         (context, target) => new TestAnalysisTask(context, target),
         (target) => {},
         [new ResultDescriptor('output', null)]);
-    WorkItem item = new WorkItem(context, target, descriptor, null);
+    WorkItem item = new WorkItem(context, target, descriptor, null, null);
     WorkItem result = item.gatherInputs(taskManager, []);
     expect(result, isNull);
     expect(item.exception, isNull);
@@ -686,7 +686,7 @@
     taskManager.addTaskDescriptor(task1);
     taskManager.addTaskDescriptor(task2);
     // gather inputs
-    WorkItem item = new WorkItem(context, target, task2, null);
+    WorkItem item = new WorkItem(context, target, task2, null, null);
     WorkItem inputItem = item.gatherInputs(taskManager, []);
     expect(inputItem, isNotNull);
   }
@@ -699,7 +699,7 @@
         (context, target) => new TestAnalysisTask(context, target),
         (target) => {'one': inputResult.of(target)},
         [new ResultDescriptor('output', null)]);
-    WorkItem item = new WorkItem(context, target, descriptor, null);
+    WorkItem item = new WorkItem(context, target, descriptor, null, null);
     WorkItem result = item.gatherInputs(taskManager, []);
     expect(result, isNull);
     expect(item.exception, isNotNull);
@@ -712,8 +712,8 @@
     TaskManager manager = new TaskManager();
     TaskDescriptor descriptor = new TaskDescriptor(
         'task', null, (_) => {}, [new ResultDescriptor('result', null)]);
-    WorkOrder order =
-        new WorkOrder(manager, new WorkItem(null, null, descriptor, null));
+    WorkOrder order = new WorkOrder(
+        manager, new WorkItem(null, null, descriptor, null, null));
     expect(order, isNotNull);
     expect(order.currentItems, isNull);
     expect(order.current, isNull);
@@ -723,7 +723,7 @@
     TaskManager manager = new TaskManager();
     TaskDescriptor descriptor = new TaskDescriptor(
         'task', null, (_) => {}, [new ResultDescriptor('result', null)]);
-    WorkItem workItem = new WorkItem(null, null, descriptor, null);
+    WorkItem workItem = new WorkItem(null, null, descriptor, null, null);
     WorkOrder order = new WorkOrder(manager, workItem);
     // "item" has no child items
     expect(order.moveNext(), isTrue);
diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart
index 5dddc25..75c0a5a 100644
--- a/pkg/analyzer/test/src/task/options_test.dart
+++ b/pkg/analyzer/test/src/task/options_test.dart
@@ -6,12 +6,13 @@
 
 import 'package:analyzer/analyzer.dart';
 import 'package:analyzer/source/analysis_options_provider.dart';
-import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/engine.dart' hide AnalysisContextImpl;
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/task/options.dart';
 import 'package:analyzer/task/general.dart';
 import 'package:analyzer/task/model.dart';
 import 'package:unittest/unittest.dart';
+import 'package:yaml/yaml.dart';
 
 import '../../generated/test_support.dart';
 import '../../reflective_tests.dart';
@@ -20,6 +21,7 @@
 
 main() {
   initializeTestEnvironment();
+  runReflectiveTests(ContextConfigurationTest);
   runReflectiveTests(GenerateOptionsErrorsTaskTest);
   runReflectiveTests(OptionsFileValidatorTest);
 }
@@ -28,10 +30,95 @@
     new isInstanceOf<GenerateOptionsErrorsTask>();
 
 @reflectiveTest
+class ContextConfigurationTest extends AbstractContextTest {
+  final AnalysisOptionsProvider optionsProvider = new AnalysisOptionsProvider();
+
+  AnalysisOptions get analysisOptions => context.analysisOptions;
+
+  configureContext(String optionsSource) =>
+      configureContextOptions(context, parseOptions(optionsSource));
+
+  Map<String, YamlNode> parseOptions(String source) =>
+      optionsProvider.getOptionsFromString(source);
+
+  test_configure_bad_options_contents() {
+    configureContext('''
+analyzer:
+  strong-mode:true # misformatted
+''');
+    expect(analysisOptions.strongMode, false);
+  }
+
+  test_configure_enableGenericMethods() {
+    expect(analysisOptions.enableGenericMethods, false);
+    configureContext('''
+analyzer:
+  language:
+    enableGenericMethods: true
+''');
+    expect(analysisOptions.enableGenericMethods, true);
+  }
+
+  test_configure_enableSuperMixins() {
+    configureContext('''
+analyzer:
+  language:
+    enableSuperMixins: true
+''');
+    expect(analysisOptions.enableSuperMixins, true);
+  }
+
+  test_configure_error_filters() {
+    configureContext('''
+analyzer:
+  errors:
+    invalid_assignment: ignore
+    unused_local_variable: ignore
+''');
+
+    List<ErrorFilter> filters =
+        context.getConfigurationData(CONFIGURED_ERROR_FILTERS);
+    expect(filters, hasLength(2));
+
+    var unused_error = new AnalysisError(
+        new TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [
+      ['x']
+    ]);
+    var invalid_assignment_error =
+        new AnalysisError(new TestSource(), 0, 1, HintCode.INVALID_ASSIGNMENT, [
+      ['x'],
+      ['y']
+    ]);
+
+    expect(filters.any((filter) => filter(unused_error)), isTrue);
+    expect(filters.any((filter) => filter(invalid_assignment_error)), isTrue);
+  }
+
+  test_configure_strong_mode() {
+    configureContext('''
+analyzer:
+  strong-mode: true
+''');
+    expect(analysisOptions.strongMode, true);
+  }
+
+  test_configure_strong_mode_bad_value() {
+    configureContext('''
+analyzer:
+  strong-mode: foo
+''');
+    expect(analysisOptions.strongMode, false);
+  }
+}
+
+@reflectiveTest
 class GenerateOptionsErrorsTaskTest extends AbstractContextTest {
   final optionsFilePath = '/${AnalysisEngine.ANALYSIS_OPTIONS_FILE}';
 
   Source source;
+  LineInfo lineInfo(String source) =>
+      GenerateOptionsErrorsTask.computeLineInfo(source);
+
   @override
   setUp() {
     super.setUp();
@@ -46,6 +133,18 @@
         unorderedEquals([GenerateOptionsErrorsTask.CONTENT_INPUT_NAME]));
   }
 
+  test_compute_lineInfo() {
+    expect(lineInfo('foo\nbar').getLocation(4).lineNumber, 2);
+    expect(lineInfo('foo\nbar').getLocation(4).columnNumber, 1);
+    expect(lineInfo('foo\r\nbar').getLocation(5).lineNumber, 2);
+    expect(lineInfo('foo\r\nbar').getLocation(5).columnNumber, 1);
+    expect(lineInfo('foo\rbar').getLocation(4).lineNumber, 2);
+    expect(lineInfo('foo\rbar').getLocation(4).columnNumber, 1);
+    expect(lineInfo('foo').getLocation(0).lineNumber, 1);
+    expect(lineInfo('foo').getLocation(0).columnNumber, 1);
+    expect(lineInfo('').getLocation(1).lineNumber, 1);
+  }
+
   test_constructor() {
     GenerateOptionsErrorsTask task =
         new GenerateOptionsErrorsTask(context, source);
@@ -110,9 +209,12 @@
     expect(task, isGenerateOptionsErrorsTask);
     List<AnalysisError> errors = outputs[ANALYSIS_OPTIONS_ERRORS];
     expect(errors, hasLength(1));
-    expect(errors[0].errorCode, AnalysisOptionsWarningCode.UNSUPPORTED_OPTION);
-    expect(errors[0].message,
-        "The option 'not_supported' is not supported by analyzer");
+    expect(errors[0].errorCode,
+        AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES);
+    expect(
+        errors[0].message,
+        "The option 'not_supported' is not supported by analyzer, supported "
+        "values are 'errors', 'exclude', 'language', 'plugins' and 'strong-mode'");
   }
 }
 
@@ -122,6 +224,66 @@
       new OptionsFileValidator(new TestSource());
   final AnalysisOptionsProvider optionsProvider = new AnalysisOptionsProvider();
 
+  test_analyzer_error_code_supported() {
+    validate(
+        '''
+analyzer:
+  errors:
+    unused_local_variable: ignore
+''',
+        []);
+  }
+
+  test_analyzer_error_code_supported_bad_value() {
+    validate(
+        '''
+analyzer:
+  errors:
+    unused_local_variable: ftw
+    ''',
+        [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES]);
+  }
+
+  test_analyzer_error_code_unsupported() {
+    validate(
+        '''
+analyzer:
+  errors:
+    not_supported: ignore
+    ''',
+        [AnalysisOptionsWarningCode.UNRECOGNIZED_ERROR_CODE]);
+  }
+
+  test_analyzer_language_supported() {
+    validate(
+        '''
+analyzer:
+  language:
+    enableSuperMixins: true
+''',
+        []);
+  }
+
+  test_analyzer_language_unsupported_key() {
+    validate(
+        '''
+analyzer:
+  language:
+    unsupported: true
+''',
+        [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES]);
+  }
+
+  test_analyzer_language_unsupported_value() {
+    validate(
+        '''
+analyzer:
+  language:
+    enableSuperMixins: foo
+''',
+        [AnalysisOptionsWarningCode.UNSUPPORTED_VALUE]);
+  }
+
   test_analyzer_supported_exclude() {
     validate(
         '''
@@ -141,13 +303,22 @@
         []);
   }
 
+  test_analyzer_supported_strong_mode_supported_bad_value() {
+    validate(
+        '''
+analyzer:
+  strong-mode: w00t
+    ''',
+        [AnalysisOptionsWarningCode.UNSUPPORTED_VALUE]);
+  }
+
   test_analyzer_unsupported_option() {
     validate(
         '''
 analyzer:
   not_supported: true
     ''',
-        [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION]);
+        [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES]);
   }
 
   test_linter_supported_rules() {
@@ -166,7 +337,7 @@
 linter:
   unsupported: true
     ''',
-        [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION]);
+        [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE]);
   }
 
   void validate(String source, List<AnalysisOptionsErrorCode> expected) {
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index aa51b50..6e8ba4b 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -125,6 +125,18 @@
           y = /*info:DynamicCast, info:DynamicInvoke*/f(3);
           (/*info:DynamicInvoke*/f(3.0));
         }
+        {
+          dynamic g = new B();
+          (/*info:DynamicInvoke*/g.call(32.0));
+          (/*info:DynamicInvoke*/g.col(42.0));
+          (/*info:DynamicInvoke*/g.foo(42.0));
+          (/*info:DynamicInvoke*/g.x);
+          A f = new B();
+          f.call(32.0);
+          (/*info:DynamicInvoke*/f.col(42.0));
+          (/*info:DynamicInvoke*/f.foo(42.0));
+          (/*info:DynamicInvoke*/f.x);
+        }
       }
     '''
   });
@@ -1120,6 +1132,13 @@
           }
 
           class Child extends Base {
+            /*severe:InvalidFieldOverride,severe:InvalidMethodOverride*/A f1; // invalid for getter
+            /*severe:InvalidFieldOverride,severe:InvalidMethodOverride*/C f2; // invalid for setter
+            /*severe:InvalidFieldOverride*/var f3;
+            /*severe:InvalidFieldOverride,severe:InvalidMethodOverride,severe:InvalidMethodOverride*/dynamic f4;
+          }
+
+          class Child2 implements Base {
             /*severe:InvalidMethodOverride*/A f1; // invalid for getter
             /*severe:InvalidMethodOverride*/C f2; // invalid for setter
             var f3;
@@ -1128,6 +1147,40 @@
        '''
   });
 
+  testChecker('private override', {
+    '/helper.dart': '''
+          import 'main.dart' as main;
+
+          class Base {
+            var f1;
+            var _f2;
+            var _f3;
+            get _f4 => null;
+
+            int _m1();
+          }
+
+          class GrandChild extends main.Child {
+            /*severe:InvalidFieldOverride*/var _f2;
+            /*severe:InvalidFieldOverride*/var _f3;
+            var _f4;
+
+            /*severe:InvalidMethodOverride*/String _m1();
+          }
+    ''',
+    '/main.dart': '''
+          import 'helper.dart' as helper;
+
+          class Child extends helper.Base {
+            /*severe:InvalidFieldOverride*/var f1;
+            var _f2;
+            var _f4;
+
+            String _m1();
+          }
+    '''
+  });
+
   testChecker('getter/getter override', {
     '/main.dart': '''
           class A {}
@@ -1164,6 +1217,13 @@
           }
 
           class Child extends Base {
+            /*severe:InvalidFieldOverride,severe:InvalidMethodOverride*/A get f1 => null;
+            /*severe:InvalidFieldOverride*/C get f2 => null;
+            /*severe:InvalidFieldOverride*/get f3 => null;
+            /*severe:InvalidFieldOverride,severe:InvalidMethodOverride*/dynamic get f4 => null;
+          }
+
+          class Child2 implements Base {
             /*severe:InvalidMethodOverride*/A get f1 => null;
             C get f2 => null;
             get f3 => null;
@@ -1211,6 +1271,20 @@
           }
 
           class Child extends Base {
+            /*severe:InvalidFieldOverride*/B get f1 => null;
+            /*severe:InvalidFieldOverride*/B get f2 => null;
+            /*severe:InvalidFieldOverride*/B get f3 => null;
+            /*severe:InvalidFieldOverride*/B get f4 => null;
+            /*severe:InvalidFieldOverride*/B get f5 => null;
+
+            /*severe:InvalidFieldOverride*/void set f1(A value) {}
+            /*severe:InvalidFieldOverride,severe:InvalidMethodOverride*/void set f2(C value) {}
+            /*severe:InvalidFieldOverride*/void set f3(value) {}
+            /*severe:InvalidFieldOverride,severe:InvalidMethodOverride*/void set f4(dynamic value) {}
+            /*severe:InvalidFieldOverride*/set f5(B value) {}
+          }
+
+          class Child2 implements Base {
             B get f1 => null;
             B get f2 => null;
             B get f3 => null;
@@ -1496,18 +1570,34 @@
             }
 
             class T1 extends Base {
-              /*severe:InvalidMethodOverride*/B get f => null;
+              /*severe:InvalidFieldOverride,severe:InvalidMethodOverride*/B get f => null;
             }
 
             class T2 extends Base {
-              /*severe:InvalidMethodOverride*/set f(B b) => null;
+              /*severe:InvalidFieldOverride,severe:InvalidMethodOverride*/set f(B b) => null;
             }
 
             class T3 extends Base {
-              /*severe:InvalidMethodOverride*/final B f;
+              /*severe:InvalidFieldOverride,severe:InvalidMethodOverride*/final B f;
             }
             class T4 extends Base {
               // two: one for the getter one for the setter.
+              /*severe:InvalidFieldOverride,severe:InvalidMethodOverride,severe:InvalidMethodOverride*/B f;
+            }
+
+            class T5 implements Base {
+              /*severe:InvalidMethodOverride*/B get f => null;
+            }
+
+            class T6 implements Base {
+              /*severe:InvalidMethodOverride*/set f(B b) => null;
+            }
+
+            class T7 implements Base {
+              /*severe:InvalidMethodOverride*/final B f;
+            }
+            class T8 implements Base {
+              // two: one for the getter one for the setter.
               /*severe:InvalidMethodOverride,severe:InvalidMethodOverride*/B f;
             }
          '''
@@ -1534,12 +1624,14 @@
 
             class Grandparent {
                 m(A a) {}
+                int x;
             }
             class Parent extends Grandparent {
             }
 
             class Test extends Parent {
                 /*severe:InvalidMethodOverride*/m(B a) {}
+                /*severe:InvalidFieldOverride*/int x;
             }
          '''
     });
@@ -1588,17 +1680,20 @@
 
             class Base {
                 m(A a) {}
+                int x;
             }
 
             class M1 {
                 m(B a) {}
             }
 
-            class M2 {}
+            class M2 {
+                int x;
+            }
 
             class T1 extends Base with /*severe:InvalidMethodOverride*/M1 {}
-            class T2 extends Base with /*severe:InvalidMethodOverride*/M1, M2 {}
-            class T3 extends Base with M2, /*severe:InvalidMethodOverride*/M1 {}
+            class T2 extends Base with /*severe:InvalidMethodOverride*/M1, /*severe:InvalidFieldOverride*/M2 {}
+            class T3 extends Base with /*severe:InvalidFieldOverride*/M2, /*severe:InvalidMethodOverride*/M1 {}
          '''
     });
 
@@ -1612,13 +1707,15 @@
 
             class M1 {
                 m(B a) {}
+                int x;
             }
 
             class M2 {
                 m(A a) {}
+                int x;
             }
 
-            class T1 extends Base with M1, /*severe:InvalidMethodOverride*/M2 {}
+            class T1 extends Base with M1, /*severe:InvalidMethodOverride,severe:InvalidFieldOverride*/M2 {}
          '''
     });
 
diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
index 125b356..2a051be 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -540,7 +540,7 @@
         }
 
         class B extends A {
-          get x => 3;
+          /*severe:InvalidFieldOverride*/get x => 3;
         }
 
         foo() {
@@ -613,7 +613,7 @@
 
         class B<E> extends A<E> {
           E y;
-          get x => y;
+          /*severe:InvalidFieldOverride*/get x => y;
         }
 
         foo() {
@@ -747,13 +747,13 @@
           final I2 a;
         }
 
-        class C1 extends A implements B {
-          /*severe:InvalidMethodOverride,severe:InvalidMethodOverride*/get a => null;
+        class C1 implements A, B {
+          /*severe:InvalidMethodOverride*/get a => null;
         }
 
         // Still ambiguous
-        class C2 extends B implements A {
-          /*severe:InvalidMethodOverride,severe:InvalidMethodOverride*/get a => null;
+        class C2 implements B, A {
+          /*severe:InvalidMethodOverride*/get a => null;
         }
     '''
   });
@@ -780,12 +780,12 @@
           final I2 a;
         }
 
-        class C1 extends A implements B {
+        class C1 implements A, B {
           I3 get a => null;
         }
 
-        class C2 extends A implements B {
-          /*severe:InvalidMethodOverride,severe:InvalidMethodOverride*/get a => null;
+        class C2 implements A, B {
+          /*severe:InvalidMethodOverride*/get a => null;
         }
     '''
   });
@@ -797,7 +797,7 @@
           var x;
         }
 
-        class B extends A {
+        class B implements A {
           var x = 2;
         }
 
@@ -815,7 +815,7 @@
           final x;
         }
 
-        class B extends A {
+        class B implements A {
           final x = 2;
         }
 
@@ -832,7 +832,7 @@
           var x, y = 2, z = "hi";
         }
 
-        class B extends A {
+        class B implements A {
           var x = 2, y = 3, z, w = 2;
         }
 
diff --git a/pkg/analyzer/test/src/util/absolute_path_test.dart b/pkg/analyzer/test/src/util/absolute_path_test.dart
new file mode 100644
index 0000000..0f195c2
--- /dev/null
+++ b/pkg/analyzer/test/src/util/absolute_path_test.dart
@@ -0,0 +1,96 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.analyzer.src.util.absolute_path;
+
+import 'package:analyzer/src/util/absolute_path.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../reflective_tests.dart';
+import '../../utils.dart';
+
+main() {
+  initializeTestEnvironment();
+  runReflectiveTests(AbsolutePathContextPosixTest);
+  runReflectiveTests(AbsolutePathContextWindowsTest);
+}
+
+@reflectiveTest
+class AbsolutePathContextPosixTest {
+  AbsolutePathContext context = new AbsolutePathContext(r'/');
+
+  void test_append() {
+    expect(context.append(r'/path/to', r'foo.dart'), r'/path/to/foo.dart');
+  }
+
+  void test_basename() {
+    expect(context.basename(r'/path/to/foo.dart'), r'foo.dart');
+    expect(context.basename(r'/path/to'), r'to');
+    expect(context.basename(r'/path'), r'path');
+    expect(context.basename(r'/'), r'');
+  }
+
+  void test_dirname() {
+    expect(context.dirname(r'/path/to/foo.dart'), r'/path/to');
+    expect(context.dirname(r'/path/to'), r'/path');
+    expect(context.dirname(r'/path'), r'/');
+    expect(context.dirname(r'/'), r'/');
+  }
+
+  void test_isWithin() {
+    expect(context.isWithin(r'/root/path', r'/root/path/a'), isTrue);
+    expect(context.isWithin(r'/root/path', r'/root/other'), isFalse);
+    expect(context.isWithin(r'/root/path', r'/root/path'), isFalse);
+  }
+
+  void test_split() {
+    expect(context.split(r'/path/to/foo'), [r'', r'path', r'to', r'foo']);
+    expect(context.split(r'/path'), [r'', r'path']);
+  }
+
+  void test_suffix() {
+    expect(context.suffix(r'/root/path', r'/root/path/a/b.dart'), r'a/b.dart');
+    expect(context.suffix(r'/root/path', r'/root/other.dart'), isNull);
+  }
+}
+
+@reflectiveTest
+class AbsolutePathContextWindowsTest {
+  AbsolutePathContext context = new AbsolutePathContext(r'\');
+
+  void test_append() {
+    expect(context.append(r'C:\path\to', r'foo.dart'), r'C:\path\to\foo.dart');
+  }
+
+  void test_basename() {
+    expect(context.basename(r'C:\path\to\foo.dart'), r'foo.dart');
+    expect(context.basename(r'C:\path\to'), r'to');
+    expect(context.basename(r'C:\path'), r'path');
+    expect(context.basename(r'C:\'), r'');
+  }
+
+  void test_dirname() {
+    expect(context.dirname(r'C:\path\to\foo.dart'), r'C:\path\to');
+    expect(context.dirname(r'C:\path\to'), r'C:\path');
+    expect(context.dirname(r'C:\path'), r'C:\');
+    expect(context.dirname(r'C:\'), r'C:\');
+  }
+
+  void test_isWithin() {
+    expect(context.isWithin(r'C:\root\path', r'C:\root\path\a'), isTrue);
+    expect(context.isWithin(r'C:\root\path', r'C:\root\other'), isFalse);
+    expect(context.isWithin(r'C:\root\path', r'C:\root\path'), isFalse);
+  }
+
+  void test_split() {
+    expect(context.split(r'C:\path\to\foo'), [r'C:', r'path', r'to', r'foo']);
+    expect(context.split(r'C:\path'), [r'C:', r'path']);
+  }
+
+  void test_suffix() {
+    expect(
+        context.suffix(r'C:\root\path', r'C:\root\path\a\b.dart'), r'a\b.dart');
+    expect(context.suffix(r'C:\root\path', r'C:\root\other.dart'), isNull);
+  }
+}
diff --git a/pkg/analyzer/test/src/util/glob_test.dart b/pkg/analyzer/test/src/util/glob_test.dart
new file mode 100644
index 0000000..8ebc04f
--- /dev/null
+++ b/pkg/analyzer/test/src/util/glob_test.dart
@@ -0,0 +1,133 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.analyzer.src.util.glob;
+
+import 'package:analyzer/src/util/glob.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../reflective_tests.dart';
+import '../../utils.dart';
+
+main() {
+  initializeTestEnvironment();
+  runReflectiveTests(GlobPosixTest);
+  runReflectiveTests(GlobWindowsTest);
+}
+
+@reflectiveTest
+class GlobPosixTest {
+  void test_case() {
+    Glob glob = new Glob(r'\', r'**.DaRt');
+    expect(glob.matches(r'aaa.dart'), isTrue);
+    expect(glob.matches(r'bbb.DART'), isTrue);
+    expect(glob.matches(r'ccc.dArT'), isTrue);
+    expect(glob.matches(r'ddd.DaRt'), isTrue);
+  }
+
+  void test_question() {
+    Glob glob = new Glob(r'/', r'?.dart');
+    expect(glob.matches(r'a.dart'), isTrue);
+    expect(glob.matches(r'b.dart'), isTrue);
+    expect(glob.matches(r'cc.dart'), isFalse);
+  }
+
+  void test_specialChars() {
+    Glob glob = new Glob(r'/', r'*.dart');
+    expect(glob.matches(r'a.dart'), isTrue);
+    expect(glob.matches('_-\a.dart'), isTrue);
+    expect(glob.matches(r'^$*?.dart'), isTrue);
+    expect(glob.matches(r'()[]{}.dart'), isTrue);
+    expect(glob.matches('\u2665.dart'), isTrue);
+  }
+
+  void test_specialChars2() {
+    Glob glob = new Glob(r'/', r'a[]b.dart');
+    expect(glob.matches(r'a[]b.dart'), isTrue);
+    expect(glob.matches(r'aNb.dart'), isFalse);
+  }
+
+  void test_star() {
+    Glob glob = new Glob(r'/', r'web/*.dart');
+    expect(glob.matches(r'web/foo.dart'), isTrue);
+    expect(glob.matches(r'web/barbaz.dart'), isTrue);
+    // does not end with 'dart'
+    expect(glob.matches(r'web/foo.html'), isFalse);
+    // not in 'web'
+    expect(glob.matches(r'lib/foo.dart'), isFalse);
+    expect(glob.matches(r'/web/foo.dart'), isFalse);
+    // in sub-folder
+    expect(glob.matches(r'web/sub/foo.dart'), isFalse);
+  }
+
+  void test_starStar() {
+    Glob glob = new Glob(r'/', r'**.dart');
+    expect(glob.matches(r'foo/bar.dart'), isTrue);
+    expect(glob.matches(r'foo/bar/baz.dart'), isTrue);
+    expect(glob.matches(r'/foo/bar.dart'), isTrue);
+    expect(glob.matches(r'/foo/bar/baz.dart'), isTrue);
+    // does not end with 'dart'
+    expect(glob.matches(r'/web/foo.html'), isFalse);
+  }
+
+  void test_starStar_star() {
+    Glob glob = new Glob(r'/', r'**/*.dart');
+    expect(glob.matches(r'foo/bar.dart'), isTrue);
+    expect(glob.matches(r'foo/bar/baz.dart'), isTrue);
+    expect(glob.matches(r'/foo/bar.dart'), isTrue);
+    expect(glob.matches(r'/foo/bar/baz.dart'), isTrue);
+    // does not end with 'dart'
+    expect(glob.matches(r'/web/foo.html'), isFalse);
+  }
+}
+
+@reflectiveTest
+class GlobWindowsTest {
+  void test_case() {
+    Glob glob = new Glob(r'\', r'**.dart');
+    expect(glob.matches(r'aaa.dart'), isTrue);
+    expect(glob.matches(r'bbb.DART'), isTrue);
+    expect(glob.matches(r'ccc.dArT'), isTrue);
+    expect(glob.matches(r'ddd.DaRt'), isTrue);
+  }
+
+  void test_question() {
+    Glob glob = new Glob(r'\', r'?.dart');
+    expect(glob.matches(r'a.dart'), isTrue);
+    expect(glob.matches(r'b.dart'), isTrue);
+    expect(glob.matches(r'cc.dart'), isFalse);
+  }
+
+  void test_specialChars() {
+    Glob glob = new Glob(r'\', r'*.dart');
+    expect(glob.matches(r'a.dart'), isTrue);
+    expect(glob.matches('_-\a.dart'), isTrue);
+    expect(glob.matches(r'^$*?.dart'), isTrue);
+    expect(glob.matches(r'()[]{}.dart'), isTrue);
+    expect(glob.matches('\u2665.dart'), isTrue);
+  }
+
+  void test_star() {
+    Glob glob = new Glob(r'\', r'web/*.dart');
+    expect(glob.matches(r'web\foo.dart'), isTrue);
+    expect(glob.matches(r'web\barbaz.dart'), isTrue);
+    // does not end with 'dart'
+    expect(glob.matches(r'web\foo.html'), isFalse);
+    // not in 'web'
+    expect(glob.matches(r'lib\foo.dart'), isFalse);
+    expect(glob.matches(r'\web\foo.dart'), isFalse);
+    // in sub-folder
+    expect(glob.matches(r'web\sub\foo.dart'), isFalse);
+  }
+
+  void test_starStar() {
+    Glob glob = new Glob(r'\', r'**.dart');
+    expect(glob.matches(r'foo\bar.dart'), isTrue);
+    expect(glob.matches(r'foo\bar\baz.dart'), isTrue);
+    expect(glob.matches(r'C:\foo\bar.dart'), isTrue);
+    expect(glob.matches(r'C:\foo\bar\baz.dart'), isTrue);
+    // does not end with 'dart'
+    expect(glob.matches(r'C:\web\foo.html'), isFalse);
+  }
+}
diff --git a/pkg/analyzer/test/src/util/test_all.dart b/pkg/analyzer/test/src/util/test_all.dart
index f611c58..6d44df6 100644
--- a/pkg/analyzer/test/src/util/test_all.dart
+++ b/pkg/analyzer/test/src/util/test_all.dart
@@ -7,14 +7,20 @@
 import 'package:unittest/unittest.dart';
 
 import '../../utils.dart';
+import 'absolute_path_test.dart' as absolute_path_test;
 import 'asserts_test.dart' as asserts_test;
+import 'glob_test.dart' as glob_test;
 import 'lru_map_test.dart' as lru_map_test;
+import 'yaml_test.dart' as yaml_test;
 
 /// Utility for manually running all tests.
 main() {
   initializeTestEnvironment();
-  group('task tests', () {
+  group('util tests', () {
+    absolute_path_test.main();
     asserts_test.main();
+    glob_test.main();
     lru_map_test.main();
+    yaml_test.main();
   });
 }
diff --git a/pkg/analyzer/test/src/util/yaml_test.dart b/pkg/analyzer/test/src/util/yaml_test.dart
new file mode 100644
index 0000000..6cf00cc
--- /dev/null
+++ b/pkg/analyzer/test/src/util/yaml_test.dart
@@ -0,0 +1,104 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.test.util.yaml;
+
+import 'package:analyzer/src/util/yaml.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../utils.dart';
+
+main() {
+  initializeTestEnvironment();
+
+  group('yaml', () {
+    group('merge', () {
+      test('map', () {
+        expect(
+            merge({
+              'one': true,
+              'two': false,
+              'three': {
+                'nested': {'four': true, 'six': true}
+              }
+            }, {
+              'three': {
+                'nested': {'four': false, 'five': true},
+                'five': true
+              },
+              'seven': true
+            }),
+            equals({
+              'one': true,
+              'two': false,
+              'three': {
+                'nested': {'four': false, 'five': true, 'six': true},
+                'five': true
+              },
+              'seven': true
+            }));
+      });
+
+      test('list', () {
+        expect(merge([1, 2, 3], [2, 3, 4, 5]), equals([1, 2, 3, 4, 5]));
+      });
+
+      test('list w/ promotion', () {
+        expect(merge(['one', 'two', 'three'], {'three': false, 'four': true}),
+            equals({'one': true, 'two': true, 'three': false, 'four': true}));
+        expect(merge({'one': false, 'two': false}, ['one', 'three']),
+            equals({'one': true, 'two': false, 'three': true}));
+      });
+
+      test('map w/ list promotion', () {
+        var map1 = {
+          'one': ['a', 'b', 'c']
+        };
+        var map2 = {
+          'one': {'a': true, 'b': false}
+        };
+        var map3 = {
+          'one': {'a': true, 'b': false, 'c': true}
+        };
+        expect(merge(map1, map2), map3);
+      });
+
+      test('map w/ no promotion', () {
+        var map1 = {
+          'one': ['a', 'b', 'c']
+        };
+        var map2 = {
+          'one': {'a': 'foo', 'b': 'bar'}
+        };
+        var map3 = {
+          'one': {'a': 'foo', 'b': 'bar'}
+        };
+        expect(merge(map1, map2), map3);
+      });
+
+      test('map w/ no promotion (2)', () {
+        var map1 = {
+          'one': {'a': 'foo', 'b': 'bar'}
+        };
+        var map2 = {
+          'one': ['a', 'b', 'c']
+        };
+        var map3 = {
+          'one': ['a', 'b', 'c']
+        };
+        expect(merge(map1, map2), map3);
+      });
+
+      test('object', () {
+        expect(merge(1, 2), 2);
+        expect(merge(1, 'foo'), 'foo');
+        expect(merge({'foo': 1}, 'foo'), 'foo');
+      });
+    });
+  });
+}
+
+final Merger merger = new Merger();
+
+Object merge(Object o1, Object o2) => merger.merge(o1, o2);
diff --git a/pkg/analyzer/tool/generate_files b/pkg/analyzer/tool/generate_files
index 4d0b220..1e0322f 100755
--- a/pkg/analyzer/tool/generate_files
+++ b/pkg/analyzer/tool/generate_files
@@ -48,3 +48,4 @@
 
 cd "${SCRIPT_DIR}"
 "${DART}" "${VM_OPTIONS[@]}" "task_dependency_graph/generate.dart"
+"${DART}" "${VM_OPTIONS[@]}" "summary/generate.dart"
diff --git a/pkg/analyzer/tool/summary/check_test.dart b/pkg/analyzer/tool/summary/check_test.dart
new file mode 100644
index 0000000..ac5f7bb
--- /dev/null
+++ b/pkg/analyzer/tool/summary/check_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.tool.summary.check_test;
+
+import 'dart:io';
+
+import 'package:analyzer/src/codegen/tools.dart';
+import 'package:path/path.dart';
+
+import 'generate.dart';
+
+/**
+ * Check that the target file has been code generated.  If it hasn't tell the
+ * user to run generate.dart.
+ */
+main() {
+  String script = Platform.script.toFilePath(windows: Platform.isWindows);
+  String pkgPath = normalize(join(dirname(script), '..', '..'));
+  GeneratedContent.checkAll(
+      pkgPath, 'tool/summary/generate.dart', <GeneratedContent>[target]);
+}
diff --git a/pkg/analyzer/tool/summary/generate.dart b/pkg/analyzer/tool/summary/generate.dart
new file mode 100644
index 0000000..186a101
--- /dev/null
+++ b/pkg/analyzer/tool/summary/generate.dart
@@ -0,0 +1,368 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * This file contains code to generate serialization/deserialization logic for
+ * summaries based on an "IDL" description of the summary format (written in
+ * stylized Dart).
+ *
+ * For each class in the "IDL" input, two corresponding classes are generated:
+ * - A class with the same name which represents deserialized summary data in
+ *   memory.  This class has read-only semantics.
+ * - A "builder" class which can be used to generate serialized summary data.
+ *   This class has write-only semantics.
+ *
+ * Each of the "builder" classess has a single `finish` method which finalizes
+ * the entity being built and returns it as an [Object].  This object should
+ * only be passed to other builders (or to [BuilderContext.getBuffer]);
+ * otherwise the client should treat it as opaque, since it exposes
+ * implementation details of the underlying summary infrastructure.
+ */
+library analyzer.tool.summary.generate;
+
+import 'dart:convert';
+import 'dart:io' hide File;
+
+import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/codegen/tools.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:path/path.dart';
+
+import 'idl_model.dart' as idlModel;
+
+main() {
+  String script = Platform.script.toFilePath(windows: Platform.isWindows);
+  String pkgPath = normalize(join(dirname(script), '..', '..'));
+  GeneratedContent.generateAll(pkgPath, <GeneratedContent>[target]);
+}
+
+final GeneratedFile target =
+    new GeneratedFile('lib/src/summary/format.dart', (String pkgPath) {
+  // Parse the input "IDL" file and pass it to the [_CodeGenerator].
+  PhysicalResourceProvider provider = new PhysicalResourceProvider(
+      PhysicalResourceProvider.NORMALIZE_EOL_ALWAYS);
+  String idlPath = join(pkgPath, 'tool', 'summary', 'idl.dart');
+  File idlFile = provider.getFile(idlPath);
+  Source idlSource = provider.getFile(idlPath).createSource();
+  String idlText = idlFile.readAsStringSync();
+  BooleanErrorListener errorListener = new BooleanErrorListener();
+  CharacterReader idlReader = new CharSequenceReader(idlText);
+  Scanner scanner = new Scanner(idlSource, idlReader, errorListener);
+  Token tokenStream = scanner.tokenize();
+  Parser parser = new Parser(idlSource, new BooleanErrorListener());
+  CompilationUnit idlParsed = parser.parseCompilationUnit(tokenStream);
+  _CodeGenerator codeGenerator = new _CodeGenerator();
+  codeGenerator.processCompilationUnit(idlParsed);
+  return codeGenerator._outBuffer.toString();
+});
+
+class _CodeGenerator {
+  /**
+   * Buffer in which generated code is accumulated.
+   */
+  final StringBuffer _outBuffer = new StringBuffer();
+
+  /**
+   * Current indentation level.
+   */
+  String _indentation = '';
+
+  /**
+   * Semantic model of the "IDL" input file.
+   */
+  idlModel.Idl _idl;
+
+  /**
+   * Perform basic sanity checking of the IDL (over and above that done by
+   * [extractIdl]).
+   */
+  void checkIdl() {
+    _idl.classes.forEach((String name, idlModel.ClassDeclaration cls) {
+      cls.fields.forEach((String fieldName, idlModel.FieldType type) {
+        if (type.isList) {
+          if (_idl.classes.containsKey(type.typeName)) {
+            // List of classes is ok
+          } else if (type.typeName == 'int') {
+            // List of ints is ok
+          } else {
+            throw new Exception(
+                '$name.$fieldName: illegal type (list of ${type.typeName})');
+          }
+        }
+      });
+    });
+  }
+
+  /**
+   * Generate a string representing the Dart type which should be used to
+   * represent [type] when deserialized.
+   */
+  String dartType(idlModel.FieldType type) {
+    if (type.isList) {
+      return 'List<${type.typeName}>';
+    } else {
+      return type.typeName;
+    }
+  }
+
+  /**
+   * Generate a Dart expression representing the default value for a field
+   * having the given [type], or `null` if there is no default value.
+   */
+  String defaultValue(idlModel.FieldType type) {
+    if (type.isList) {
+      return 'const <${type.typeName}>[]';
+    } else if (_idl.enums.containsKey(type.typeName)) {
+      return '${type.typeName}.${_idl.enums[type.typeName].values[0]}';
+    } else if (type.typeName == 'int') {
+      return '0';
+    } else if (type.typeName == 'String') {
+      return "''";
+    } else if (type.typeName == 'bool') {
+      return 'false';
+    } else {
+      return null;
+    }
+  }
+
+  /**
+   * Generate a string representing the Dart type which should be used to
+   * represent [type] while building a serialized data structure.
+   */
+  String encodedType(idlModel.FieldType type) {
+    String typeStr;
+    if (_idl.classes.containsKey(type.typeName)) {
+      typeStr = '${type.typeName}Builder';
+    } else {
+      typeStr = type.typeName;
+    }
+    if (type.isList) {
+      return 'List<$typeStr>';
+    } else {
+      return typeStr;
+    }
+  }
+
+  /**
+   * Process the AST in [idlParsed] and store the resulting semantic model in
+   * [_idl].  Also perform some error checking.
+   */
+  void extractIdl(CompilationUnit idlParsed) {
+    _idl = new idlModel.Idl();
+    for (CompilationUnitMember decl in idlParsed.declarations) {
+      if (decl is ClassDeclaration) {
+        bool isTopLevel = false;
+        for (Annotation annotation in decl.metadata) {
+          if (annotation.arguments == null &&
+              annotation.name.name == 'topLevel') {
+            isTopLevel = true;
+          }
+        }
+        idlModel.ClassDeclaration cls =
+            new idlModel.ClassDeclaration(isTopLevel);
+        _idl.classes[decl.name.name] = cls;
+        for (ClassMember classMember in decl.members) {
+          if (classMember is FieldDeclaration) {
+            TypeName type = classMember.fields.type;
+            bool isList = false;
+            if (type.name.name == 'List' &&
+                type.typeArguments != null &&
+                type.typeArguments.arguments.length == 1) {
+              isList = true;
+              type = type.typeArguments.arguments[0];
+            }
+            if (type.typeArguments != null) {
+              throw new Exception('Cannot handle type arguments in `$type`');
+            }
+            idlModel.FieldType fieldType =
+                new idlModel.FieldType(type.name.name, isList);
+            for (VariableDeclaration field in classMember.fields.variables) {
+              cls.fields[field.name.name] = fieldType;
+            }
+          } else {
+            throw new Exception('Unexpected class member `$classMember`');
+          }
+        }
+      } else if (decl is EnumDeclaration) {
+        idlModel.EnumDeclaration enm = new idlModel.EnumDeclaration();
+        _idl.enums[decl.name.name] = enm;
+        for (EnumConstantDeclaration constDecl in decl.constants) {
+          enm.values.add(constDecl.name.name);
+        }
+      } else if (decl is TopLevelVariableDeclaration) {
+        // Ignore top leve variable declarations; they are present just to make
+        // the IDL analyze without warnings.
+      } else {
+        throw new Exception('Unexpected declaration `$decl`');
+      }
+    }
+  }
+
+  /**
+   * Execute [callback] with two spaces added to [_indentation].
+   */
+  void indent(void callback()) {
+    String oldIndentation = _indentation;
+    try {
+      _indentation += '  ';
+      callback();
+    } finally {
+      _indentation = oldIndentation;
+    }
+  }
+
+  /**
+   * Add the string [s] to the output as a single line, indenting as
+   * appropriate.
+   */
+  void out([String s = '']) {
+    if (s == '') {
+      _outBuffer.writeln('');
+    } else {
+      _outBuffer.writeln('$_indentation$s');
+    }
+  }
+
+  /**
+   * Entry point to the code generator.  Interpret the AST in [idlParsed],
+   * generate code, and output it to [_outBuffer].
+   */
+  void processCompilationUnit(CompilationUnit idlParsed) {
+    extractIdl(idlParsed);
+    checkIdl();
+    out('// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file');
+    out('// for details. All rights reserved. Use of this source code is governed by a');
+    out('// BSD-style license that can be found in the LICENSE file.');
+    out('//');
+    out('// This file has been automatically generated.  Please do not edit it manually.');
+    out('// To regenerate the file, use the script "pkg/analyzer/tool/generate_files".');
+    out();
+    out('library analyzer.src.summary.format;');
+    out();
+    out("import 'dart:convert';");
+    out("import 'builder.dart' as builder;");
+    out();
+    _idl.enums.forEach((String name, idlModel.EnumDeclaration enm) {
+      out('enum $name {');
+      indent(() {
+        for (String value in enm.values) {
+          out('$value,');
+        }
+      });
+      out('}');
+      out();
+    });
+    _idl.classes.forEach((String name, idlModel.ClassDeclaration cls) {
+      out('class $name {');
+      indent(() {
+        cls.fields.forEach((String fieldName, idlModel.FieldType type) {
+          out('${dartType(type)} _$fieldName;');
+        });
+        out();
+        out('$name.fromJson(Map json)');
+        indent(() {
+          List<String> initializers = <String>[];
+          cls.fields.forEach((String fieldName, idlModel.FieldType type) {
+            String convert = 'json[${quoted(fieldName)}]';
+            if (type.isList && type.typeName == 'int') {
+              // No conversion necessary.
+            } else if (type.isList) {
+              convert =
+                  '$convert?.map((x) => new ${type.typeName}.fromJson(x))?.toList()';
+            } else if (_idl.classes.containsKey(type.typeName)) {
+              convert =
+                  '$convert == null ? null : new ${type.typeName}.fromJson($convert)';
+            } else if (_idl.enums.containsKey(type.typeName)) {
+              convert =
+                  '$convert == null ? null : ${type.typeName}.values[$convert]';
+            }
+            initializers.add('_$fieldName = $convert');
+          });
+          for (int i = 0; i < initializers.length; i++) {
+            String prefix = i == 0 ? ': ' : '  ';
+            String suffix = i == initializers.length - 1 ? ';' : ',';
+            out('$prefix${initializers[i]}$suffix');
+          }
+        });
+        out();
+        if (cls.isTopLevel) {
+          out('$name.fromBuffer(List<int> buffer) : this.fromJson(JSON.decode(UTF8.decode(buffer)));');
+          out();
+        }
+        cls.fields.forEach((String fieldName, idlModel.FieldType type) {
+          String def = defaultValue(type);
+          String defaultSuffix = def == null ? '' : ' ?? $def';
+          out('${dartType(type)} get $fieldName => _$fieldName$defaultSuffix;');
+        });
+      });
+      out('}');
+      out();
+      List<String> builderParams = <String>[];
+      out('class ${name}Builder {');
+      indent(() {
+        out('final Map _json = {};');
+        out();
+        out('${name}Builder(builder.BuilderContext context);');
+        cls.fields.forEach((String fieldName, idlModel.FieldType type) {
+          out();
+          String conversion = '_value';
+          String condition = '';
+          if (type.isList) {
+            if (_idl.classes.containsKey(type.typeName)) {
+              conversion = '$conversion.map((b) => b.finish()).toList()';
+            } else {
+              conversion = '$conversion.toList()';
+            }
+            condition = ' || _value.isEmpty';
+          } else if (_idl.enums.containsKey(type.typeName)) {
+            conversion = '$conversion.index';
+            condition = ' || _value == ${defaultValue(type)}';
+          } else if (_idl.classes.containsKey(type.typeName)) {
+            conversion = '$conversion.finish()';
+          }
+          builderParams.add('${encodedType(type)} $fieldName');
+          out('void set $fieldName(${encodedType(type)} _value) {');
+          indent(() {
+            out('assert(!_json.containsKey(${quoted(fieldName)}));');
+            out('if (_value != null$condition) {');
+            indent(() {
+              out('_json[${quoted(fieldName)}] = $conversion;');
+            });
+            out('}');
+          });
+          out('}');
+        });
+        if (cls.isTopLevel) {
+          out();
+          out('List<int> toBuffer() => UTF8.encode(JSON.encode(finish()));');
+        }
+        out();
+        out('Map finish() => _json;');
+      });
+      out('}');
+      out();
+      out('${name}Builder encode$name(builder.BuilderContext builderContext, {${builderParams.join(', ')}}) {');
+      indent(() {
+        out('${name}Builder builder = new ${name}Builder(builderContext);');
+        cls.fields.forEach((String fieldName, idlModel.FieldType type) {
+          out('builder.$fieldName = $fieldName;');
+        });
+        out('return builder;');
+      });
+      out('}');
+      out();
+    });
+  }
+
+  /**
+   * Enclose [s] in quotes, escaping as necessary.
+   */
+  String quoted(String s) {
+    return JSON.encode(s);
+  }
+}
diff --git a/pkg/analyzer/tool/summary/idl.dart b/pkg/analyzer/tool/summary/idl.dart
index b450499..545dbfc 100644
--- a/pkg/analyzer/tool/summary/idl.dart
+++ b/pkg/analyzer/tool/summary/idl.dart
@@ -57,6 +57,12 @@
 const private = null;
 
 /**
+ * Annotation describing a class which can be the top level object in an
+ * encoded summary.
+ */
+const topLevel = null;
+
+/**
  * Information about a dependency that exists between one library and another
  * due to an "import" declaration.
  */
@@ -70,6 +76,7 @@
 /**
  * Pre-linked summary of a library.
  */
+@topLevel
 class PrelinkedLibrary {
   /**
    * The unlinked library summary.
@@ -104,6 +111,23 @@
 }
 
 /**
+ * Information about the resolution of an [UnlinkedReference].
+ */
+class PrelinkedReference {
+  /**
+   * Index into [UnlinkedLibrary.dependencies] indicating which imported library
+   * declares the entity being referred to.
+   */
+  int dependency;
+
+  /**
+   * The kind of the entity being referred to.  For the pseudo-type `dynamic`,
+   * the kind if [PrelinkedReferenceKind.classOrEnum].
+   */
+  PrelinkedReferenceKind kind;
+}
+
+/**
  * Enum used to indicate the kind of entity referred to by a
  * [PrelinkedReference].
  */
@@ -130,22 +154,6 @@
 }
 
 /**
- * Information about the resolution of an [UnlinkedReference].
- */
-class PrelinkedReference {
-  /**
-   * Index into [UnlinkedLibrary.dependencies] indicating which imported library
-   * declares the entity being referred to.
-   */
-  int dependency;
-
-  /**
-   * The kind of the entity being referred to.
-   */
-  PrelinkedReferenceKind kind;
-}
-
-/**
  * Unlinked summary information about a class declaration.
  */
 class UnlinkedClass {
@@ -212,12 +220,23 @@
   /**
    * List of names which are shown.  Empty if this is a `hide` combinator.
    */
-  List<String> shows;
+  List<UnlinkedCombinatorName> shows;
 
   /**
    * List of names which are hidden.  Empty if this is a `show` combinator.
    */
-  List<String> hides;
+  List<UnlinkedCombinatorName> hides;
+}
+
+/**
+ * Unlinked summary information about a single name in a `show` or `hide`
+ * combinator.
+ */
+class UnlinkedCombinatorName {
+  /**
+   * The name itself.
+   */
+  String name;
 }
 
 /**
@@ -254,31 +273,6 @@
 }
 
 /**
- * Enum used to indicate the kind of an executable.
- */
-enum UnlinkedExecutableKind {
-  /**
-   * Executable is a function or method.
-   */
-  functionOrMethod,
-
-  /**
-   * Executable is a getter.
-   */
-  getter,
-
-  /**
-   * Executable is a setter.
-   */
-  setter,
-
-  /**
-   * Executable is a constructor.
-   */
-  constructor
-}
-
-/**
  * Unlinked summary information about a function, method, getter, or setter
  * declaration.
  */
@@ -350,6 +344,31 @@
 }
 
 /**
+ * Enum used to indicate the kind of an executable.
+ */
+enum UnlinkedExecutableKind {
+  /**
+   * Executable is a function or method.
+   */
+  functionOrMethod,
+
+  /**
+   * Executable is a getter.
+   */
+  getter,
+
+  /**
+   * Executable is a setter.
+   */
+  setter,
+
+  /**
+   * Executable is a constructor.
+   */
+  constructor
+}
+
+/**
  * Unlinked summary information about an export declaration.
  */
 class UnlinkedExport {
@@ -468,26 +487,6 @@
 }
 
 /**
- * Enum used to indicate the kind of a parameter.
- */
-enum UnlinkedParamKind {
-  /**
-   * Parameter is required.
-   */
-  required,
-
-  /**
-   * Parameter is positional optional (enclosed in `[]`)
-   */
-  positional,
-
-  /**
-   * Parameter is named optional (enclosed in `{}`)
-   */
-  named
-}
-
-/**
  * Unlinked summary information about a function parameter.
  */
 class UnlinkedParam {
@@ -527,6 +526,26 @@
   bool isInitializingFormal;
 }
 
+/**
+ * Enum used to indicate the kind of a parameter.
+ */
+enum UnlinkedParamKind {
+  /**
+   * Parameter is required.
+   */
+  required,
+
+  /**
+   * Parameter is positional optional (enclosed in `[]`)
+   */
+  positional,
+
+  /**
+   * Parameter is named optional (enclosed in `{}`)
+   */
+  named
+}
+
 class UnlinkedPrefix {
   /**
    * The name of the prefix, or the empty string in the case of the
@@ -541,7 +560,8 @@
  */
 class UnlinkedReference {
   /**
-   * Name of the entity being referred to.
+   * Name of the entity being referred to.  The empty string refers to the
+   * pseudo-type `dynamic`.
    */
   String name;
 
@@ -607,21 +627,33 @@
   /**
    * Index into [UnlinkedLibrary.references] for the type being referred to, or
    * zero if this is a reference to a type parameter.
+   *
+   * Note that since zero is also a valid index into
+   * [UnlinkedLibrary.references], we cannot distinguish between references to
+   * type parameters and references to types by checking [reference] against
+   * zero.  To distinguish between references to type parameters and references
+   * to types, check whether [paramReference] is zero.
    */
   int reference;
 
   /**
-   * If this is a reference to a type parameter, one-based index into
-   * [UnlinkedClass.typeParameters] or [UnlinkedTypedef.typeParameters] for the
-   * parameter being referenced.  Otherwise zero.
+   * If this is a reference to a type parameter, one-based index into the list
+   * of [UnlinkedTypeParam]s currently in effect.  Indexing is done using De
+   * Bruijn index conventions; that is, innermost parameters come first, and
+   * if a class or method has multiple parameters, they are indexed from right
+   * to left.  So for instance, if the enclosing declaration is
    *
-   * If generic method syntax is enabled, this may also be a one-based index
-   * into [UnlinkedExecutable.typeParameters].  Note that this creates an
-   * ambiguity since it allows executables with type parameters to be nested
-   * inside other declarations with type parameters (which might themselves be
-   * executables).  The ambiguity is resolved by considering this to be a
-   * one-based index into a list that concatenates all type parameters that are
-   * in scope, listing the outermost type parameters first.
+   *     class C<T,U> {
+   *       m<V,W> {
+   *         ...
+   *       }
+   *     }
+   *
+   * Then [paramReference] values of 1, 2, 3, and 4 represent W, V, U, and T,
+   * respectively.
+   *
+   * If the type being referred to is not a type parameter, [paramReference] is
+   * zero.
    */
   int paramReference;
 
diff --git a/pkg/analyzer/tool/summary/idl_model.dart b/pkg/analyzer/tool/summary/idl_model.dart
new file mode 100644
index 0000000..e298b97
--- /dev/null
+++ b/pkg/analyzer/tool/summary/idl_model.dart
@@ -0,0 +1,70 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * This file contains a set of concrete classes representing an in-memory
+ * semantic model of the IDL used to code generate summary serialization and
+ * deserialization code.
+ */
+library analyzer.tool.summary.idl_model;
+
+/**
+ * Information about a single class defined in the IDL.
+ */
+class ClassDeclaration {
+  /**
+   * Fields defined in the class.
+   */
+  final Map<String, FieldType> fields = <String, FieldType>{};
+
+  /**
+   * Indicates whether the class has the `topLevel` annotation.
+   */
+  final bool isTopLevel;
+
+  ClassDeclaration(this.isTopLevel);
+}
+
+/**
+ * Information about a single enum defined in the IDL.
+ */
+class EnumDeclaration {
+  /**
+   * List of enumerated values.
+   */
+  final List<String> values = <String>[];
+}
+
+/**
+ * Information about the type of a class field defined in the IDL.
+ */
+class FieldType {
+  /**
+   * Type of the field (e.g. 'int').
+   */
+  final String typeName;
+
+  /**
+   * Indicates whether this field contains a list of the type specified in
+   * [typeName].
+   */
+  final bool isList;
+
+  FieldType(this.typeName, this.isList);
+}
+
+/**
+ * Top level representation of the summary IDL.
+ */
+class Idl {
+  /**
+   * Classes defined in the IDL.
+   */
+  final Map<String, ClassDeclaration> classes = <String, ClassDeclaration>{};
+
+  /**
+   * Enums defined in the IDL.
+   */
+  final Map<String, EnumDeclaration> enums = <String, EnumDeclaration>{};
+}
diff --git a/pkg/analyzer/tool/task_dependency_graph/check_test.dart b/pkg/analyzer/tool/task_dependency_graph/check_test.dart
index a2d1118..3d64a85 100644
--- a/pkg/analyzer/tool/task_dependency_graph/check_test.dart
+++ b/pkg/analyzer/tool/task_dependency_graph/check_test.dart
@@ -6,6 +6,7 @@
 
 import 'dart:io';
 
+import 'package:analyzer/src/codegen/tools.dart';
 import 'package:path/path.dart';
 
 import 'generate.dart';
@@ -16,19 +17,7 @@
  */
 main() {
   String script = Platform.script.toFilePath(windows: Platform.isWindows);
-  Driver driver = new Driver();
-  if (!driver.checkFile()) {
-    print('${driver.file.absolute} does not have expected contents.');
-    print('Please regenerate using:');
-    String executable = Platform.executable;
-    String packageRoot = '';
-    if (Platform.packageRoot.isNotEmpty) {
-      packageRoot = ' --package-root=${Platform.packageRoot}';
-    }
-    String generateScript = join(dirname(script), 'generate.dart');
-    print('  $executable$packageRoot $generateScript');
-    exit(1);
-  } else {
-    print('Generated file is up to date.');
-  }
+  String pkgPath = normalize(join(dirname(script), '..', '..'));
+  GeneratedContent.checkAll(pkgPath, 'tool/task_dependency_graph/generate.dart',
+      <GeneratedContent>[target]);
 }
diff --git a/pkg/analyzer/tool/task_dependency_graph/generate.dart b/pkg/analyzer/tool/task_dependency_graph/generate.dart
index a98eaba..daac102 100644
--- a/pkg/analyzer/tool/task_dependency_graph/generate.dart
+++ b/pkg/analyzer/tool/task_dependency_graph/generate.dart
@@ -23,6 +23,7 @@
 import 'package:analyzer/analyzer.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/codegen/tools.dart';
 import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
@@ -32,14 +33,21 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:path/path.dart' as path;
+import 'package:path/path.dart';
 
 /**
  * Generate the target .dot file.
  */
 main() {
-  new Driver().generateFile();
+  String script = Platform.script.toFilePath(windows: Platform.isWindows);
+  String pkgPath = normalize(join(dirname(script), '..', '..'));
+  GeneratedContent.generateAll(pkgPath, <GeneratedContent>[target]);
 }
 
+final GeneratedFile target = new GeneratedFile(
+    'tool/task_dependency_graph/tasks.dot',
+    (String pkgPath) => new Driver(pkgPath).generateFileContents());
+
 typedef void GetterFinderCallback(PropertyAccessorElement element);
 
 class Driver {
@@ -52,9 +60,7 @@
   InterfaceType extensionPointIdType;
   final String rootDir;
 
-  Driver()
-      : rootDir =
-            findRoot(Platform.script.toFilePath(windows: Platform.isWindows));
+  Driver(String pkgPath) : rootDir = new Directory(pkgPath).absolute.path;
 
   /**
    * Get an [io.File] object corresponding to the file in which the generated
@@ -64,18 +70,6 @@
       path.join(rootDir, 'tool', 'task_dependency_graph', 'tasks.dot'));
 
   /**
-   * Determine if the output [file] contains the expected contents.
-   */
-  bool checkFile() {
-    String expectedContents = generateFileContents();
-    String actualContents = file.readAsStringSync();
-    // Normalize Windows line endings to Unix line endings so that the
-    // comparison doesn't fail on Windows.
-    actualContents = actualContents.replaceAll('\r\n', '\n');
-    return expectedContents == actualContents;
-  }
-
-  /**
    * Starting at [node], find all calls to registerExtension() which refer to
    * the given [extensionIdVariable], and execute [callback] for the associated
    * result descriptors.
@@ -123,14 +117,6 @@
   }
 
   /**
-   * Generate the task dependency graph and write it to the output [file].
-   */
-  void generateFile() {
-    String fileContents = generateFileContents();
-    file.writeAsStringSync(fileContents);
-  }
-
-  /**
    * Generate the task dependency graph and return it as a [String].
    */
   String generateFileContents() {
@@ -268,21 +254,6 @@
     throw new Exception(
         'Could not find extension ID corresponding to $resultListGetterName');
   }
-
-  /**
-   * Find the root directory of the analyzer package by proceeding
-   * upward to the 'tool' dir, and then going up one more directory.
-   */
-  static String findRoot(String pathname) {
-    while (path.basename(pathname) != 'tool') {
-      String parent = path.dirname(pathname);
-      if (parent.length >= pathname.length) {
-        throw new Exception("Can't find root directory");
-      }
-      pathname = parent;
-    }
-    return path.dirname(pathname);
-  }
 }
 
 /**
diff --git a/pkg/compiler/lib/compiler_new.dart b/pkg/compiler/lib/compiler_new.dart
index 7d4ef18..b6c1e4f 100644
--- a/pkg/compiler/lib/compiler_new.dart
+++ b/pkg/compiler/lib/compiler_new.dart
@@ -168,7 +168,7 @@
     throw new ArgumentError("compilerOutput must be non-null");
   }
 
-  Compiler compiler = new Compiler(
+  CompilerImpl compiler = new CompilerImpl(
       compilerInput,
       compilerOutput,
       compilerDiagnostics,
diff --git a/pkg/compiler/lib/src/apiimpl.dart b/pkg/compiler/lib/src/apiimpl.dart
index fdcbd37..3bd085f 100644
--- a/pkg/compiler/lib/src/apiimpl.dart
+++ b/pkg/compiler/lib/src/apiimpl.dart
@@ -14,29 +14,37 @@
     NonFilePackagesDirectoryPackages;
 import 'package:package_config/src/util.dart' show
     checkValidPackageUri;
-import 'package:sdk_library_metadata/libraries.dart' as library_info;
 
 import '../compiler_new.dart' as api;
 import 'commandline_options.dart';
 import 'common.dart';
 import 'common/tasks.dart' show
     GenericTask;
-import 'compiler.dart' as leg;
+import 'compiler.dart';
 import 'diagnostics/diagnostic_listener.dart' show
     DiagnosticOptions;
 import 'diagnostics/messages.dart' show
     Message;
 import 'elements/elements.dart' as elements;
 import 'io/source_file.dart';
+import 'platform_configuration.dart' as platform_configuration;
 import 'script.dart';
 
 const bool forceIncrementalSupport =
     const bool.fromEnvironment('DART2JS_EXPERIMENTAL_INCREMENTAL_SUPPORT');
 
-class Compiler extends leg.Compiler {
+/// Locations of the platform descriptor files relative to the library root.
+const String _clientPlatform = "lib/dart_client.platform";
+const String _serverPlatform = "lib/dart_server.platform";
+const String _sharedPlatform = "lib/dart_shared.platform";
+const String _dart2dartPlatform = "lib/dart2dart.platform";
+
+/// Implements the [Compiler] using a [api.CompilerInput] for supplying the
+/// sources.
+class CompilerImpl extends Compiler {
   api.CompilerInput provider;
   api.CompilerDiagnostics handler;
-  final Uri libraryRoot;
+  final Uri platformConfigUri;
   final Uri packageConfig;
   final Uri packageRoot;
   final api.PackagesDiscoveryProvider packagesDiscoveryProvider;
@@ -44,23 +52,29 @@
   List<String> options;
   Map<String, dynamic> environment;
   bool mockableLibraryUsed = false;
-  final Set<library_info.Category> allowedLibraryCategories;
+
+  /// A mapping of the dart: library-names to their location.
+  ///
+  /// Initialized in [setupSdk].
+  Map<String, Uri> sdkLibraries;
 
   GenericTask userHandlerTask;
   GenericTask userProviderTask;
   GenericTask userPackagesDiscoveryTask;
 
-  Compiler(this.provider,
+  Uri get libraryRoot => platformConfigUri.resolve(".");
+
+  CompilerImpl(this.provider,
            api.CompilerOutput outputProvider,
            this.handler,
-           this.libraryRoot,
+           Uri libraryRoot,
            this.packageRoot,
            List<String> options,
            this.environment,
            [this.packageConfig,
             this.packagesDiscoveryProvider])
       : this.options = options,
-        this.allowedLibraryCategories = getAllowedLibraryCategories(options),
+        this.platformConfigUri = resolvePlatformConfig(libraryRoot, options),
         super(
             outputProvider: outputProvider,
             enableTypeAssertions: hasOption(options, Flags.enableCheckedMode),
@@ -173,37 +187,41 @@
     return const <String>[];
   }
 
-  static Set<library_info.Category> getAllowedLibraryCategories(
-      List<String> options) {
-    Iterable<library_info.Category> categories =
-      extractCsvOption(options, '--categories=')
-          .map(library_info.parseCategory)
-          .where((x) => x != null);
-    if (categories.isEmpty) {
-      return new Set.from([library_info.Category.client]);
+  static Uri resolvePlatformConfig(Uri libraryRoot,
+                                   List<String> options) {
+    String platformConfigPath =
+        extractStringOption(options, "--platform-config=", null);
+    if (platformConfigPath != null) {
+      return libraryRoot.resolve(platformConfigPath);
+    } else if (hasOption(options, '--output-type=dart')) {
+      return libraryRoot.resolve(_dart2dartPlatform);
+    } else {
+      Iterable<String> categories = extractCsvOption(options, '--categories=');
+      if (categories.length == 0) {
+        return libraryRoot.resolve(_clientPlatform);
+      }
+      assert(categories.length <= 2);
+      if (categories.contains("Client")) {
+        if (categories.contains("Server")) {
+          return libraryRoot.resolve(_sharedPlatform);
+        }
+        return libraryRoot.resolve(_clientPlatform);
+      }
+      assert(categories.contains("Server"));
+      return libraryRoot.resolve(_serverPlatform);
     }
-    return new Set.from(categories);
   }
 
   static bool hasOption(List<String> options, String option) {
     return options.indexOf(option) >= 0;
   }
 
-  String lookupPatchPath(String dartLibraryName) {
-    library_info.LibraryInfo info = lookupLibraryInfo(dartLibraryName);
-    if (info == null) return null;
-    if (!info.isDart2jsLibrary) return null;
-    String path = info.dart2jsPatchPath;
-    if (path == null) return null;
-    return "lib/$path";
-  }
-
   void log(message) {
     callUserHandler(
         null, null, null, null, message, api.Diagnostic.VERBOSE_INFO);
   }
 
-  /// See [leg.Compiler.translateResolvedUri].
+  /// See [Compiler.translateResolvedUri].
   Uri translateResolvedUri(elements.LibraryElement importingLibrary,
                            Uri resolvedUri, Spannable spannable) {
     if (resolvedUri.scheme == 'dart') {
@@ -302,81 +320,58 @@
   }
 
   /// Translates "resolvedUri" with scheme "dart" to a [uri] resolved relative
-  /// to [libraryRoot] according to the information in [library_info.libraries].
+  /// to [platformConfigUri] according to the information in the file at
+  /// [platformConfigUri].
   ///
   /// Returns null and emits an error if the library could not be found or
   /// imported into [importingLibrary].
   ///
-  /// If [importingLibrary] is a platform or patch library all dart2js libraries
-  /// can be resolved. Otherwise only libraries with categories in
-  /// [allowedLibraryCategories] can be resolved.
+  /// Internal libraries (whose name starts with '_') can be only resolved if
+  /// [importingLibrary] is a platform or patch library.
   Uri translateDartUri(elements.LibraryElement importingLibrary,
                        Uri resolvedUri, Spannable spannable) {
 
-    library_info.LibraryInfo libraryInfo = lookupLibraryInfo(resolvedUri.path);
+    Uri location = lookupLibraryUri(resolvedUri.path);
 
-    bool allowInternalLibraryAccess = false;
-    if (importingLibrary != null) {
-      if (importingLibrary.isPlatformLibrary || importingLibrary.isPatch) {
-        allowInternalLibraryAccess = true;
-      } else if (importingLibrary.canonicalUri.path.contains(
-          'sdk/tests/compiler/dart2js_native')) {
-        allowInternalLibraryAccess = true;
-      }
+    if (location == null) {
+      reporter.reportErrorMessage(
+          spannable,
+          MessageKind.LIBRARY_NOT_FOUND,
+          {'resolvedUri': resolvedUri});
+      return null;
     }
 
-    String computePath() {
-      if (libraryInfo == null) {
-        return null;
-      } else if (!libraryInfo.isDart2jsLibrary) {
-        return null;
-      } else {
-        if (libraryInfo.isInternal &&
-            !allowInternalLibraryAccess) {
-          if (importingLibrary != null) {
-            reporter.reportErrorMessage(
-                spannable,
-                MessageKind.INTERNAL_LIBRARY_FROM,
-                {'resolvedUri': resolvedUri,
-                  'importingUri': importingLibrary.canonicalUri});
-          } else {
-            reporter.reportErrorMessage(
-                spannable,
-                MessageKind.INTERNAL_LIBRARY,
-                {'resolvedUri': resolvedUri});
-            registerDisallowedLibraryUse(resolvedUri);
-          }
-          return null;
-        } else if (!allowInternalLibraryAccess &&
-            !allowedLibraryCategories.any(libraryInfo.categories.contains)) {
-          registerDisallowedLibraryUse(resolvedUri);
-          // TODO(sigurdm): Currently we allow the sdk libraries to import
-          // libraries from any category. We might want to revisit this.
-          return null;
+    if (resolvedUri.path.startsWith('_')  ) {
+      bool allowInternalLibraryAccess = importingLibrary != null &&
+          (importingLibrary.isPlatformLibrary ||
+              importingLibrary.isPatch ||
+              importingLibrary.canonicalUri.path
+                  .contains('sdk/tests/compiler/dart2js_native'));
+
+      if (!allowInternalLibraryAccess) {
+        if (importingLibrary != null) {
+          reporter.reportErrorMessage(
+              spannable,
+              MessageKind.INTERNAL_LIBRARY_FROM,
+              {'resolvedUri': resolvedUri,
+                'importingUri': importingLibrary.canonicalUri});
         } else {
-          return (libraryInfo.dart2jsPath != null)
-              ? libraryInfo.dart2jsPath
-              : libraryInfo.path;
+          reporter.reportErrorMessage(
+              spannable,
+              MessageKind.INTERNAL_LIBRARY,
+              {'resolvedUri': resolvedUri});
+          registerDisallowedLibraryUse(resolvedUri);
         }
+        return null;
       }
     }
 
-    String path = computePath();
-
-    if (path == null) {
-      if (libraryInfo == null) {
-        reporter.reportErrorMessage(
-            spannable,
-            MessageKind.LIBRARY_NOT_FOUND,
-            {'resolvedUri': resolvedUri});
-      } else {
-        reporter.reportErrorMessage(
-            spannable,
-            MessageKind.LIBRARY_NOT_SUPPORTED,
-            {'resolvedUri': resolvedUri});
-      }
-      // TODO(johnniwinther): Support signaling the error through the returned
-      // value.
+    if (location.scheme == "unsupported") {
+      reporter.reportErrorMessage(
+          spannable,
+          MessageKind.LIBRARY_NOT_SUPPORTED,
+          {'resolvedUri': resolvedUri});
+      registerDisallowedLibraryUse(resolvedUri);
       return null;
     }
 
@@ -386,13 +381,7 @@
       // supports this use case better.
       mockableLibraryUsed = true;
     }
-    return libraryRoot.resolve("lib/$path");
-  }
-
-  Uri resolvePatchUri(String dartLibraryPath) {
-    String patchPath = lookupPatchPath(dartLibraryPath);
-    if (patchPath == null) return null;
-    return libraryRoot.resolve(patchPath);
+    return location;
   }
 
   Uri translatePackageUri(Spannable node, Uri uri) {
@@ -418,11 +407,14 @@
   Future<elements.LibraryElement> analyzeUri(
       Uri uri,
       {bool skipLibraryWithPartOfTag: true}) {
-    if (packages == null) {
-      return setupPackages(uri).then((_) => super.analyzeUri(uri));
+    List<Future> setupFutures = new List<Future>();
+    if (sdkLibraries == null) {
+      setupFutures.add(setupSdk());
     }
-    return super.analyzeUri(
-        uri, skipLibraryWithPartOfTag: skipLibraryWithPartOfTag);
+    if (packages == null) {
+      setupFutures.add(setupPackages(uri));
+    }
+    return Future.wait(setupFutures).then((_) => super.analyzeUri(uri));
   }
 
   Future setupPackages(Uri uri) {
@@ -463,10 +455,24 @@
     return new Future.value();
   }
 
-  Future<bool> run(Uri uri) {
-    log('Allowed library categories: $allowedLibraryCategories');
+  Future<Null> setupSdk() {
+    if (sdkLibraries == null) {
+      return platform_configuration.load(platformConfigUri, provider)
+          .then((Map<String, Uri> mapping) {
+        sdkLibraries = mapping;
+      });
+    } else {
+      // The incremental compiler sets up the sdk before run.
+      // Therefore this will be called a second time.
+      return new Future.value(null);
+    }
+  }
 
-    return setupPackages(uri).then((_) {
+  Future<bool> run(Uri uri) {
+    log('Using platform configuration at ${platformConfigUri}');
+
+    return Future.wait([setupSdk(), setupPackages(uri)]).then((_) {
+      assert(sdkLibraries != null);
       assert(packages != null);
 
       return super.run(uri).then((bool success) {
@@ -493,13 +499,6 @@
   void reportDiagnostic(DiagnosticMessage message,
                         List<DiagnosticMessage> infos,
                         api.Diagnostic kind) {
-    // TODO(johnniwinther): Move this to the [DiagnosticReporter]?
-    if (kind == api.Diagnostic.ERROR ||
-        kind == api.Diagnostic.CRASH ||
-        (reporter.options.fatalWarnings &&
-         kind == api.Diagnostic.WARNING)) {
-      compilationFailed = true;
-    }
     _reportDiagnosticMessage(message, kind);
     for (DiagnosticMessage info in infos) {
       _reportDiagnosticMessage(info, api.Diagnostic.INFO);
@@ -557,10 +556,15 @@
     }
   }
 
-
   fromEnvironment(String name) => environment[name];
 
-  library_info.LibraryInfo lookupLibraryInfo(String libraryName) {
-    return library_info.libraries[libraryName];
+  Uri lookupLibraryUri(String libraryName) {
+    assert(invariant(NO_LOCATION_SPANNABLE,
+        sdkLibraries != null, message: "setupSdk() has not been run"));
+    return sdkLibraries[libraryName];
+  }
+
+  Uri resolvePatchUri(String libraryName) {
+    return backend.resolvePatchUri(libraryName, platformConfigUri);
   }
 }
diff --git a/pkg/compiler/lib/src/closure.dart b/pkg/compiler/lib/src/closure.dart
index da13773..d015b7c 100644
--- a/pkg/compiler/lib/src/closure.dart
+++ b/pkg/compiler/lib/src/closure.dart
@@ -103,7 +103,7 @@
 // TODO(ahe): These classes continuously cause problems.  We need to
 // find a more general solution.
 class ClosureFieldElement extends ElementX
-    implements FieldElement, CapturedVariable {
+    implements FieldElement, CapturedVariable, PrivatelyNamedJSEntity {
   /// The [BoxLocal] or [LocalElement] being accessed through the field.
   final Local local;
 
@@ -120,6 +120,11 @@
 
   MemberElement get memberContext => closureClass.methodElement.memberContext;
 
+  @override
+  Entity get declaredEntity => local;
+  @override
+  Entity get rootOfScope => closureClass;
+
   bool get hasNode => false;
 
   Node get node {
@@ -196,8 +201,8 @@
               STATE_DONE) {
     JavaScriptBackend backend = compiler.backend;
     ClassElement superclass = methodElement.isInstanceMember
-        ? backend.boundClosureClass
-        : backend.closureClass;
+        ? backend.helpers.boundClosureClass
+        : backend.helpers.closureClass;
     superclass.ensureResolved(compiler.resolution);
     supertype = superclass.thisType;
     interfaces = const Link<DartType>();
@@ -246,10 +251,12 @@
 // TODO(ngeoffray, ahe): These classes continuously cause problems.  We need to
 // find a more general solution.
 class BoxFieldElement extends ElementX
-    implements TypedElement, CapturedVariable, FieldElement {
+    implements TypedElement, CapturedVariable, FieldElement,
+        PrivatelyNamedJSEntity {
   final BoxLocal box;
 
-  BoxFieldElement(String name, this.variableElement, BoxLocal box)
+  BoxFieldElement(String name, this.variableElement,
+      BoxLocal box)
       : this.box = box,
         super(name, ElementKind.FIELD, box.executableContext);
 
@@ -257,6 +264,11 @@
 
   DartType get type => variableElement.type;
 
+  @override
+  Entity get declaredEntity => variableElement;
+  @override
+  Entity get rootOfScope => box;
+
   final VariableElement variableElement;
 
   accept(ElementVisitor visitor, arg) {
@@ -519,6 +531,8 @@
   ///
   /// Also, the names should be distinct from real field names to prevent
   /// clashes with selectors for those fields.
+  ///
+  /// These names are not used in generated code, just as element name.
   String getClosureVariableName(String name, int id) {
     return "_captured_${name}_$id";
   }
@@ -532,6 +546,8 @@
   ///
   /// Also, the names should be distinct from real field names to prevent
   /// clashes with selectors for those fields.
+  ///
+  /// These names are not used in generated code, just as element name.
   String getBoxFieldName(int id) {
     return "_box_$id";
   }
@@ -906,6 +922,7 @@
   }
 
   visitFor(For node) {
+    List<LocalVariableElement> boxedLoopVariables = <LocalVariableElement>[];
     inNewScope(node, () {
       // First visit initializer and update so we can easily check if a loop
       // variable was captured in one of these subexpressions.
@@ -929,24 +946,27 @@
       // condition or body are indeed flagged as mutated.
       if (node.conditionStatement != null) visit(node.conditionStatement);
       if (node.body != null) visit(node.body);
+
+      // See if we have declared loop variables that need to be boxed.
+      if (node.initializer == null) return;
+      VariableDefinitions definitions =
+          node.initializer.asVariableDefinitions();
+      if (definitions == null) return;
+      for (Link<Node> link = definitions.definitions.nodes;
+           !link.isEmpty;
+           link = link.tail) {
+        Node definition = link.head;
+        LocalVariableElement element = elements[definition];
+        // Non-mutated variables should not be boxed.  The mutatedVariables set
+        // gets cleared when 'inNewScope' returns, so check it here.
+        if (isCapturedVariable(element) && mutatedVariables.contains(element)) {
+          boxedLoopVariables.add(element);
+        }
+      }
     });
-    // See if we have declared loop variables that need to be boxed.
-    if (node.initializer == null) return;
-    VariableDefinitions definitions = node.initializer.asVariableDefinitions();
-    if (definitions == null) return;
     ClosureScope scopeData = closureData.capturingScopes[node];
     if (scopeData == null) return;
-    List<LocalVariableElement> result = <LocalVariableElement>[];
-    for (Link<Node> link = definitions.definitions.nodes;
-         !link.isEmpty;
-         link = link.tail) {
-      Node definition = link.head;
-      LocalVariableElement element = elements[definition];
-      if (isCapturedVariable(element)) {
-        result.add(element);
-      }
-    }
-    scopeData.boxedLoopVariables = result;
+    scopeData.boxedLoopVariables = boxedLoopVariables;
   }
 
   /** Returns a non-unique name for the given closure element. */
@@ -994,6 +1014,9 @@
     String closureName = computeClosureName(element);
     ClosureClassElement globalizedElement = new ClosureClassElement(
         node, closureName, compiler, element);
+    // Extend [globalizedElement] as an instantiated class in the closed world.
+    compiler.world.registerClass(
+        globalizedElement, isDirectlyInstantiated: true);
     FunctionElement callElement =
         new SynthesizedCallMethodElementX(Identifiers.call,
                                           element,
@@ -1130,3 +1153,14 @@
     return typeVariable == other.typeVariable;
   }
 }
+
+///
+/// Move the below classes to a JS model eventually.
+///
+abstract class JSEntity implements Entity {
+  Entity get declaredEntity;
+}
+
+abstract class PrivatelyNamedJSEntity implements JSEntity {
+  Entity get rootOfScope;
+}
diff --git a/pkg/compiler/lib/src/common/backend_api.dart b/pkg/compiler/lib/src/common/backend_api.dart
index 4638207..ff49bcc 100644
--- a/pkg/compiler/lib/src/common/backend_api.dart
+++ b/pkg/compiler/lib/src/common/backend_api.dart
@@ -7,6 +7,10 @@
 import 'dart:async' show Future;
 
 import '../common.dart';
+import '../common/codegen.dart' show
+    CodegenImpact;
+import '../common/resolution.dart' show
+    ResolutionImpact;
 import '../compiler.dart' show
     Compiler;
 import '../compile_time_constants.dart' show
@@ -31,19 +35,21 @@
 import '../enqueue.dart' show
     Enqueuer,
     CodegenEnqueuer,
-    ResolutionEnqueuer,
-    WorldImpact;
+    ResolutionEnqueuer;
 import '../io/code_output.dart' show
     CodeBuffer;
 import '../io/source_information.dart' show
     SourceInformationStrategy;
+import '../js_backend/backend_helpers.dart' as js_backend show
+    BackendHelpers;
 import '../js_backend/js_backend.dart' as js_backend show
     JavaScriptBackend;
 import '../library_loader.dart' show
     LibraryLoader,
     LoadedLibraries;
 import '../native/native.dart' as native show
-    NativeEnqueuer;
+    NativeEnqueuer,
+    maybeEnableNative;
 import '../patch_parser.dart' show
     checkNativeAnnotation, checkJsInteropAnnotation;
 import '../resolution/tree_elements.dart' show
@@ -53,13 +59,13 @@
     Send;
 import '../universe/call_structure.dart' show
     CallStructure;
+import '../universe/world_impact.dart' show
+    WorldImpact;
 
 import 'codegen.dart' show
     CodegenWorkItem;
 import 'registry.dart' show
     Registry;
-import 'resolution.dart' show
-    ResolutionCallbacks;
 import 'tasks.dart' show
     CompilerTask;
 import 'work.dart' show
@@ -86,8 +92,8 @@
   /// the frontend and the backend.
   ConstantCompilerTask get constantCompilerTask;
 
-  /// Backend callback methods for the resolution phase.
-  ResolutionCallbacks get resolutionCallbacks;
+  /// Backend transformation methods for the world impacts.
+  ImpactTransformer get impactTransformer;
 
   /// The strategy used for collecting and emitting source information.
   SourceInformationStrategy get sourceInformationStrategy {
@@ -108,6 +114,7 @@
   void initializeHelperClasses() {}
 
   void enqueueHelpers(ResolutionEnqueuer world, Registry registry);
+
   WorldImpact codegen(CodegenWorkItem work);
 
   // The backend determines the native resolution enqueuer, with a no-op
@@ -174,11 +181,6 @@
     enqueuer.registerInstantiatedType(type, mirrorUsage: mirrorUsage);
   }
 
-  /// Register an is check to the backend.
-  void registerIsCheckForCodegen(DartType type,
-                                 Enqueuer enqueuer,
-                                 Registry registry) {}
-
   /// Register a runtime type variable bound tests between [typeArgument] and
   /// [bound].
   void registerTypeVariableBoundsSubtypeCheck(DartType typeArgument,
@@ -225,33 +227,39 @@
   /// Call this method to enable support for isolates.
   void enableIsolateSupport(Enqueuer enqueuer) {}
 
-  void registerRequiredType(DartType type) {}
-
   void registerConstSymbol(String name) {}
 
   bool isNullImplementation(ClassElement cls) {
-    return cls == compiler.nullClass;
+    return cls == compiler.coreClasses.nullClass;
   }
 
-  ClassElement get intImplementation => compiler.intClass;
-  ClassElement get doubleImplementation => compiler.doubleClass;
-  ClassElement get numImplementation => compiler.numClass;
-  ClassElement get stringImplementation => compiler.stringClass;
-  ClassElement get listImplementation => compiler.listClass;
-  ClassElement get growableListImplementation => compiler.listClass;
-  ClassElement get fixedListImplementation => compiler.listClass;
-  ClassElement get constListImplementation => compiler.listClass;
-  ClassElement get mapImplementation => compiler.mapClass;
-  ClassElement get constMapImplementation => compiler.mapClass;
-  ClassElement get functionImplementation => compiler.functionClass;
-  ClassElement get typeImplementation => compiler.typeClass;
-  ClassElement get boolImplementation => compiler.boolClass;
-  ClassElement get nullImplementation => compiler.nullClass;
-  ClassElement get uint32Implementation => compiler.intClass;
-  ClassElement get uint31Implementation => compiler.intClass;
-  ClassElement get positiveIntImplementation => compiler.intClass;
+  ClassElement get intImplementation => compiler.coreClasses.intClass;
+  ClassElement get doubleImplementation => compiler.coreClasses.doubleClass;
+  ClassElement get numImplementation => compiler.coreClasses.numClass;
+  ClassElement get stringImplementation => compiler.coreClasses.stringClass;
+  ClassElement get listImplementation => compiler.coreClasses.listClass;
+  ClassElement get growableListImplementation => compiler.coreClasses.listClass;
+  ClassElement get fixedListImplementation => compiler.coreClasses.listClass;
+  ClassElement get constListImplementation => compiler.coreClasses.listClass;
+  ClassElement get mapImplementation => compiler.coreClasses.mapClass;
+  ClassElement get constMapImplementation => compiler.coreClasses.mapClass;
+  ClassElement get functionImplementation => compiler.coreClasses.functionClass;
+  ClassElement get typeImplementation => compiler.coreClasses.typeClass;
+  ClassElement get boolImplementation => compiler.coreClasses.boolClass;
+  ClassElement get nullImplementation => compiler.coreClasses.nullClass;
+  ClassElement get uint32Implementation => compiler.coreClasses.intClass;
+  ClassElement get uint31Implementation => compiler.coreClasses.intClass;
+  ClassElement get positiveIntImplementation => compiler.coreClasses.intClass;
+  ClassElement get syncStarIterableImplementation =>
+      compiler.coreClasses.iterableClass;
+  ClassElement get asyncFutureImplementation =>
+      compiler.coreClasses.futureClass;
+  ClassElement get asyncStarStreamImplementation =>
+      compiler.coreClasses.streamClass;
 
-  ClassElement defaultSuperclass(ClassElement element) => compiler.objectClass;
+  ClassElement defaultSuperclass(ClassElement element) {
+    return compiler.coreClasses.objectClass;
+  }
 
   bool isInterceptorClass(ClassElement element) => false;
 
@@ -259,6 +267,20 @@
   /// backend has specialized handling for the element.
   bool isForeign(Element element) => false;
 
+  /// Returns `true` if [element] is a native element, that is, that the
+  /// corresponding entity already exists in the target language.
+  bool isNative(Element element) => false;
+
+  /// Returns `true` if [element] is implemented via typed JavaScript interop.
+  // TODO(johnniwinther): Move this to [JavaScriptBackend].
+  bool isJsInterop(Element element) => false;
+
+  /// Returns `true` if the `native` pseudo keyword is supported for [library].
+  bool canLibraryUseNative(LibraryElement library) {
+    // TODO(johnniwinther): Move this to [JavaScriptBackend].
+    return native.maybeEnableNative(compiler, library);
+  }
+
   /// Processes [element] for resolution and returns the [FunctionElement] that
   /// defines the implementation of [element].
   FunctionElement resolveExternalFunction(FunctionElement element) => element;
@@ -270,8 +292,8 @@
     // TODO(johnniwinther): Remove this when patching is only done by the
     // JavaScript backend.
     Uri canonicalUri = library.canonicalUri;
-    if (canonicalUri == js_backend.JavaScriptBackend.DART_JS_HELPER ||
-        canonicalUri == js_backend.JavaScriptBackend.DART_INTERCEPTORS) {
+    if (canonicalUri == js_backend.BackendHelpers.DART_JS_HELPER ||
+        canonicalUri == js_backend.BackendHelpers.DART_INTERCEPTORS) {
       return true;
     }
     return false;
@@ -286,7 +308,8 @@
   /// This method is called immediately after the [library] and its parts have
   /// been scanned.
   Future onLibraryScanned(LibraryElement library, LibraryLoader loader) {
-    if (library.canUseNative) {
+    // TODO(johnniwinther): Move this to [JavaScriptBackend].
+    if (canLibraryUseNative(library)) {
       library.forEachLocalMember((Element element) {
         if (element.isClass) {
           checkNativeAnnotation(compiler, element);
@@ -296,7 +319,7 @@
     checkJsInteropAnnotation(compiler, library);
     library.forEachLocalMember((Element element) {
       checkJsInteropAnnotation(compiler, element);
-      if (element.isClass && element.isJsInterop) {
+      if (element.isClass && isJsInterop(element)) {
         ClassElement classElement = element;
         classElement.forEachMember((_, memberElement) {
           checkJsInteropAnnotation(compiler, memberElement);
@@ -395,6 +418,12 @@
                            Element element,
                            CallStructure callStructure,
                            ForeignResolver resolver) {}
+
+  /// Returns the location of the patch-file associated with [libraryName]
+  /// resolved from [plaformConfigUri].
+  ///
+  /// Returns null if there is none.
+  Uri resolvePatchUri(String libraryName, Uri plaformConfigUri);
 }
 
 /// Interface for resolving calls to foreign functions.
@@ -409,3 +438,18 @@
   /// Resolves [typeName] to a type in the context of [node].
   DartType resolveTypeFromString(Node node, String typeName);
 }
+
+/// Backend transformation methods for the world impacts.
+class ImpactTransformer {
+  /// Transform the [ResolutionImpact] into a [WorldImpact] adding the
+  /// backend dependencies for features used in [worldImpact].
+  WorldImpact transformResolutionImpact(ResolutionImpact worldImpact) {
+    return worldImpact;
+  }
+
+  /// Transform the [CodegenImpact] into a [WorldImpact] adding the
+  /// backend dependencies for features used in [worldImpact].
+  WorldImpact transformCodegenImpact(CodegenImpact worldImpact) {
+    return worldImpact;
+  }
+}
diff --git a/pkg/compiler/lib/src/common/codegen.dart b/pkg/compiler/lib/src/common/codegen.dart
index ab154f9..37c9855 100644
--- a/pkg/compiler/lib/src/common/codegen.dart
+++ b/pkg/compiler/lib/src/common/codegen.dart
@@ -19,148 +19,216 @@
     FunctionElement,
     LocalFunctionElement;
 import '../enqueue.dart' show
-    CodegenEnqueuer,
-    WorldImpact;
-import '../js_backend/js_backend.dart' show
-    JavaScriptBackend;
+    CodegenEnqueuer;
 import '../resolution/tree_elements.dart' show
     TreeElements;
-import '../universe/selector.dart' show
-    Selector;
-import '../universe/universe.dart' show
-    UniverseSelector;
+import '../universe/use.dart' show
+    DynamicUse,
+    StaticUse,
+    TypeUse;
+import '../universe/world_impact.dart' show
+    WorldImpact,
+    WorldImpactBuilder;
 import '../util/util.dart' show
+    Pair,
     Setlet;
 import 'registry.dart' show
-    Registry;
+    Registry,
+    EagerRegistry;
 import 'work.dart' show
     ItemCompilationContext,
     WorkItem;
 
+class CodegenImpact extends WorldImpact {
+  const CodegenImpact();
+
+  // TODO(johnniwinther): Remove this.
+  Registry get registry => null;
+
+  Iterable<ConstantValue> get compileTimeConstants => const <ConstantValue>[];
+
+  Iterable<Pair<DartType, DartType>> get typeVariableBoundsSubtypeChecks {
+    return const <Pair<DartType, DartType>>[];
+  }
+
+  Iterable<String> get constSymbols => const <String>[];
+
+  Iterable<Set<ClassElement>> get specializedGetInterceptors {
+    return const <Set<ClassElement>>[];
+  }
+
+  bool get usesInterceptor => false;
+
+  Iterable<ClassElement> get typeConstants => const <ClassElement>[];
+
+  Iterable<Element> get asyncMarkers => const <FunctionElement>[];
+}
+
+class _CodegenImpact extends WorldImpactBuilder implements CodegenImpact {
+  // TODO(johnniwinther): Remove this.
+  final Registry registry;
+
+  Setlet<ConstantValue> _compileTimeConstants;
+  Setlet<Pair<DartType, DartType>> _typeVariableBoundsSubtypeChecks;
+  Setlet<String> _constSymbols;
+  List<Set<ClassElement>> _specializedGetInterceptors;
+  bool _usesInterceptor = false;
+  Setlet<ClassElement> _typeConstants;
+  Setlet<FunctionElement> _asyncMarkers;
+
+  _CodegenImpact(this.registry);
+
+  void registerCompileTimeConstant(ConstantValue constant) {
+    if (_compileTimeConstants == null) {
+      _compileTimeConstants = new Setlet<ConstantValue>();
+    }
+    _compileTimeConstants.add(constant);
+  }
+
+  Iterable<ConstantValue> get compileTimeConstants {
+    return _compileTimeConstants != null
+        ? _compileTimeConstants : const <ConstantValue>[];
+  }
+
+  void registerTypeVariableBoundsSubtypeCheck(DartType subtype,
+                                              DartType supertype) {
+    if (_typeVariableBoundsSubtypeChecks == null) {
+      _typeVariableBoundsSubtypeChecks = new Setlet<Pair<DartType, DartType>>();
+    }
+    _typeVariableBoundsSubtypeChecks.add(
+        new Pair<DartType, DartType>(subtype, supertype));
+  }
+
+  Iterable<Pair<DartType, DartType>> get typeVariableBoundsSubtypeChecks {
+    return _typeVariableBoundsSubtypeChecks != null
+        ? _typeVariableBoundsSubtypeChecks : const <Pair<DartType, DartType>>[];
+  }
+
+  void registerConstSymbol(String name) {
+    if (_constSymbols == null) {
+      _constSymbols = new Setlet<String>();
+    }
+    _constSymbols.add(name);
+  }
+
+  Iterable<String> get constSymbols {
+    return _constSymbols != null
+        ? _constSymbols : const <String>[];
+  }
+
+  void registerSpecializedGetInterceptor(Set<ClassElement> classes) {
+    if (_specializedGetInterceptors == null) {
+      _specializedGetInterceptors = <Set<ClassElement>>[];
+    }
+    _specializedGetInterceptors.add(classes);
+  }
+
+  Iterable<Set<ClassElement>> get specializedGetInterceptors {
+    return _specializedGetInterceptors != null
+        ? _specializedGetInterceptors : const <Set<ClassElement>>[];
+  }
+
+  void registerUseInterceptor() {
+    _usesInterceptor = true;
+  }
+
+  bool get usesInterceptor => _usesInterceptor;
+
+  void registerTypeConstant(ClassElement element) {
+    if (_typeConstants == null) {
+      _typeConstants = new Setlet<ClassElement>();
+    }
+    _typeConstants.add(element);
+  }
+
+  Iterable<ClassElement> get typeConstants {
+    return _typeConstants != null
+        ? _typeConstants : const <ClassElement>[];
+  }
+
+  void registerAsyncMarker(FunctionElement element) {
+    if (_asyncMarkers == null) {
+      _asyncMarkers = new Setlet<FunctionElement>();
+    }
+    _asyncMarkers.add(element);
+  }
+
+  Iterable<Element> get asyncMarkers {
+    return _asyncMarkers != null
+        ? _asyncMarkers : const <FunctionElement>[];
+  }
+}
+
 // TODO(johnniwinther): Split this class into interface and implementation.
 // TODO(johnniwinther): Move this implementation to the JS backend.
 class CodegenRegistry extends Registry {
   final Compiler compiler;
-  final TreeElements treeElements;
+  final Element currentElement;
+  final _CodegenImpact worldImpact;
 
-  CodegenRegistry(this.compiler, this.treeElements);
+  CodegenRegistry(Compiler compiler, AstElement currentElement)
+      : this.compiler = compiler,
+        this.currentElement = currentElement,
+        this.worldImpact = new _CodegenImpact(new EagerRegistry(
+          'EagerRegistry for $currentElement', compiler.enqueuer.codegen));
 
   bool get isForResolution => false;
 
-  Element get currentElement => treeElements.analyzedElement;
-
   String toString() => 'CodegenRegistry for $currentElement';
 
-  CodegenEnqueuer get world => compiler.enqueuer.codegen;
-  JavaScriptBackend get backend => compiler.backend;
-
-  void registerAssert(bool hasMessage) {
-    // Codegen does not register asserts.  They have been lowered to calls.
-    assert(false);
-  }
-
+  @deprecated
   void registerInstantiatedClass(ClassElement element) {
-    backend.registerInstantiatedType(element.rawType, world, this);
+    registerInstantiation(element.rawType);
   }
 
-  void registerInstantiatedType(InterfaceType type) {
-    backend.registerInstantiatedType(type, world, this);
+  void registerStaticUse(StaticUse staticUse) {
+    worldImpact.registerStaticUse(staticUse);
   }
 
-  void registerStaticUse(Element element) {
-    world.registerStaticUse(element);
+  void registerDynamicUse(DynamicUse dynamicUse) {
+    worldImpact.registerDynamicUse(dynamicUse);
   }
 
-  void registerDynamicInvocation(UniverseSelector selector) {
-    world.registerDynamicInvocation(selector);
-    compiler.dumpInfoTask.elementUsesSelector(currentElement, selector);
-  }
-
-  void registerDynamicSetter(UniverseSelector selector) {
-    world.registerDynamicSetter(selector);
-    compiler.dumpInfoTask.elementUsesSelector(currentElement, selector);
-  }
-
-  void registerDynamicGetter(UniverseSelector selector) {
-    world.registerDynamicGetter(selector);
-    compiler.dumpInfoTask.elementUsesSelector(currentElement, selector);
-  }
-
-  void registerGetterForSuperMethod(Element element) {
-    world.registerGetterForSuperMethod(element);
-  }
-
-  void registerFieldGetter(Element element) {
-    world.registerFieldGetter(element);
-  }
-
-  void registerFieldSetter(Element element) {
-    world.registerFieldSetter(element);
-  }
-
-  void registerIsCheck(DartType type) {
-    world.registerIsCheck(type);
-    backend.registerIsCheckForCodegen(type, world, this);
+  void registerTypeUse(TypeUse typeUse) {
+    worldImpact.registerTypeUse(typeUse);
   }
 
   void registerCompileTimeConstant(ConstantValue constant) {
-    backend.registerCompileTimeConstant(constant, this);
+    worldImpact.registerCompileTimeConstant(constant);
   }
 
   void registerTypeVariableBoundsSubtypeCheck(DartType subtype,
                                               DartType supertype) {
-    backend.registerTypeVariableBoundsSubtypeCheck(subtype, supertype);
+    worldImpact.registerTypeVariableBoundsSubtypeCheck(subtype, supertype);
   }
 
   void registerInstantiatedClosure(LocalFunctionElement element) {
-    backend.registerInstantiatedClosure(element, this);
-  }
-
-  void registerGetOfStaticFunction(FunctionElement element) {
-    world.registerGetOfStaticFunction(element);
-  }
-
-  void registerSelectorUse(Selector selector) {
-    world.registerSelectorUse(new UniverseSelector(selector, null));
+    worldImpact.registerStaticUse(new StaticUse.closure(element));
   }
 
   void registerConstSymbol(String name) {
-    backend.registerConstSymbol(name);
+    worldImpact.registerConstSymbol(name);
   }
 
   void registerSpecializedGetInterceptor(Set<ClassElement> classes) {
-    backend.registerSpecializedGetInterceptor(classes);
+    worldImpact.registerSpecializedGetInterceptor(classes);
   }
 
   void registerUseInterceptor() {
-    backend.registerUseInterceptor(world);
+    worldImpact.registerUseInterceptor();
   }
 
   void registerTypeConstant(ClassElement element) {
-    backend.customElementsAnalysis.registerTypeConstant(element, world);
-    backend.lookupMapAnalysis.registerTypeConstant(element);
-  }
-
-  void registerStaticInvocation(Element element) {
-    world.registerStaticUse(element);
-  }
-
-  void registerSuperInvocation(Element element) {
-    world.registerStaticUse(element);
-  }
-
-  void registerDirectInvocation(Element element) {
-    world.registerStaticUse(element);
+    worldImpact.registerTypeConstant(element);
   }
 
   void registerInstantiation(InterfaceType type) {
-    backend.registerInstantiatedType(type, world, this);
+    registerTypeUse(new TypeUse.instantiation(type));
   }
 
   void registerAsyncMarker(FunctionElement element) {
-    backend.registerAsyncMarker(element, world, this);
+    worldImpact.registerAsyncMarker(element);
   }
-
 }
 
 /// [WorkItem] used exclusively by the [CodegenEnqueuer].
@@ -193,7 +261,9 @@
   WorldImpact run(Compiler compiler, CodegenEnqueuer world) {
     if (world.isProcessed(element)) return const WorldImpact();
 
-    registry = new CodegenRegistry(compiler, resolutionTree);
-    return compiler.codegen(this, world);
+    registry = new CodegenRegistry(compiler, element);
+    var impact = compiler.codegen(this, world);
+    compiler.dumpInfoTask.registerImpact(element, impact);
+    return impact;
   }
 }
diff --git a/pkg/compiler/lib/src/common/names.dart b/pkg/compiler/lib/src/common/names.dart
index 45c7b1f..657cc6f 100644
--- a/pkg/compiler/lib/src/common/names.dart
+++ b/pkg/compiler/lib/src/common/names.dart
@@ -38,6 +38,9 @@
 
   /// The name of the runtime type property on 'Object'.
   static const String runtimeType_ = 'runtimeType';
+
+  /// The name of the getter returning the size of containers and strings.
+  static const String length = 'length';
 }
 
 /// [Name]s commonly used.
@@ -67,6 +70,8 @@
   static const Name INDEX_NAME = const PublicName("[]");
   static const Name INDEX_SET_NAME = const PublicName("[]=");
   static const Name CALL_NAME = Names.call;
+
+  static const Name length = const PublicName(Identifiers.length);
 }
 
 /// [Selector]s commonly used.
@@ -101,6 +106,16 @@
       new Selector.call(const PublicName("compareTo"), CallStructure.ONE_ARG);
 
   static final Selector equals = new Selector.binaryOperator('==');
+
+  static final Selector length = new Selector.getter(Names.length);
+
+  /// List of all the selectors held in static fields.
+  ///
+  /// These objects are shared between different runs in batch-mode and must
+  /// thus remain in the [Selector.canonicalizedValues] map.
+  static final List<Selector> ALL = <Selector>[
+      cancel, current, iterator, moveNext, noSuchMethod_, toString_,
+      hashCode_, compareTo, equals, length];
 }
 
 /// [Uri]s commonly used.
@@ -123,4 +138,4 @@
   /// The URI for 'dart:_native_typed_data'.
   static final Uri dart__native_typed_data =
       new Uri(scheme: 'dart', path: '_native_typed_data');
-}
\ No newline at end of file
+}
diff --git a/pkg/compiler/lib/src/common/registry.dart b/pkg/compiler/lib/src/common/registry.dart
index 055a7c6..1ba7b9d 100644
--- a/pkg/compiler/lib/src/common/registry.dart
+++ b/pkg/compiler/lib/src/common/registry.dart
@@ -5,12 +5,15 @@
 library dart2js.common.registry;
 
 import '../dart_types.dart' show
-  InterfaceType;
+    InterfaceType;
+import '../enqueue.dart' show
+    Enqueuer;
 import '../elements/elements.dart' show
-  Element,
-  FunctionElement;
-import '../universe/universe.dart' show
-  UniverseSelector;
+    Element,
+    FunctionElement;
+import '../universe/use.dart' show
+    DynamicUse,
+    StaticUse;
 
 /// Interface for registration of element dependencies.
 abstract class Registry {
@@ -19,15 +22,36 @@
 
   bool get isForResolution;
 
-  void registerDynamicInvocation(UniverseSelector selector);
+  void registerDynamicUse(DynamicUse staticUse);
 
-  void registerDynamicGetter(UniverseSelector selector);
-
-  void registerDynamicSetter(UniverseSelector selector);
-
-  void registerStaticInvocation(Element element);
+  void registerStaticUse(StaticUse staticUse);
 
   void registerInstantiation(InterfaceType type);
+}
 
-  void registerGetOfStaticFunction(FunctionElement element);
+// TODO(johnniwinther): Remove this.
+class EagerRegistry extends Registry {
+  final String name;
+  final Enqueuer world;
+
+  EagerRegistry(this.name, this.world);
+
+  bool get isForResolution => world.isResolutionQueue;
+
+  @override
+  void registerDynamicUse(DynamicUse dynamicUse) {
+    world.registerDynamicUse(dynamicUse);
+  }
+
+  @override
+  void registerInstantiation(InterfaceType type) {
+    world.registerInstantiatedType(type);
+  }
+
+  @override
+  void registerStaticUse(StaticUse staticUse) {
+    world.registerStaticUse(staticUse);
+  }
+
+  String toString() => name;
 }
diff --git a/pkg/compiler/lib/src/common/resolution.dart b/pkg/compiler/lib/src/common/resolution.dart
index 88cb4b9..727f3aa 100644
--- a/pkg/compiler/lib/src/common/resolution.dart
+++ b/pkg/compiler/lib/src/common/resolution.dart
@@ -8,6 +8,8 @@
 import '../common.dart';
 import '../compiler.dart' show
     Compiler;
+import '../constants/expressions.dart' show
+    ConstantExpression;
 import '../core_types.dart' show
     CoreTypes;
 import '../dart_types.dart' show
@@ -26,18 +28,15 @@
     TypedefElement,
     TypeVariableElement;
 import '../enqueue.dart' show
-    ResolutionEnqueuer,
-    WorldImpact;
+    ResolutionEnqueuer;
+import '../parser/element_listener.dart' show
+    ScannerOptions;
 import '../tree/tree.dart' show
     AsyncForIn,
     Send,
     TypeAnnotation;
-import '../universe/universe.dart' show
-    UniverseSelector;
-import '../util/util.dart' show
-    Setlet;
-import 'registry.dart' show
-    Registry;
+import '../universe/world_impact.dart' show
+    WorldImpact;
 import 'work.dart' show
     ItemCompilationContext,
     WorkItem;
@@ -59,27 +58,16 @@
   bool get isAnalyzed => _isAnalyzed;
 }
 
-// TODO(johnniwinther): Rename this to something like  `BackendResolutionApi`
-// and clean up the interface.
-/// Backend callbacks function specific to the resolution phase.
-class ResolutionCallbacks {
-  /// Transform the [ResolutionImpact] into a [WorldImpact] adding the
-  /// backend dependencies for features used in [worldImpact].
-  WorldImpact transformImpact(ResolutionImpact worldImpact) => worldImpact;
-}
-
 class ResolutionImpact extends WorldImpact {
   const ResolutionImpact();
 
-  // TODO(johnniwinther): Remove this.
-  void registerDependency(Element element) {}
-
   Iterable<Feature> get features => const <Feature>[];
-  Iterable<DartType> get requiredTypes => const <DartType>[];
   Iterable<MapLiteralUse> get mapLiterals => const <MapLiteralUse>[];
   Iterable<ListLiteralUse> get listLiterals => const <ListLiteralUse>[];
-  Iterable<DartType> get typeLiterals => const <DartType>[];
   Iterable<String> get constSymbolNames => const <String>[];
+  Iterable<ConstantExpression> get constantLiterals {
+    return const <ConstantExpression>[];
+  }
 }
 
 /// A language feature seen during resolution.
@@ -111,6 +99,8 @@
   STACK_TRACE_IN_CATCH,
   /// String interpolation.
   STRING_INTERPOLATION,
+  /// String juxtaposition.
+  STRING_JUXTAPOSITION,
   /// An implicit call to `super.noSuchMethod`, like calling an unresolved
   /// super method.
   SUPER_NO_SUCH_METHOD,
@@ -182,129 +172,6 @@
   }
 }
 
-/// Mutable implementation of [WorldImpact] used to transform
-/// [ResolutionImpact] to [WorldImpact].
-// TODO(johnniwinther): Remove [Registry] when dependency is tracked directly
-// on [WorldImpact].
-class TransformedWorldImpact extends WorldImpact {
-  final ResolutionImpact worldImpact;
-
-  Setlet<Element> _staticUses;
-  Setlet<InterfaceType> _instantiatedTypes;
-  Setlet<UniverseSelector> _dynamicGetters;
-  Setlet<UniverseSelector> _dynamicInvocations;
-  Setlet<UniverseSelector> _dynamicSetters;
-
-  TransformedWorldImpact(this.worldImpact);
-
-  @override
-  Iterable<DartType> get asCasts => worldImpact.asCasts;
-
-  @override
-  Iterable<DartType> get checkedModeChecks => worldImpact.checkedModeChecks;
-
-  @override
-  Iterable<MethodElement> get closurizedFunctions {
-    return worldImpact.closurizedFunctions;
-  }
-
-  @override
-  Iterable<UniverseSelector> get dynamicGetters {
-    return _dynamicGetters != null
-        ? _dynamicGetters : worldImpact.dynamicGetters;
-  }
-
-  @override
-  Iterable<UniverseSelector> get dynamicInvocations {
-    return _dynamicInvocations != null
-        ? _dynamicInvocations : worldImpact.dynamicInvocations;
-  }
-
-  @override
-  Iterable<UniverseSelector> get dynamicSetters {
-    return _dynamicSetters != null
-        ? _dynamicSetters : worldImpact.dynamicSetters;
-  }
-
-  @override
-  Iterable<DartType> get isChecks => worldImpact.isChecks;
-
-  @override
-  Iterable<Element> get staticUses {
-    if (_staticUses == null) {
-      return worldImpact.staticUses;
-    }
-    return _staticUses;
-  }
-
-  _unsupported(String message) => throw new UnsupportedError(message);
-
-  void registerDynamicGetter(UniverseSelector selector) {
-    if (_dynamicGetters == null) {
-      _dynamicGetters = new Setlet<UniverseSelector>();
-      _dynamicGetters.addAll(worldImpact.dynamicGetters);
-    }
-    _dynamicGetters.add(selector);
-  }
-
-  void registerDynamicInvocation(UniverseSelector selector) {
-    if (_dynamicInvocations == null) {
-      _dynamicInvocations = new Setlet<UniverseSelector>();
-      _dynamicInvocations.addAll(worldImpact.dynamicInvocations);
-    }
-    _dynamicInvocations.add(selector);
-  }
-
-  void registerDynamicSetter(UniverseSelector selector) {
-    if (_dynamicSetters == null) {
-      _dynamicSetters = new Setlet<UniverseSelector>();
-      _dynamicSetters.addAll(worldImpact.dynamicSetters);
-    }
-    _dynamicSetters.add(selector);
-  }
-
-  void registerInstantiatedType(InterfaceType type) {
-    // TODO(johnniwinther): Remove this when dependency tracking is done on
-    // the world impact itself.
-    worldImpact.registerDependency(type.element);
-    if (_instantiatedTypes == null) {
-      _instantiatedTypes = new Setlet<InterfaceType>();
-    }
-    _instantiatedTypes.add(type);
-  }
-
-  @override
-  Iterable<InterfaceType> get instantiatedTypes {
-    return _instantiatedTypes != null
-        ? _instantiatedTypes : const <InterfaceType>[];
-  }
-
-  @override
-  Iterable<DartType> get typeLiterals {
-    return worldImpact.typeLiterals;
-  }
-
-  void registerStaticUse(Element element) {
-    // TODO(johnniwinther): Remove this when dependency tracking is done on
-    // the world impact itself.
-    worldImpact.registerDependency(element);
-    if (_staticUses == null) {
-      _staticUses = new Setlet<Element>();
-    }
-    _staticUses.add(element);
-  }
-
-  @override
-  Iterable<LocalFunctionElement> get closures => worldImpact.closures;
-
-  String toString() {
-    StringBuffer sb = new StringBuffer();
-    sb.write('TransformedWorldImpact($worldImpact)');
-    sb.write(super.toString());
-    return sb.toString();
-  }
-}
-
 // TODO(johnniwinther): Rename to `Resolver` or `ResolverContext`.
 abstract class Resolution {
   Parsing get parsing;
@@ -328,4 +195,5 @@
   DiagnosticReporter get reporter;
   void parsePatchClass(ClassElement cls);
   measure(f());
+  ScannerOptions getScannerOptionsFor(Element element);
 }
\ No newline at end of file
diff --git a/pkg/compiler/lib/src/common/work.dart b/pkg/compiler/lib/src/common/work.dart
index 49f23c0..482d9e8 100644
--- a/pkg/compiler/lib/src/common/work.dart
+++ b/pkg/compiler/lib/src/common/work.dart
@@ -10,7 +10,8 @@
 import '../elements/elements.dart' show
     AstElement;
 import '../enqueue.dart' show
-    Enqueuer,
+    Enqueuer;
+import '../universe/world_impact.dart' show
     WorldImpact;
 
 
diff --git a/pkg/compiler/lib/src/compile_time_constants.dart b/pkg/compiler/lib/src/compile_time_constants.dart
index 99672db..d633e6b 100644
--- a/pkg/compiler/lib/src/compile_time_constants.dart
+++ b/pkg/compiler/lib/src/compile_time_constants.dart
@@ -16,11 +16,12 @@
 import 'constants/evaluation.dart';
 import 'constants/expressions.dart';
 import 'constants/values.dart';
+import 'core_types.dart' show
+    CoreTypes;
 import 'dart_types.dart';
 import 'elements/elements.dart';
 import 'elements/modelx.dart' show
     FunctionElementX;
-import 'helpers/helpers.dart';
 import 'resolution/tree_elements.dart' show
     TreeElements;
 import 'resolution/operators.dart';
@@ -161,6 +162,8 @@
 
   DiagnosticReporter get reporter => compiler.reporter;
 
+  CoreTypes get coreTypes => compiler.coreTypes;
+
   @override
   ConstantValue getConstantValueForVariable(VariableElement element) {
     return getConstantValue(initialVariableValues[element.declaration]);
@@ -256,7 +259,7 @@
             expression = null;
           }
         } else {
-          DartType constantType = value.getType(compiler.coreTypes);
+          DartType constantType = value.getType(coreTypes);
           if (!constantSystem.isSubtype(
               compiler.types, constantType, elementType)) {
             if (isConst) {
@@ -367,7 +370,7 @@
 
   ConstantSystem get constantSystem => handler.constantSystem;
   Resolution get resolution => compiler.resolution;
-
+  CoreTypes get coreTypes => compiler.coreTypes;
   DiagnosticReporter get reporter => compiler.reporter;
 
   AstConstant evaluate(Node node) {
@@ -505,7 +508,7 @@
       subexpressions.add(subexpression.expression);
       ConstantValue expression = subexpression.value;
       DartString expressionString;
-      if (expression.isNum || expression.isBool) {
+      if (expression.isNum || expression.isBool || expression.isNull) {
         PrimitiveConstantValue primitive = expression;
         expressionString =
             new DartString.literal(primitive.primitiveValue.toString());
@@ -532,7 +535,7 @@
   }
 
   AstConstant visitLiteralSymbol(LiteralSymbol node) {
-    InterfaceType type = compiler.symbolClass.rawType;
+    InterfaceType type = coreTypes.symbolType;
     String text = node.slowNameString;
     List<AstConstant> arguments = <AstConstant>[
       new AstConstant(context, node, new StringConstantExpression(text),
@@ -724,13 +727,13 @@
     if (condition == null) {
       return null;
     } else if (!condition.value.isBool) {
-      DartType conditionType = condition.value.getType(compiler.coreTypes);
+      DartType conditionType = condition.value.getType(coreTypes);
       if (isEvaluatingConstant) {
         reporter.reportErrorMessage(
             node.condition,
             MessageKind.NOT_ASSIGNABLE,
             {'fromType': conditionType,
-             'toType': compiler.boolClass.rawType});
+             'toType': coreTypes.boolType});
         return new ErroneousAstConstant(context, node);
       }
       return null;
@@ -823,19 +826,33 @@
     // The redirection chain of this element may not have been resolved through
     // a post-process action, so we have to make sure it is done here.
     compiler.resolver.resolveRedirectionChain(constructor, node);
-    InterfaceType constructedType =
-        constructor.computeEffectiveTargetType(type);
-    ConstructorElement target = constructor.effectiveTarget;
-    // The constructor must be an implementation to ensure that field
-    // initializers are handled correctly.
-    ConstructorElement implementation = target.implementation;
 
-    if (implementation.isErroneous) {
-      // TODO(johnniwinther): This should probably be an [ErroneousAstConstant].
-      return new AstConstant(context, node, new ConstructedConstantExpression(
-              type, constructor, callStructure, const <ConstantExpression>[]),
-          new ConstructedConstantValue(
-              constructedType, const <FieldElement, ConstantValue>{}));
+    bool isInvalid = false;
+    InterfaceType constructedType = type;
+    ConstructorElement implementation;
+    if (constructor.isRedirectingFactory) {
+      if (constructor.isEffectiveTargetMalformed) {
+        isInvalid = true;
+      } else {
+        constructedType =
+            constructor.computeEffectiveTargetType(type);
+        ConstructorElement target = constructor.effectiveTarget;
+        // The constructor must be an implementation to ensure that field
+        // initializers are handled correctly.
+        implementation = target.implementation;
+      }
+    } else {
+      // The constructor must be an implementation to ensure that field
+      // initializers are handled correctly.
+      implementation = constructor.implementation;
+      isInvalid = implementation.isMalformed;
+      if (implementation.isGenerativeConstructor &&
+          constructor.enclosingClass.isAbstract) {
+        isInvalid = true;
+      }
+    }
+    if (isInvalid) {
+      return signalNotCompileTimeConstant(node);
     }
 
     List<AstConstant> concreteArguments;
@@ -885,45 +902,45 @@
     }
 
     if (!firstArgument.isString) {
-      DartType type = defaultValue.getType(compiler.coreTypes);
+      DartType type = defaultValue.getType(coreTypes);
       reporter.reportErrorMessage(
           normalizedArguments[0].node,
           MessageKind.NOT_ASSIGNABLE,
           {'fromType': type,
-           'toType': compiler.stringClass.rawType});
+           'toType': coreTypes.stringType});
       return null;
     }
 
     if (constructor == compiler.intEnvironment &&
         !(defaultValue.isNull || defaultValue.isInt)) {
-      DartType type = defaultValue.getType(compiler.coreTypes);
+      DartType type = defaultValue.getType(coreTypes);
       reporter.reportErrorMessage(
           normalizedArguments[1].node,
           MessageKind.NOT_ASSIGNABLE,
           {'fromType': type,
-           'toType': compiler.intClass.rawType});
+           'toType': coreTypes.intType});
       return null;
     }
 
     if (constructor == compiler.boolEnvironment &&
         !(defaultValue.isNull || defaultValue.isBool)) {
-      DartType type = defaultValue.getType(compiler.coreTypes);
+      DartType type = defaultValue.getType(coreTypes);
       reporter.reportErrorMessage(
           normalizedArguments[1].node,
           MessageKind.NOT_ASSIGNABLE,
           {'fromType': type,
-           'toType': compiler.boolClass.rawType});
+           'toType': coreTypes.boolType});
       return null;
     }
 
     if (constructor == compiler.stringEnvironment &&
         !(defaultValue.isNull || defaultValue.isString)) {
-      DartType type = defaultValue.getType(compiler.coreTypes);
+      DartType type = defaultValue.getType(coreTypes);
       reporter.reportErrorMessage(
           normalizedArguments[1].node,
           MessageKind.NOT_ASSIGNABLE,
           {'fromType': type,
-           'toType': compiler.stringClass.rawType});
+           'toType': coreTypes.stringType});
       return null;
     }
 
@@ -1064,7 +1081,7 @@
   void potentiallyCheckType(TypedElement element, AstConstant constant) {
     if (compiler.enableTypeAssertions) {
       DartType elementType = element.type.substByContext(constructedType);
-      DartType constantType = constant.value.getType(compiler.coreTypes);
+      DartType constantType = constant.value.getType(coreTypes);
       if (!constantSystem.isSubtype(
           compiler.types, constantType, elementType)) {
         reporter.withCurrentElement(constant.element, () {
@@ -1089,7 +1106,7 @@
    * parameters (like [:this.x:]), also updates the [fieldValues] map.
    */
   void assignArgumentsToParameters(List<AstConstant> arguments) {
-    if (constructor.isErroneous) return;
+    if (constructor.isMalformed) return;
     // Assign arguments to parameters.
     FunctionSignature signature = constructor.functionSignature;
     int index = 0;
@@ -1148,10 +1165,16 @@
           // A super initializer or constructor redirection.
           Send call = link.head;
           FunctionElement target = elements[call];
-          List<AstConstant> compiledArguments = evaluateArgumentsToConstructor(
-              call, elements.getSelector(call).callStructure, call.arguments,
-              target, compileArgument: evaluateConstant);
-          evaluateSuperOrRedirectSend(compiledArguments, target);
+          if (!target.isMalformed) {
+            List<AstConstant> compiledArguments =
+                evaluateArgumentsToConstructor(
+                  call,
+                  elements.getSelector(call).callStructure,
+                  call.arguments,
+                  target,
+                  compileArgument: evaluateConstant);
+            evaluateSuperOrRedirectSend(compiledArguments, target);
+          }
           foundSuperOrRedirect = true;
         } else {
           // A field initializer.
@@ -1169,7 +1192,7 @@
       // the class is not Object.
       ClassElement enclosingClass = constructor.enclosingClass;
       ClassElement superClass = enclosingClass.superclass;
-      if (enclosingClass != compiler.objectClass) {
+      if (!enclosingClass.isObject) {
         assert(superClass != null);
         assert(superClass.isResolved);
 
@@ -1193,7 +1216,7 @@
    * native JavaScript constructor.
    */
   void evaluateConstructorFieldValues(List<AstConstant> arguments) {
-    if (constructor.isErroneous) return;
+    if (constructor.isMalformed) return;
     reporter.withCurrentElement(constructor, () {
       assignArgumentsToParameters(arguments);
       evaluateConstructorInitializers();
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 8fab748..392b202 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -17,12 +17,13 @@
 import 'common/backend_api.dart' show
     Backend;
 import 'common/codegen.dart' show
-    CodegenRegistry,
+    CodegenImpact,
     CodegenWorkItem;
 import 'common/names.dart' show
     Identifiers,
     Uris;
 import 'common/registry.dart' show
+    EagerRegistry,
     Registry;
 import 'common/resolution.dart' show
     Parsing,
@@ -37,6 +38,7 @@
 import 'compile_time_constants.dart';
 import 'constants/values.dart';
 import 'core_types.dart' show
+    CoreClasses,
     CoreTypes;
 import 'dart_backend/dart_backend.dart' as dart_backend;
 import 'dart_types.dart' show
@@ -69,10 +71,11 @@
     Enqueuer,
     EnqueueTask,
     ResolutionEnqueuer,
-    QueueFilter,
-    WorldImpact;
+    QueueFilter;
 import 'io/source_information.dart' show
     SourceInformation;
+import 'js_backend/backend_helpers.dart' as js_backend show
+    BackendHelpers;
 import 'js_backend/js_backend.dart' as js_backend show
     JavaScriptBackend;
 import 'library_loader.dart' show
@@ -81,11 +84,15 @@
     LoadedLibraries;
 import 'mirrors_used.dart' show
     MirrorUsageAnalyzerTask;
+import 'common/names.dart' show
+    Selectors;
 import 'null_compiler_output.dart' show
     NullCompilerOutput,
     NullSink;
 import 'parser/diet_parser_task.dart' show
     DietParserTask;
+import 'parser/element_listener.dart' show
+    ScannerOptions;
 import 'parser/parser_task.dart' show
     ParserTask;
 import 'patch_parser.dart' show
@@ -127,6 +134,10 @@
     Selector;
 import 'universe/universe.dart' show
     Universe;
+import 'universe/use.dart' show
+    StaticUse;
+import 'universe/world_impact.dart' show
+    WorldImpact;
 import 'util/util.dart' show
     Link,
     Setlet;
@@ -277,25 +288,8 @@
   /// Initialized when dart:typed_data is loaded.
   LibraryElement typedDataLibrary;
 
-  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 resourceClass => _coreTypes.resourceClass;
-  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;
-
   DiagnosticReporter get reporter => _reporter;
+  CoreClasses get coreClasses => _coreTypes;
   CoreTypes get coreTypes => _coreTypes;
   Resolution get resolution => _resolution;
   Parsing get parsing => _parsing;
@@ -552,10 +546,14 @@
     reporter.internalError(spannable, "$methodName not implemented.");
   }
 
+  // Compiles the dart script at [uri].
+  //
+  // The resulting future will complete with true if the compilation
+  // succeded.
   Future<bool> run(Uri uri) {
     totalCompileTime.start();
 
-    return new Future.sync(() => runCompiler(uri))
+    return new Future.sync(() => runInternal(uri))
         .catchError((error) => _reporter.onError(uri, error))
         .whenComplete(() {
       tracer.close();
@@ -609,7 +607,7 @@
       _coreTypes.streamClass = findRequiredElement(library, 'Stream');
     } else if (uri == Uris.dart__native_typed_data) {
       typedDataClass = findRequiredElement(library, 'NativeTypedData');
-    } else if (uri == js_backend.JavaScriptBackend.DART_JS_HELPER) {
+    } else if (uri == js_backend.BackendHelpers.DART_JS_HELPER) {
       patchAnnotationClass = findRequiredElement(library, '_Patch');
       nativeAnnotationClass = findRequiredElement(library, 'Native');
     }
@@ -695,7 +693,7 @@
       for (Uri uri in disallowedLibraryUris) {
         if (loadedLibraries.containsLibrary(uri)) {
           Set<String> importChains =
-              computeImportChainsFor(loadedLibraries, Uri.parse('dart:io'));
+              computeImportChainsFor(loadedLibraries, uri);
           reporter.reportInfo(NO_LOCATION_SPANNABLE,
              MessageKind.DISALLOWED_LIBRARY_IMPORT,
               {'uri': uri,
@@ -728,8 +726,9 @@
                  MessageTemplate.IMPORT_EXPERIMENTAL_MIRRORS_PADDING)});
       }
 
-      functionClass.ensureResolved(resolution);
-      functionApplyMethod = functionClass.lookupLocalMember('apply');
+      coreClasses.functionClass.ensureResolved(resolution);
+      functionApplyMethod =
+          coreClasses.functionClass.lookupLocalMember('apply');
 
       if (preserveComments) {
         return libraryLoader.loadLibrary(Uris.dart_mirrors)
@@ -768,23 +767,20 @@
 
   void onClassResolved(ClassElement cls) {
     if (mirrorSystemClass == cls) {
-      mirrorSystemGetNameFunction =
-        cls.lookupLocalMember('getName');
-    } else if (symbolClass == cls) {
+      mirrorSystemGetNameFunction = cls.lookupLocalMember('getName');
+    } else if (coreClasses.symbolClass == cls) {
       symbolConstructor = cls.constructors.head;
     } else if (symbolImplementationClass == cls) {
-      symbolValidatedConstructor = symbolImplementationClass.lookupConstructor(
+      symbolValidatedConstructor = cls.lookupConstructor(
           symbolValidatedConstructorSelector.name);
     } else if (mirrorsUsedClass == cls) {
       mirrorsUsedConstructor = cls.constructors.head;
-    } else if (intClass == cls) {
-      intEnvironment = intClass.lookupConstructor(Identifiers.fromEnvironment);
-    } else if (stringClass == cls) {
-      stringEnvironment =
-          stringClass.lookupConstructor(Identifiers.fromEnvironment);
-    } else if (boolClass == cls) {
-      boolEnvironment =
-          boolClass.lookupConstructor(Identifiers.fromEnvironment);
+    } else if (coreClasses.intClass == cls) {
+      intEnvironment = cls.lookupConstructor(Identifiers.fromEnvironment);
+    } else if (coreClasses.stringClass == cls) {
+      stringEnvironment = cls.lookupConstructor(Identifiers.fromEnvironment);
+    } else if (coreClasses.boolClass == cls) {
+      boolEnvironment = cls.lookupConstructor(Identifiers.fromEnvironment);
     }
   }
 
@@ -823,13 +819,15 @@
   Element _unnamedListConstructor;
   Element get unnamedListConstructor {
     if (_unnamedListConstructor != null) return _unnamedListConstructor;
-    return _unnamedListConstructor = listClass.lookupDefaultConstructor();
+    return _unnamedListConstructor =
+        coreClasses.listClass.lookupDefaultConstructor();
   }
 
   Element _filledListConstructor;
   Element get filledListConstructor {
     if (_filledListConstructor != null) return _filledListConstructor;
-    return _filledListConstructor = listClass.lookupConstructor("filled");
+    return _filledListConstructor =
+        coreClasses.listClass.lookupConstructor("filled");
   }
 
   /**
@@ -838,7 +836,7 @@
    */
   Uri resolvePatchUri(String dartLibraryPath);
 
-  Future runCompiler(Uri uri) {
+  Future runInternal(Uri uri) {
     // TODO(ahe): This prevents memory leaks when invoking the compiler
     // multiple times. Implement a better mechanism where we can store
     // such caches in the compiler and get access to them through a
@@ -846,6 +844,13 @@
     StringToken.canonicalizedSubstrings.clear();
     Selector.canonicalizedValues.clear();
 
+    // The selector objects held in static fields must remain canonical.
+    for (Selector selector in Selectors.ALL) {
+      Selector.canonicalizedValues
+        .putIfAbsent(selector.hashCode, () => <Selector>[])
+        .add(selector);
+    }
+
     assert(uri != null || analyzeOnly || hasIncrementalSupport);
     return new Future.sync(() {
       if (librariesToAnalyzeWhenRun != null) {
@@ -889,7 +894,7 @@
             Identifiers.main, mainApp);
       }
       mainFunction = backend.helperForMissingMain();
-    } else if (main.isErroneous && main.isSynthesized) {
+    } else if (main.isError && main.isSynthesized) {
       if (main is ErroneousElement) {
         errorElement = main;
       } else {
@@ -915,7 +920,7 @@
               parameter);
           mainFunction = backend.helperForMainArity();
           // Don't warn about main not being used:
-          enqueuer.resolution.registerStaticUse(main);
+          enqueuer.resolution.registerStaticUse(new StaticUse.foreignUse(main));
         });
       }
     }
@@ -935,7 +940,7 @@
     }
   }
 
-  /// Analyze all member of the library in [libraryUri].
+  /// Analyze all members of the library in [libraryUri].
   ///
   /// If [skipLibraryWithPartOfTag] is `true`, member analysis is skipped if the
   /// library has a `part of` tag, assuming it is a part and not a library.
@@ -1104,7 +1109,7 @@
 
   void processQueue(Enqueuer world, Element main) {
     world.nativeEnqueuer.processNativeClasses(libraryLoader.libraries);
-    if (main != null && !main.isErroneous) {
+    if (main != null && !main.isMalformed) {
       FunctionElement mainMethod = main;
       mainMethod.computeType(resolution);
       if (mainMethod.functionSignature.parameterCount != 0) {
@@ -1174,7 +1179,7 @@
            element.impliesType ||
            element.isField ||
            element.isFunction ||
-           element.isGenerativeConstructor ||
+           element.isConstructor ||
            element.isGetter ||
            element.isSetter,
            message: 'Unexpected element kind: ${element.kind}'));
@@ -1299,7 +1304,7 @@
 
   void reportUnusedCode() {
     void checkLive(member) {
-      if (member.isErroneous) return;
+      if (member.isMalformed) return;
       if (member.isFunction) {
         if (!enqueuer.resolution.hasBeenProcessed(member)) {
           reporter.reportHintMessage(
@@ -1437,7 +1442,7 @@
   int hints = 0;
 }
 
-class _CompilerCoreTypes implements CoreTypes {
+class _CompilerCoreTypes implements CoreTypes, CoreClasses {
   final Resolution resolution;
 
   ClassElement objectClass;
@@ -1552,6 +1557,12 @@
   }
 
   @override
+  InterfaceType get stackTraceType {
+    stackTraceClass.ensureResolved(resolution);
+    return stackTraceClass.rawType;
+  }
+
+  @override
   InterfaceType iterableType([DartType elementType]) {
     iterableClass.ensureResolved(resolution);
     InterfaceType type = iterableClass.rawType;
@@ -1674,6 +1685,12 @@
   void reportDiagnostic(DiagnosticMessage message,
                         List<DiagnosticMessage> infos,
                         api.Diagnostic kind) {
+    if (kind == api.Diagnostic.ERROR ||
+        kind == api.Diagnostic.CRASH ||
+        (options.fatalWarnings &&
+         kind == api.Diagnostic.WARNING)) {
+      compiler.compilationFailed = true;
+    }
     compiler.reportDiagnostic(message, infos, kind);
   }
 
@@ -1995,7 +2012,7 @@
         compiler.checker.check(element);
       }
       WorldImpact worldImpact =
-          compiler.backend.resolutionCallbacks.transformImpact(
+          compiler.backend.impactTransformer.transformResolutionImpact(
               resolutionImpact);
       return worldImpact;
     });
@@ -2028,13 +2045,23 @@
       }
     });
   }
+
+  ScannerOptions getScannerOptionsFor(Element element) {
+    return new ScannerOptions(
+      canUseNative: compiler.backend.canLibraryUseNative(element.library));
+  }
 }
 
-class GlobalDependencyRegistry extends CodegenRegistry {
+class GlobalDependencyRegistry extends EagerRegistry {
+  final Compiler compiler;
   Setlet<Element> _otherDependencies;
 
-  GlobalDependencyRegistry(Compiler compiler)
-      : super(compiler, new TreeElementMapping(null));
+  GlobalDependencyRegistry(this.compiler) : super('GlobalDependencies', null);
+
+  // TODO(johnniwinther): Rename world/universe/enqueuer through out the
+  // compiler.
+  @override
+  Enqueuer get world => compiler.enqueuer.codegen;
 
   void registerDependency(Element element) {
     if (element == null) return;
@@ -2047,4 +2074,4 @@
   Iterable<Element> get otherDependencies {
     return _otherDependencies != null ? _otherDependencies : const <Element>[];
   }
-}
\ No newline at end of file
+}
diff --git a/pkg/compiler/lib/src/core_types.dart b/pkg/compiler/lib/src/core_types.dart
index 1b71c2e..ff30de2 100644
--- a/pkg/compiler/lib/src/core_types.dart
+++ b/pkg/compiler/lib/src/core_types.dart
@@ -7,6 +7,60 @@
 import 'dart_types.dart';
 import 'elements/elements.dart' show ClassElement;
 
+/// The core classes in Dart.
+abstract class CoreClasses {
+  /// The `Object` class defined in 'dart:core'.
+  ClassElement get objectClass;
+
+  /// The `bool` class defined in 'dart:core'.
+  ClassElement get boolClass;
+
+  /// The `num` class defined in 'dart:core'.
+  ClassElement get numClass;
+
+  /// The `int` class defined in 'dart:core'.
+  ClassElement get intClass;
+
+  /// The `double` class defined in 'dart:core'.
+  ClassElement get doubleClass;
+
+  /// The `Resource` class defined in 'dart:core'.
+  ClassElement get resourceClass;
+
+  /// The `String` class defined in 'dart:core'.
+  ClassElement get stringClass;
+
+  /// The `Symbol` class defined in 'dart:core'.
+  ClassElement get symbolClass;
+
+  /// The `Function` class defined in 'dart:core'.
+  ClassElement get functionClass;
+
+  /// The `Null` class defined in 'dart:core'.
+  ClassElement get nullClass;
+
+  /// The `Type` class defined in 'dart:core'.
+  ClassElement get typeClass;
+
+  /// The `StackTrace` class defined in 'dart:core';
+  ClassElement get stackTraceClass;
+
+  /// The `List` class defined in 'dart:core';
+  ClassElement get listClass;
+
+  /// The `Map` class defined in 'dart:core';
+  ClassElement get mapClass;
+
+  /// The `Iterable` class defined in 'dart:core';
+  ClassElement get iterableClass;
+
+  /// The `Future` class defined in 'async';
+  ClassElement get futureClass;
+
+  /// The `Stream` class defined in 'async';
+  ClassElement get streamClass;
+}
+
 /// The core types in Dart.
 abstract class CoreTypes {
   /// The `Object` type defined in 'dart:core'.
@@ -42,6 +96,9 @@
   /// The `Type` type defined in 'dart:core'.
   InterfaceType get typeType;
 
+  /// The `StackTrace` type defined in 'dart:core';
+  InterfaceType get stackTraceType;
+
   /// Returns an instance of the `List` type defined in 'dart:core' with
   /// [elementType] as its type argument.
   ///
diff --git a/pkg/compiler/lib/src/cps_ir/bounds_checker.dart b/pkg/compiler/lib/src/cps_ir/bounds_checker.dart
index 1467745..28dbd62 100644
--- a/pkg/compiler/lib/src/cps_ir/bounds_checker.dart
+++ b/pkg/compiler/lib/src/cps_ir/bounds_checker.dart
@@ -12,6 +12,9 @@
 import 'type_mask_system.dart';
 import '../world.dart';
 import '../elements/elements.dart';
+import 'loop_effects.dart';
+
+
 
 /// Eliminates bounds checks when they can be proven safe.
 ///
@@ -30,7 +33,6 @@
 ///
 /// Loops are analyzed in two passes. The first pass establishes monotonicity
 /// of loop variables, which the second pass uses to compute upper/lower bounds.
-/// The first pass also records whether any side effects occurred in the loop.
 ///
 /// The two-pass scheme is suboptimal compared to a least fixed-point
 /// computation, but does not require repeated iteration.  Repeated iteration
@@ -56,7 +58,6 @@
   final Map<Primitive, Map<int, SignedVariable>> lengthOf = {};
 
   /// Fields for the two-pass handling of loops.
-  final Set<Continuation> loopsWithSideEffects = new Set<Continuation>();
   final Map<Parameter, Monotonicity> monotonicity = <Parameter, Monotonicity>{};
   bool isStrongLoopPass;
   bool foundLoop = false;
@@ -65,6 +66,7 @@
   ///
   /// The IR is divided into regions wherein the lengths of indexable objects
   /// are known not to change. Regions are identified by their "effect number".
+  LoopSideEffects loopEffects;
   final Map<Continuation, int> effectNumberAt = <Continuation, int>{};
   int currentEffectNumber = 0;
   int effectNumberCounter = 0;
@@ -72,6 +74,7 @@
   BoundsChecker(this.types, this.world);
 
   void rewrite(FunctionDefinition node) {
+    loopEffects = new LoopSideEffects(node, world);
     isStrongLoopPass = false;
     visit(node);
     if (foundLoop) {
@@ -402,12 +405,8 @@
           makeLessThanOrEqual(getValue(param), initialVariable);
         }
       }
-      if (loopsWithSideEffects.contains(cont)) {
-        currentEffectNumber = makeNewEffect();
-      }
-    } else {
-      // During the weak pass, conservatively make a new effect number in the
-      // loop body. This may be strengthened during the strong pass.
+    }
+    if (loopEffects.loopChangesLength(cont)) {
       currentEffectNumber = effectNumberAt[cont] = makeNewEffect();
     }
     push(cont);
@@ -440,12 +439,6 @@
         markMonotonicity(cont.parameters[i], Monotonicity.Decreasing);
       }
     }
-
-    // If a side effect has occurred between the entry and continue, mark
-    // the loop as having side effects.
-    if (currentEffectNumber != effectNumberAt[cont]) {
-      loopsWithSideEffects.add(cont);
-    }
   }
 
   void markMonotonicity(Parameter param, Monotonicity mono) {
diff --git a/pkg/compiler/lib/src/cps_ir/builtin_operator.dart b/pkg/compiler/lib/src/cps_ir/builtin_operator.dart
index 31f815a..9c1d83e 100644
--- a/pkg/compiler/lib/src/cps_ir/builtin_operator.dart
+++ b/pkg/compiler/lib/src/cps_ir/builtin_operator.dart
@@ -55,6 +55,14 @@
   /// This case can be compiled to  `(a / b) | 0`.
   NumTruncatingDivideToSigned32,
 
+  /// Corresponds to JavaScript's negation, which converts 0 to -0.0.
+  NumNegate,
+
+  /// Bit inversions, with coercion to uint32.
+  ///
+  /// Compiles to `(~x) >>> 0`.
+  NumBitNot,
+
   /// Concatenates any number of strings.
   ///
   /// Takes any number of arguments, and each argument must be a string.
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 3f69cd0..b9f26d2 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
@@ -34,7 +34,6 @@
     SelectorKind;
 
 import 'cps_ir_builder_task.dart' show
-    DartCapturedVariables,
     GlobalProgramInformation;
 import 'cps_ir_nodes.dart' as ir;
 
@@ -160,6 +159,13 @@
     if (hasExtraArgument) _continuationEnvironment.extend(null, null);
   }
 
+  /// Construct a collector for collecting only return jumps.
+  ///
+  /// There is no jump target, it is implicitly the exit from the function.
+  /// There is no environment at the destination.
+  JumpCollector.retrn(this._continuation)
+      : _continuationEnvironment = null, target = null;
+
   /// True if the collector has not recorded any jumps to its continuation.
   bool get isEmpty;
 
@@ -176,7 +182,8 @@
   /// values to finally blocks for returns inside try/finally and to pass
   /// values of expressions that have internal control flow to their join-point
   /// continuations.
-  void addJump(IrBuilder builder, [ir.Primitive value]);
+  void addJump(IrBuilder builder,
+      [ir.Primitive value, SourceInformation sourceInformation]);
 
   /// Add a set of variables that were boxed on entry to a try block.
   ///
@@ -260,7 +267,8 @@
     return _continuationEnvironment;
   }
 
-  void addJump(IrBuilder builder, [ir.Primitive value]) {
+  void addJump(IrBuilder builder,
+      [ir.Primitive value, SourceInformation sourceInformation]) {
     assert(_continuation == null);
     _buildTryExit(builder);
     ir.InvokeContinuation invoke = new ir.InvokeContinuation.uninitialized(
@@ -369,7 +377,8 @@
   ir.Continuation get continuation => _continuation;
   Environment get environment => _continuationEnvironment;
 
-  void addJump(IrBuilder builder, [ir.Primitive value]) {
+  void addJump(IrBuilder builder,
+      [ir.Primitive value, SourceInformation sourceInformation]) {
     assert(_continuation.parameters.length <= builder.environment.length);
     isEmpty = false;
     _buildTryExit(builder);
@@ -389,6 +398,29 @@
   }
 }
 
+/// Collect 'return' jumps.
+///
+/// A return jump is one that targets the return continuation of a function.
+/// Thus, returns from inside try/finally are not return jumps because they are
+/// intercepted by a block that contains the finally handler code.
+class ReturnJumpCollector extends JumpCollector {
+  bool isEmpty = true;
+  ir.Continuation get continuation => _continuation;
+  Environment environment = null;
+
+  /// Construct a return jump collector for a given return continuation.
+  ReturnJumpCollector(ir.Continuation continuation) : super.retrn(continuation);
+
+  void addJump(IrBuilder builder,
+      [ir.Primitive value, SourceInformation sourceInformation]) {
+    isEmpty = false;
+    builder.add(new ir.InvokeContinuation(continuation, <ir.Primitive>[value],
+        isEscapingTry: isEscapingTry,
+        sourceInformation: sourceInformation));
+    builder._current = null;
+  }
+}
+
 /// Function for building a node in the context of the current builder.
 typedef ir.Node BuildFunction(node);
 
@@ -467,7 +499,7 @@
   /// A null value indicates that the target is the function's return
   /// continuation.  Otherwise, when inside the try block of try/finally
   /// a return is intercepted to give a place to generate the finally code.
-  JumpCollector returnCollector = null;
+  JumpCollector returnCollector;
 
   /// Parameter holding the internal value of 'this' passed to the function.
   ///
@@ -484,7 +516,9 @@
   /// the environment.
   final Map<Local, ClosureLocation> boxedVariables = {};
 
-  IrBuilderSharedState(this.program, this.constants, this.currentElement);
+  IrBuilderSharedState(this.program, this.constants, this.currentElement) {
+    returnCollector = new ReturnJumpCollector(returnContinuation);
+  }
 }
 
 class ThisParameterLocal implements Local {
@@ -714,9 +748,11 @@
   /// Creates a non-constant list literal of the provided [type] and with the
   /// provided [values].
   ir.Primitive buildListLiteral(InterfaceType type,
-                                Iterable<ir.Primitive> values) {
+                                Iterable<ir.Primitive> values,
+                                {TypeMask allocationSiteType}) {
     assert(isOpen);
-    return addPrimitive(new ir.LiteralList(type, values.toList()));
+    return addPrimitive(new ir.LiteralList(type, values.toList(),
+        allocationSiteType: allocationSiteType));
   }
 
   /// Creates a non-constant map literal of the provided [type] and with the
@@ -1161,8 +1197,9 @@
     }
   }
 
-  void jumpTo(JumpCollector collector, [ir.Primitive value]) {
-    collector.addJump(this, value);
+  void jumpTo(JumpCollector collector,
+      [ir.Primitive value, SourceInformation sourceInformation]) {
+    collector.addJump(this, value, sourceInformation);
   }
 
   void addRecursiveContinuation(BackwardJumpCollector collector) {
@@ -1408,7 +1445,7 @@
     // TODO(johnniwinther): Extract this as a provided strategy.
     if (Elements.isLocal(variableElement)) {
       bodyBuilder.buildLocalVariableSet(variableElement, currentValue);
-    } else if (Elements.isErroneous(variableElement)) {
+    } else if (Elements.isMalformed(variableElement)) {
       bodyBuilder.buildErroneousInvocation(variableElement,
           new Selector.setter(
               new Name(variableElement.name, variableElement.library)),
@@ -1812,6 +1849,7 @@
       }
       builder.state.breakCollectors.forEach(interceptJump);
       builder.state.continueCollectors.forEach(interceptJump);
+      interceptJump(builder.state.returnCollector);
     }
 
     void leaveTry(IrBuilder builder) {
@@ -1822,6 +1860,7 @@
       }
       builder.state.breakCollectors.forEach(restoreJump);
       builder.state.continueCollectors.forEach(restoreJump);
+      restoreJump(builder.state.returnCollector);
     }
 
     List<ir.Parameter> buildCatch(IrBuilder builder,
@@ -2030,16 +2069,7 @@
     if (value == null) {
       value = buildNullConstant();
     }
-    if (state.returnCollector == null) {
-      add(new ir.InvokeContinuation(state.returnContinuation, [value],
-              sourceInformation: sourceInformation));
-      _current = null;
-    } else {
-      // Inside the try block of try/finally, all returns go to a join-point
-      // continuation that contains the finally code.  The return value is
-      // passed as an extra argument.
-      jumpTo(state.returnCollector, value);
-    }
+    jumpTo(state.returnCollector, value, sourceInformation);
   }
 
   /// Build a call to the closure conversion helper for the [Function] typed
@@ -2073,8 +2103,8 @@
   /// `fixedBackendName`, passing all parameters as arguments.  The target can
   /// be the JavaScript implementation of a function, getter, or setter.
   void buildRedirectingNativeFunctionBody(FunctionElement function,
+                                          String name,
                                           SourceInformation source) {
-    String name = function.fixedBackendName;
     List<ir.Primitive> arguments = <ir.Primitive>[];
     NativeBehavior behavior = new NativeBehavior();
     behavior.sideEffects.setAllSideEffects();
@@ -2607,7 +2637,8 @@
       CallStructure callStructure,
       DartType type,
       List<ir.Primitive> arguments,
-      SourceInformation sourceInformation) {
+      SourceInformation sourceInformation,
+      {TypeMask allocationSiteType}) {
     assert(isOpen);
     Selector selector =
         new Selector(SelectorKind.CALL, element.memberName, callStructure);
@@ -2625,7 +2656,8 @@
     }
     return _continueWithExpression(
         (k) => new ir.InvokeConstructor(
-            type, element, selector, arguments, k, sourceInformation));
+            type, element, selector, arguments, k, sourceInformation,
+            allocationSiteType: allocationSiteType));
   }
 
   ir.Primitive buildTypeExpression(DartType type) {
@@ -2813,6 +2845,10 @@
       return new ir.Yield(value, hasStar, k);
     });
   }
+
+  ir.Primitive buildRefinement(ir.Primitive value, TypeMask type) {
+    return addPrimitive(new ir.Refinement(value, type));
+  }
 }
 
 /// Location of a variable relative to a given closure.
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
index 9f2ad07..c960bcb 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
@@ -22,14 +22,14 @@
     ConstructorBodyElementX,
     FunctionSignatureX;
 import '../io/source_information.dart';
+import '../js_backend/backend_helpers.dart' show
+    BackendHelpers;
 import '../js_backend/js_backend.dart' show
     JavaScriptBackend,
     SyntheticConstantKind;
 import '../resolution/tree_elements.dart' show
     TreeElements;
 import '../resolution/semantic_visitor.dart';
-import '../resolution/send_resolver.dart' show
-    SendResolverMixin;
 import '../resolution/operators.dart' as op;
 import '../tree/tree.dart' as ast;
 import '../types/types.dart' show
@@ -53,6 +53,8 @@
 import 'package:js_runtime/shared/embedded_names.dart'
     show JsBuiltin, JsGetName;
 import '../constants/values.dart';
+import 'type_mask_system.dart' show
+    TypeMaskSystem;
 
 typedef void IrBuilderCallback(Element element, ir.FunctionDefinition irNode);
 
@@ -76,7 +78,8 @@
 
   String get name => 'CPS builder';
 
-  ir.FunctionDefinition buildNode(AstElement element) {
+  ir.FunctionDefinition buildNode(AstElement element,
+                                  TypeMaskSystem typeMaskSystem) {
     return measure(() {
       bailoutMessage = null;
 
@@ -88,7 +91,8 @@
 
         IrBuilderVisitor builder =
             new JsIrBuilderVisitor(
-                elementsMapping, compiler, sourceInformationBuilder);
+                elementsMapping, compiler, sourceInformationBuilder,
+                typeMaskSystem);
         ir.FunctionDefinition irNode = builder.buildExecutable(element);
         if (irNode == null) {
           bailoutMessage = builder.bailoutMessage;
@@ -113,7 +117,6 @@
 abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
     with IrBuilderMixin<ast.Node>,
          SemanticSendResolvedMixin<ir.Primitive, dynamic>,
-         SendResolverMixin,
          ErrorBulkMixin<ir.Primitive, dynamic>,
          BaseImplementationOfStaticsMixin<ir.Primitive, dynamic>,
          BaseImplementationOfLocalsMixin<ir.Primitive, dynamic>,
@@ -127,6 +130,7 @@
   final TreeElements elements;
   final Compiler compiler;
   final SourceInformationBuilder sourceInformationBuilder;
+  final TypeMaskSystem typeMaskSystem;
 
   /// A map from try statements in the source to analysis information about
   /// them.
@@ -157,7 +161,8 @@
   /// Construct a top-level visitor.
   IrBuilderVisitor(this.elements,
                    this.compiler,
-                   this.sourceInformationBuilder);
+                   this.sourceInformationBuilder,
+                   this.typeMaskSystem);
 
   DiagnosticReporter get reporter => compiler.reporter;
 
@@ -227,6 +232,16 @@
     return irBuilder.makeFunctionDefinition();
   }
 
+  /// Returns the allocation site-specific type for a given allocation.
+  ///
+  /// Currently, it is an error to call this with anything that is not the
+  /// allocation site for a List object (a literal list or a call to one
+  /// of the List constructors).
+  TypeMask getAllocationSiteType(ast.Node node) {
+    return compiler.typesTask.getGuaranteedTypeOfNode(
+        elements.analyzedElement, node);
+  }
+
   ir.Primitive visit(ast.Node node) => node.accept(this);
 
   // ## Statements ##
@@ -409,6 +424,21 @@
         closureScope: getClosureScopeForNode(node));
   }
 
+  /// If compiling with trusted type annotations, assumes that [value] is
+  /// now known to be `null` or an instance of [type].
+  ///
+  /// This is also where we should add type checks in checked mode, but this
+  /// is not supported yet.
+  ir.Primitive checkType(ir.Primitive value, DartType dartType) {
+    if (!compiler.trustTypeAnnotations) return value;
+    TypeMask type = typeMaskSystem.subtypesOf(dartType).nullable();
+    return irBuilder.buildRefinement(value, type);
+  }
+
+  ir.Primitive checkTypeVsElement(ir.Primitive value, TypedElement element) {
+    return checkType(value, element.type);
+  }
+
   ir.Primitive visitVariableDefinitions(ast.VariableDefinitions node) {
     assert(irBuilder.isOpen);
     for (ast.Node definition in node.definitions.nodes) {
@@ -420,6 +450,7 @@
         assert(!definition.arguments.isEmpty);
         assert(definition.arguments.tail.isEmpty);
         initialValue = visit(definition.arguments.head);
+        initialValue = checkTypeVsElement(initialValue, element);
       } else {
         assert(definition is ast.Identifier);
       }
@@ -440,7 +471,7 @@
     SourceInformation source = sourceInformationBuilder.buildReturn(node);
     if (node.beginToken.value == 'native') {
       FunctionElement function = irBuilder.state.currentElement;
-      assert(function.isNative);
+      assert(compiler.backend.isNative(function));
       ast.Node nativeBody = node.expression;
       if (nativeBody != null) {
         ast.LiteralString jsCode = nativeBody.asLiteralString();
@@ -454,7 +485,9 @@
               'functions with zero parameters.'));
         irBuilder.buildNativeFunctionBody(function, javaScriptCode);
       } else {
-        irBuilder.buildRedirectingNativeFunctionBody(function, source);
+        JavaScriptBackend backend = compiler.backend;
+        String name = backend.getFixedBackendName(function);
+        irBuilder.buildRedirectingNativeFunctionBody(function, name, source);
       }
     } else {
       irBuilder.buildReturn(
@@ -608,7 +641,8 @@
     }
     List<ir.Primitive> values = node.elements.nodes.mapToList(visit);
     InterfaceType type = elements.getType(node);
-    return irBuilder.buildListLiteral(type, values);
+    return irBuilder.buildListLiteral(type, values,
+        allocationSiteType: getAllocationSiteType(node));
   }
 
   ir.Primitive visitLiteralMap(ast.LiteralMap node) {
@@ -1402,7 +1436,9 @@
       LocalElement element,
       ast.Node rhs,
       _) {
-    return irBuilder.buildLocalVariableSet(element, visit(rhs));
+    ir.Primitive value = visit(rhs);
+    value = checkTypeVsElement(value, element);
+    return irBuilder.buildLocalVariableSet(element, value);
   }
 
   @override
@@ -2275,16 +2311,11 @@
 
 final String ABORT_IRNODE_BUILDER = "IrNode builder aborted";
 
-/// Classifies local variables and local functions as captured, if they
-/// are accessed from within a nested function.
-///
-/// This class is specific to the [DartIrBuilder], in that it gives up if it
-/// sees a feature that is currently unsupport by that builder. In particular,
-/// loop variables captured in a for-loop initializer, condition, or update
-/// expression are unsupported.
-class DartCapturedVariables extends ast.Visitor {
+/// Determines which local variables should be boxed in a mutable variable
+/// inside a given try block.
+class TryBoxedVariables extends ast.Visitor {
   final TreeElements elements;
-  DartCapturedVariables(this.elements);
+  TryBoxedVariables(this.elements);
 
   FunctionElement currentFunction;
   bool insideInitializer = false;
@@ -2330,25 +2361,6 @@
     node.visitChildren(this);
   }
 
-  visitFor(ast.For node) {
-    if (node.initializer != null) visit(node.initializer);
-    if (node.condition != null) visit(node.condition);
-    if (node.update != null) visit(node.update);
-
-    // Give up if a variable was captured outside of the loop body.
-    if (node.initializer is ast.VariableDefinitions) {
-      ast.VariableDefinitions definitions = node.initializer;
-      for (ast.Node node in definitions.definitions.nodes) {
-        LocalElement loopVariable = elements[node];
-        if (capturedVariables.contains(loopVariable)) {
-          return giveup(node, 'For-loop variable captured in loop header');
-        }
-      }
-    }
-
-    if (node.body != null) visit(node.body);
-  }
-
   void handleSend(ast.Send node) {
     Element element = elements[node];
     if (Elements.isLocal(element) &&
@@ -2406,18 +2418,14 @@
     if (currentFunction.asyncMarker != AsyncMarker.SYNC &&
         currentFunction.asyncMarker != AsyncMarker.SYNC_STAR &&
         currentFunction.asyncMarker != AsyncMarker.ASYNC) {
-      giveup(node, "cannot handle sync*/async* functions");
+      giveup(node, "cannot handle async* functions");
     }
 
-    bool savedInsideInitializer = insideInitializer;
     if (node.initializers != null) {
-      insideInitializer = true;
       visit(node.initializers);
     }
-    insideInitializer = false;
     visit(node.body);
     currentFunction = savedFunction;
-    insideInitializer = savedInsideInitializer;
   }
 
   visitTryStatement(ast.TryStatement node) {
@@ -2494,7 +2502,7 @@
 
   FunctionElement get throwTypeErrorHelper => _backend.helpers.throwTypeError;
 
-  ClassElement get nullClass => _compiler.nullClass;
+  ClassElement get nullClass => _compiler.coreClasses.nullClass;
 
   DartType unaliasType(DartType type) => type.unaliased;
 
@@ -2530,9 +2538,11 @@
 
   JsIrBuilderVisitor(TreeElements elements,
                      Compiler compiler,
-                     SourceInformationBuilder sourceInformationBuilder)
-      : super(elements, compiler, sourceInformationBuilder);
+                     SourceInformationBuilder sourceInformationBuilder,
+                     TypeMaskSystem typeMaskSystem)
+      : super(elements, compiler, sourceInformationBuilder, typeMaskSystem);
 
+  BackendHelpers get helpers => backend.helpers;
 
   /// Builds the IR for creating an instance of the closure class corresponding
   /// to the given nested function.
@@ -2629,6 +2639,7 @@
           root = buildConstructorBody(element);
           break;
 
+        case ElementKind.FACTORY_CONSTRUCTOR:
         case ElementKind.FUNCTION:
         case ElementKind.GETTER:
         case ElementKind.SETTER:
@@ -2684,7 +2695,8 @@
     return new JsIrBuilderVisitor(
         context.resolvedAst.elements,
         compiler,
-        sourceInformationBuilder.forContext(context));
+        sourceInformationBuilder.forContext(context),
+        typeMaskSystem);
   }
 
   /// Builds the IR for an [expression] taken from a different [context].
@@ -2792,7 +2804,7 @@
         if (value != null) {
           instanceArguments.add(value);
         } else {
-          assert(Elements.isNativeOrExtendsNative(c));
+          assert(backend.isNativeOrExtendsNative(c));
           // Native fields are initialized elsewhere.
         }
       }, includeSuperAndInjectedMembers: true);
@@ -2857,7 +2869,7 @@
         if (field.initializer != null) {
           fieldValues[field] = inlineExpression(field, field.initializer);
         } else {
-          if (Elements.isNativeOrExtendsNative(c)) {
+          if (backend.isNativeOrExtendsNative(c)) {
             // Native field is initialized elsewhere.
           } else {
             // Fields without an initializer default to null.
@@ -3124,8 +3136,8 @@
     return parameters;
   }
 
-  DartCapturedVariables _analyzeCapturedVariables(ast.Node node) {
-    DartCapturedVariables variables = new DartCapturedVariables(elements);
+  TryBoxedVariables _analyzeTryBoxedVariables(ast.Node node) {
+    TryBoxedVariables variables = new TryBoxedVariables(elements);
     try {
       variables.analyze(node);
     } catch (e) {
@@ -3155,7 +3167,7 @@
     // error-prone.
     // TODO(kmillikin): We should combine closure conversion and try/catch
     // variable analysis in some way.
-    DartCapturedVariables variables = _analyzeCapturedVariables(node);
+    TryBoxedVariables variables = _analyzeTryBoxedVariables(node);
     tryStatements = variables.tryStatements;
     IrBuilder builder = getBuilderFor(body);
 
@@ -3180,7 +3192,7 @@
             element,
             node,
             elements);
-    DartCapturedVariables variables = _analyzeCapturedVariables(node);
+    TryBoxedVariables variables = _analyzeTryBoxedVariables(node);
     tryStatements = variables.tryStatements;
     IrBuilder builder = getBuilderFor(element);
     return withBuilder(builder, () => _makeFunctionBody(element, node));
@@ -3274,12 +3286,21 @@
     // Use default values from the effective target, not the immediate target.
     ConstructorElement target = constructor.effectiveTarget;
     arguments = normalizeStaticArguments(callStructure, target, arguments);
+    TypeMask allocationSiteType;
+    ast.Node send = node.send;
+    if (Elements.isFixedListConstructorCall(constructor, send, compiler) ||
+        Elements.isGrowableListConstructorCall(constructor, send, compiler) ||
+        Elements.isFilledListConstructorCall(constructor, send, compiler) ||
+        Elements.isConstructorOfTypedArraySubclass(constructor, compiler)) {
+      allocationSiteType = getAllocationSiteType(send);
+    }
     return irBuilder.buildConstructorInvocation(
         target,
         callStructure,
         constructor.computeEffectiveTargetType(type),
         arguments,
-        sourceInformationBuilder.buildNew(node));
+        sourceInformationBuilder.buildNew(node),
+        allocationSiteType: allocationSiteType);
   }
 
   @override
@@ -3368,9 +3389,8 @@
 
     /// Call a helper method from the isolate library. The isolate library uses
     /// its own isolate structure, that encapsulates dart2js's isolate.
-    ir.Primitive buildIsolateHelperInvocation(String helperName,
+    ir.Primitive buildIsolateHelperInvocation(Element element,
                                               CallStructure callStructure) {
-      Element element = backend.isolateHelperLibrary.find(helperName);
       if (element == null) {
         reporter.internalError(node,
             'Isolate library and compiler mismatch.');
@@ -3452,7 +3472,7 @@
         validateArgumentCount(minimum: 2);
 
         ast.Node builtin = argumentNodes.tail.head;
-        JsBuiltin value = getEnumValue(builtin, backend.jsBuiltinEnum,
+        JsBuiltin value = getEnumValue(builtin, helpers.jsBuiltinEnum,
                                        JsBuiltin.values);
         js.Template template = backend.emitter.builtinTemplateFor(value);
         List<ir.Primitive> arguments =
@@ -3490,7 +3510,7 @@
         validateArgumentCount(exactly: 1);
 
         ast.Node argument = argumentNodes.head;
-        JsGetName id = getEnumValue(argument, backend.jsGetNameEnum,
+        JsGetName id = getEnumValue(argument, helpers.jsGetNameEnum,
             JsGetName.values);
         js.Name name = backend.namer.getNameForJsGetName(argument, id);
         ConstantValue nameConstant =
@@ -3529,7 +3549,7 @@
           // to fetch the current isolate.
           continue getStaticState;
         }
-        return buildIsolateHelperInvocation('_currentIsolate',
+        return buildIsolateHelperInvocation(backend.helpers.currentIsolate,
             CallStructure.NO_ARGS);
 
       getStaticState: case 'JS_GET_STATIC_STATE':
@@ -3558,7 +3578,7 @@
           return irBuilder.buildCallInvocation(closure, CallStructure.NO_ARGS,
               const <ir.Primitive>[]);
         }
-        return buildIsolateHelperInvocation('_callInIsolate',
+        return buildIsolateHelperInvocation(backend.helpers.callInIsolate,
             CallStructure.TWO_ARGS);
 
       default:
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_integrity.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_integrity.dart
index dfc07a3..dedfbad 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_integrity.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_integrity.dart
@@ -10,6 +10,8 @@
 /// enabled, you typically want the other as well, so we use the same flag.
 const bool ENABLE_DUMP = tracer.TRACE_FILTER_PATTERN != null;
 
+enum ScopeType { InScope, InDefinition, NotInScope }
+
 /// Performs integrity checks on the CPS IR.
 ///
 /// To be run for debugging purposes, not for use in production.
@@ -27,45 +29,63 @@
 class CheckCpsIntegrity extends TrampolineRecursiveVisitor {
 
   FunctionDefinition topLevelNode;
+  final Map<Definition, ScopeType> inScope = <Definition, ScopeType>{};
+  final List<Definition> definitions = [];
   String previousPass;
 
-  Set<Definition> seenDefinitions = new Set<Definition>();
-  Map<Definition, Set<Reference>> seenReferences =
-      <Definition, Set<Reference>>{};
-
-  Set<Definition> inScope = new Set<Definition>();
-  Set<Continuation> insideContinuations = new Set<Continuation>();
-
-  void markAsSeen(Definition def) {
-    if (!seenDefinitions.add(def)) {
-      error('Redeclared $def', def);
+  void handleDeclaration(Definition def) {
+    definitions.add(def);
+    // Check the reference chain for cycles broken links.
+    Reference anchor = null;
+    int i = 0;
+    for (Reference ref = def.firstRef; ref != null; ref = ref.next) {
+      if (ref.definition != def) {
+        error('Reference to ${ref.definition} found in '
+              'reference chain for $def', def);
+      }
+      if (ref == anchor) {
+        error('Cyclic reference chain for $def', def);
+      }
+      if (i & ++i == 0) { // Move the anchor every 2^Nth step.
+        anchor = ref;
+      }
     }
-    seenReferences[def] = new Set<Reference>();
   }
 
   void enterScope(Iterable<Definition> definitions) {
-    inScope.addAll(definitions);
-    pushAction(() => inScope.removeAll(definitions));
+    for (Definition def in definitions) {
+      inScope[def] = ScopeType.InScope;
+    }
+    pushAction(() {
+      for (Definition def in definitions) {
+        inScope[def] = ScopeType.NotInScope;
+      }
+    });
   }
 
   void enterContinuation(Continuation cont) {
-    insideContinuations.add(cont);
-    pushAction(() => insideContinuations.remove(cont));
+    inScope[cont] = ScopeType.InDefinition;
+    pushAction(() {
+      inScope[cont] = ScopeType.NotInScope;
+    });
   }
 
   void check(FunctionDefinition node, String previousPass) {
-    topLevelNode = node;
+    // [check] will be called multiple times per instance to avoid reallocating
+    // the large [inScope] map. Reset the other fields.
+    this.topLevelNode = node;
     this.previousPass = previousPass;
+    this.definitions.clear();
     ParentChecker.checkParents(node, this);
     visit(node);
     // Check for broken reference chains. We check this last, so out-of-scope
     // references are not classified as a broken reference chain.
-    seenDefinitions.forEach(checkReferenceChain);
+    definitions.forEach(checkReferenceChain);
   }
 
   @override
   Expression traverseLetCont(LetCont node) {
-    node.continuations.forEach(markAsSeen);
+    node.continuations.forEach(handleDeclaration);
     node.continuations.forEach(push);
 
     // Put all continuations in scope when visiting the body.
@@ -76,7 +96,7 @@
 
   @override
   Expression traverseLetPrim(LetPrim node) {
-    markAsSeen(node.primitive);
+    handleDeclaration(node.primitive);
 
     // Process references in the primitive.
     visit(node.primitive);
@@ -89,9 +109,9 @@
 
   @override
   Expression traverseLetMutable(LetMutable node) {
-    markAsSeen(node.variable);
+    handleDeclaration(node.variable);
     processReference(node.value);
-    
+
     // Put the primitive in scope when visiting the body.
     enterScope([node.variable]);
 
@@ -103,7 +123,7 @@
     if (cont.isReturnContinuation) {
       error('Non-return continuation missing body', cont);
     }
-    cont.parameters.forEach(markAsSeen);
+    cont.parameters.forEach(handleDeclaration);
     enterScope(cont.parameters);
     // Put every continuation in scope at its own body. The isRecursive
     // flag is checked explicitly using [insideContinuations].
@@ -115,12 +135,12 @@
   @override
   visitFunctionDefinition(FunctionDefinition node) {
     if (node.thisParameter != null) {
-      markAsSeen(node.thisParameter);
+      handleDeclaration(node.thisParameter);
       enterScope([node.thisParameter]);
     }
-    node.parameters.forEach(markAsSeen);
+    node.parameters.forEach(handleDeclaration);
     enterScope(node.parameters);
-    markAsSeen(node.returnContinuation);
+    handleDeclaration(node.returnContinuation);
     enterScope([node.returnContinuation]);
     if (!node.returnContinuation.isReturnContinuation) {
       error('Return continuation with a body', node);
@@ -129,22 +149,25 @@
   }
 
   @override
-  processReference(Reference reference) {
-    if (!inScope.contains(reference.definition)) {
-      error('Referenced out of scope: ${reference.definition}', reference);
+  processReference(Reference ref) {
+    Definition def = ref.definition;
+    if (inScope[def] == ScopeType.NotInScope) {
+      error('Referenced out of scope: $def', ref);
     }
-    if (!seenReferences[reference.definition].add(reference)) {
-      error('Duplicate use of Reference to ${reference.definition}', reference);
+    if (ref.previous == null && def.firstRef != ref ||
+        ref.previous != null && ref.previous.next != ref) {
+      error('Broken .previous link in reference to $def', def);
     }
+    ref.previous = ref; // Mark reference as "seen". We will repair it later.
   }
 
   @override
   processInvokeContinuation(InvokeContinuation node) {
     Continuation target = node.continuation.definition;
-    if (node.isRecursive && !insideContinuations.contains(target)) {
+    if (node.isRecursive && inScope[target] == ScopeType.InScope) {
       error('Non-recursive InvokeContinuation marked as recursive', node);
     }
-    if (!node.isRecursive && insideContinuations.contains(target)) {
+    if (!node.isRecursive && inScope[target] == ScopeType.InDefinition) {
       error('Recursive InvokeContinuation marked as non-recursive', node);
     }
     if (node.isRecursive && !target.isRecursive) {
@@ -156,25 +179,15 @@
   }
 
   void checkReferenceChain(Definition def) {
-    Set<Reference> chainedReferences = new Set<Reference>();
-    Reference prev = null;
+    Reference previous = null;
     for (Reference ref = def.firstRef; ref != null; ref = ref.next) {
-      if (ref.definition != def) {
-        error('Reference in chain for $def points to ${ref.definition}', def);
+      if (ref.previous != ref) {
+        // Reference was not seen during IR traversal, so it is orphaned.
+        error('Orphaned reference in reference chain for $def', def);
       }
-      if (ref.previous != prev) {
-        error('Broken .previous link in reference to $def', def);
-      }
-      prev = ref;
-      if (!chainedReferences.add(ref)) {
-        error('Cyclic reference chain for $def', def);
-      }
-    }
-    if (!chainedReferences.containsAll(seenReferences[def])) {
-      error('Seen reference to $def not in reference chain', def);
-    }
-    if (!seenReferences[def].containsAll(chainedReferences)) {
-      error('Reference chain for $def contains orphaned references', def);
+      // Repair the .previous link that was used for marking.
+      ref.previous = previous;
+      previous = ref;
     }
   }
 
@@ -192,7 +205,7 @@
       sexpr = '(Set DUMP_IR flag to enable SExpr dump)';
     }
     throw 'CPS integrity violation\n'
-          'After $previousPass on ${topLevelNode.element}\n'
+          'After \'$previousPass\' on ${topLevelNode.element}\n'
           '$message\n\n'
           '$sexpr\n';
   }
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 cbb45f0..50e84bd 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
@@ -590,12 +590,20 @@
   final Selector selector;
   final SourceInformation sourceInformation;
 
+  /// If non-null, this is an allocation site-specific type that is potentially
+  /// better than the inferred return type of [target].
+  ///
+  /// In particular, container type masks depend on the allocation site and
+  /// can therefore not be inferred solely based on the call target.
+  TypeMask allocationSiteType;
+
   InvokeConstructor(this.dartType,
                     this.target,
                     this.selector,
                     List<Primitive> args,
                     Continuation cont,
-                    this.sourceInformation)
+                    this.sourceInformation,
+                    {this.allocationSiteType})
       : arguments = _referenceList(args),
         continuation = new Reference<Continuation>(cont);
 
@@ -1184,22 +1192,85 @@
   }
 }
 
+/// Obtains the interceptor for the given value.  This is a method table
+/// corresponding to the Dart class of the value.
+///
+/// All values are either intercepted or self-intercepted.  The interceptor for
+/// an "intercepted value" is one of the subclasses of Interceptor.
+/// The interceptor for a "self-intercepted value" is the value itself.
+///
+/// If the input is an intercepted value, and any of its superclasses is in
+/// [interceptedClasses], the method table for the input is returned.
+/// Otherwise, the input itself is returned.
+///
+/// There are thus three significant cases:
+/// - the input is a self-interceptor
+/// - the input is an intercepted value and is caught by [interceptedClasses]
+/// - the input is an intercepted value but is bypassed by [interceptedClasses]
+///
+/// The [flags] field indicates which of the above cases may happen, with
+/// additional special cases for null (which can either by intercepted or
+/// bypassed).
 class Interceptor extends Primitive {
   final Reference<Primitive> input;
   final Set<ClassElement> interceptedClasses = new Set<ClassElement>();
   final SourceInformation sourceInformation;
 
-  /// If non-null, all uses of this the interceptor call are guaranteed to
-  /// see this value.
-  ///
-  /// The interceptor call is not immediately replaced by the constant, because
-  /// that might prevent the interceptor from being shared.
-  ///
-  /// The precise input type is not known when sharing interceptors, because
-  /// refinement nodes have been removed by then. So this field carries the
-  /// known constant until we know if it should be shared or replaced by
-  /// the constant.
-  values.InterceptorConstantValue constantValue;
+  /// The input was a self-interceptor.
+  static const int SELF_INTERCEPT = 1 << 0;
+
+  /// A non-null value was mapped to an interceptor that was mentioned in
+  /// [interceptedClasses].
+  static const int NON_NULL_INTERCEPT_EXACT = 1 << 1;
+
+  /// A non-null value was mapped to an interceptor that is a subclass of
+  /// one mentioned in [interceptedClasses].
+  static const int NON_NULL_INTERCEPT_SUBCLASS = 1 << 2;
+
+  /// A non-null intercepted value was bypassed because none of its supertypes
+  /// were mentioned in [interceptedClasses].
+  static const int NON_NULL_BYPASS = 1 << 3;
+
+  /// Null was returned as-is.
+  static const int NULL_BYPASS = 1 << 4;
+
+  /// Null was mapped to JSNull, which was mentioned in [interceptedClasses].
+  static const int NULL_INTERCEPT_EXACT = 1 << 5;
+
+  /// Null was mapped to JSNull, because a superclass thereof (the interceptor
+  /// root class) was mentioned in [interceptedClasses].
+  static const int NULL_INTERCEPT_SUBCLASS = 1 << 6;
+
+  static const int NON_NULL_INTERCEPT = NON_NULL_INTERCEPT_EXACT |
+                                        NON_NULL_INTERCEPT_SUBCLASS;
+  static const int NULL_INTERCEPT = NULL_INTERCEPT_EXACT |
+                                    NULL_INTERCEPT_SUBCLASS;
+  static const int NULL = NULL_BYPASS |
+                          NULL_INTERCEPT;
+  static const int INTERCEPT_EXACT = NON_NULL_INTERCEPT_EXACT |
+                                     NULL_INTERCEPT_EXACT;
+  static const int INTERCEPT_SUBCLASS = NON_NULL_INTERCEPT_SUBCLASS |
+                                        NULL_INTERCEPT_SUBCLASS;
+  static const int INTERCEPT = NULL_INTERCEPT | NON_NULL_INTERCEPT;
+  static const int BYPASS = NULL_BYPASS | NON_NULL_BYPASS;
+
+  static const int ALL_FLAGS = SELF_INTERCEPT | BYPASS | INTERCEPT;
+
+  /// Which of the above cases may happen at runtime. Set by type propagation.
+  int flags = ALL_FLAGS;
+
+  void clearFlag(int flag) {
+    flags &= ~flag;
+  }
+
+  bool get isAlwaysIntercepted => flags & ~INTERCEPT == 0;
+  bool get isAlwaysNullOrIntercepted => flags & ~(NULL | INTERCEPT) == 0;
+
+  /// If the value is intercepted, it always matches exactly a class in
+  /// [interceptedClasses].
+  bool get isInterceptedClassAlwaysExact {
+    return flags & (INTERCEPT & ~INTERCEPT_EXACT) == 0;
+  }
 
   Interceptor(Primitive input, this.sourceInformation)
       : this.input = new Reference<Primitive>(input);
@@ -1274,7 +1345,11 @@
   final InterfaceType dartType;
   final List<Reference<Primitive>> values;
 
-  LiteralList(this.dartType, List<Primitive> values)
+  /// If non-null, this is an allocation site-specific type for the list
+  /// created here.
+  TypeMask allocationSiteType;
+
+  LiteralList(this.dartType, List<Primitive> values, {this.allocationSiteType})
       : this.values = _referenceList(values);
 
   accept(Visitor visitor) => visitor.visitLiteralList(this);
@@ -2004,7 +2079,9 @@
     if (cont.isReturnContinuation) {
       traverseContinuation(cont);
     } else {
-      _trampoline(traverseContinuation(cont));
+      int initialHeight = _stack.length;
+      Expression body = traverseContinuation(cont);
+      _trampoline(body, initialHeight: initialHeight);
     }
   }
 
@@ -2044,8 +2121,8 @@
     return node.body;
   }
 
-  void _trampoline(Expression node) {
-    int initialHeight = _stack.length;
+  void _trampoline(Expression node, {int initialHeight}) {
+    initialHeight = initialHeight ?? _stack.length;
     _processBlock(node);
     while (_stack.length > initialHeight) {
       StackAction callback = _stack.removeLast();
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 1b4d2f4..12a6a31 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart
@@ -81,17 +81,15 @@
         });
       });
       tag("HIR", () {
+        String formatParameter(cps_ir.Parameter param) {
+          return '${names.name(param)} ${param.type}';
+        }
         if (entryPointParameters != null) {
-          String formatParameter(cps_ir.Parameter param) {
-            return '${names.name(param)} ${param.type}';
-          }
           String params = entryPointParameters.map(formatParameter).join(', ');
           printStmt('x0', 'Entry ($params)');
         }
-        for (cps_ir.Parameter param in block.parameters) {
-          String name = names.name(param);
-          printStmt(name, "Parameter $name [useCount=${countUses(param)}]");
-        }
+        String params = block.parameters.map(formatParameter).join(', ');
+        printStmt('x0', 'Parameters ($params)');
         visit(block.body);
       });
     });
@@ -327,7 +325,8 @@
   }
 
   visitInterceptor(cps_ir.Interceptor node) {
-    return "Interceptor(${formatReference(node.input)})";
+    return 'Interceptor(${formatReference(node.input)}, '
+           '${node.interceptedClasses})';
   }
 
   visitCreateFunction(cps_ir.CreateFunction node) {
@@ -415,7 +414,7 @@
   @override
   visitRefinement(cps_ir.Refinement node) {
     String value = formatReference(node.value);
-    return 'Refinement $value ${node.type}';
+    return 'Refinement $value ${node.refineType}';
   }
 }
 
diff --git a/pkg/compiler/lib/src/cps_ir/insert_refinements.dart b/pkg/compiler/lib/src/cps_ir/insert_refinements.dart
index e9a0364..6c5ec70 100644
--- a/pkg/compiler/lib/src/cps_ir/insert_refinements.dart
+++ b/pkg/compiler/lib/src/cps_ir/insert_refinements.dart
@@ -9,6 +9,7 @@
 import '../common/names.dart';
 import '../types/types.dart' show TypeMask;
 import 'type_mask_system.dart';
+import 'cps_fragment.dart';
 
 /// Inserts [Refinement] nodes in the IR to allow for sparse path-sensitive
 /// type analysis in the [TypePropagator] pass.
@@ -34,9 +35,13 @@
 
   /// Updates references to refer to the refinement currently in scope.
   void processReference(Reference node) {
-    Refinement refined = refinementFor[node.definition];
-    if (refined != null) {
-      node.changeTo(refined);
+    Definition definition = node.definition;
+    if (definition is Primitive) {
+      Primitive prim = definition.effectiveDefinition;
+      Refinement refined = refinementFor[prim];
+      if (refined != null && refined != definition) {
+        node.changeTo(refined);
+      }
     }
   }
 
@@ -60,7 +65,6 @@
       // Create a new LetCont binding only this continuation.
       let.continuations.remove(cont);
       let = new LetCont(cont, null);
-      cont.parent = let;
     } else {
       let.remove(); // Reuse the existing LetCont.
     }
@@ -83,7 +87,6 @@
         refined.destroy();
       } else {
         LetPrim let = new LetPrim(refined);
-        refined.parent = let;
         let.insertBelow(cont);
       }
     });
@@ -120,6 +123,34 @@
     }
   }
 
+  void visitTypeCast(TypeCast node) {
+    Continuation cont = node.continuation.definition;
+    Primitive value = node.value.definition;
+
+    processReference(node.value);
+    node.typeArguments.forEach(processReference);
+
+    // Refine the type of the input.
+    sinkContinuationToUse(cont, node);
+    TypeMask type = types.subtypesOf(node.dartType).nullable();
+    Refinement refinement = new Refinement(value, type);
+    pushRefinement(cont, refinement);
+  }
+
+  void visitRefinement(Refinement node) {
+    // We found a pre-existing refinement node. These are generated by the
+    // IR builder to hold information from --trust-type-annotations.
+    // Update its input to use our own current refinement, then update the
+    // environment to use this refinement.
+    processReference(node.value);
+    Primitive value = node.value.definition.effectiveDefinition;
+    Primitive oldRefinement = refinementFor[value];
+    refinementFor[value] = node;
+    pushAction(() {
+      refinementFor[value] = oldRefinement;
+    });
+  }
+
   CallExpression getCallWithResult(Primitive prim) {
     if (prim is Parameter && prim.parent is Continuation) {
       Continuation cont = prim.parent;
@@ -207,9 +238,10 @@
     for (Continuation cont in node.continuations) {
       if (cont.hasExactlyOneUse &&
           (cont.firstRef.parent is InvokeMethod ||
+           cont.firstRef.parent is TypeCast ||
            cont.firstRef.parent is Branch)) {
         // Do not push the continuation here.
-        // visitInvokeMethod and visitBranch will do that.
+        // visitInvokeMethod, visitBranch, and visitTypeCast will do that.
       } else {
         push(cont);
       }
diff --git a/pkg/compiler/lib/src/cps_ir/loop_effects.dart b/pkg/compiler/lib/src/cps_ir/loop_effects.dart
new file mode 100644
index 0000000..9dd39ff
--- /dev/null
+++ b/pkg/compiler/lib/src/cps_ir/loop_effects.dart
@@ -0,0 +1,176 @@
+library dart2js.cps_ir.loop_effects;
+
+import 'cps_ir_nodes.dart';
+import 'loop_hierarchy.dart';
+import 'type_mask_system.dart';
+import '../universe/side_effects.dart';
+import '../elements/elements.dart';
+import '../world.dart';
+
+/// Determines which the [SideEffects] that may occur during each loop in
+/// a given function, in addition to whether the loop may change the length
+/// of an indexable object.
+///
+/// TODO(asgerf): Make length a flag on [SideEffects] for better precision and
+/// so we don't need to special case the length in this class.
+class LoopSideEffects extends TrampolineRecursiveVisitor {
+  LoopHierarchy loopHierarchy;
+  final World world;
+  final Map<Continuation, List<Continuation>> exitContinuations = {};
+  final Map<Continuation, SideEffects> loopSideEffects = {};
+  final Set<Continuation> loopsChangingLength = new Set<Continuation>();
+  Continuation currentLoopHeader;
+  SideEffects currentLoopSideEffects = new SideEffects.empty();
+  bool currentLoopChangesLength = false;
+
+  LoopSideEffects(FunctionDefinition node, this.world, {this.loopHierarchy}) {
+    if (loopHierarchy == null) {
+      loopHierarchy = new LoopHierarchy(node);
+    }
+    visit(node);
+  }
+
+  /// Returns the accumulated effects and dependencies on all paths from the
+  /// loop entry to any recursive invocation of the loop.
+  SideEffects getSideEffectsInLoop(Continuation loop) {
+    return loopSideEffects[loop];
+  }
+
+  /// True if the length of an indexable object may change between the loop
+  /// entry and a recursive invocation of the loop.
+  bool loopChangesLength(Continuation loop) {
+    return loopsChangingLength.contains(loop);
+  }
+
+  @override
+  Expression traverseContinuation(Continuation cont) {
+    if (cont.isRecursive) {
+      SideEffects oldEffects = currentLoopSideEffects;
+      Continuation oldLoopHeader = currentLoopHeader;
+      bool oldChangesLength = currentLoopChangesLength;
+      currentLoopHeader = cont;
+      loopSideEffects[cont] = currentLoopSideEffects = new SideEffects.empty();
+      exitContinuations[cont] = <Continuation>[];
+      pushAction(() {
+        oldEffects.add(currentLoopSideEffects);
+        if (currentLoopChangesLength) {
+          loopsChangingLength.add(cont);
+        }
+        currentLoopChangesLength = currentLoopChangesLength || oldChangesLength;
+        currentLoopHeader = oldLoopHeader;
+        currentLoopSideEffects = oldEffects;
+        exitContinuations[cont].forEach(push);
+      });
+    }
+    return cont.body;
+  }
+
+  @override
+  Expression traverseLetHandler(LetHandler node) {
+    enqueueContinuation(node.handler);
+    return node.body;
+  }
+
+  @override
+  Expression traverseLetCont(LetCont node) {
+    node.continuations.forEach(enqueueContinuation);
+    return node.body;
+  }
+
+  void enqueueContinuation(Continuation cont) {
+    Continuation loop = loopHierarchy.getEnclosingLoop(cont);
+    if (loop == currentLoopHeader) {
+      push(cont);
+    } else {
+      // Multiple loops can be exited at once.
+      // Register as an exit from the outermost loop being exited.
+      Continuation inner = currentLoopHeader;
+      Continuation outer = loopHierarchy.getEnclosingLoop(currentLoopHeader);
+      while (outer != loop) {
+        inner = outer;
+        outer = loopHierarchy.getEnclosingLoop(outer);
+      }
+      exitContinuations[inner].add(cont);
+    }
+  }
+
+  void addSideEffects(SideEffects effects) {
+    currentLoopSideEffects.add(effects);
+    if (effects.changesIndex()) {
+      currentLoopChangesLength = true;
+    }
+  }
+
+  void addAllSideEffects() {
+    currentLoopSideEffects.setAllSideEffects();
+    currentLoopSideEffects.setDependsOnSomething();
+    currentLoopChangesLength = true;
+  }
+
+  void visitInvokeMethod(InvokeMethod node) {
+    addSideEffects(world.getSideEffectsOfSelector(node.selector, node.mask));
+  }
+
+  void visitInvokeStatic(InvokeStatic node) {
+    addSideEffects(world.getSideEffectsOfElement(node.target));
+  }
+
+  void visitInvokeMethodDirectly(InvokeMethodDirectly node) {
+    FunctionElement target = node.target;
+    if (target is ConstructorBodyElement) {
+      ConstructorBodyElement body = target;
+      target = body.constructor;
+    }
+    addSideEffects(world.getSideEffectsOfElement(target));
+  }
+
+  void visitInvokeConstructor(InvokeConstructor node) {
+    addSideEffects(world.getSideEffectsOfElement(node.target));
+  }
+
+  void visitSetStatic(SetStatic node) {
+    currentLoopSideEffects.setChangesStaticProperty();
+  }
+
+  void visitGetStatic(GetStatic node) {
+    currentLoopSideEffects.setDependsOnStaticPropertyStore();
+  }
+
+  void visitGetField(GetField node) {
+    currentLoopSideEffects.setDependsOnInstancePropertyStore();
+  }
+
+  void visitSetField(SetField node) {
+    currentLoopSideEffects.setChangesInstanceProperty();
+  }
+
+  void visitGetIndex(GetIndex node) {
+    currentLoopSideEffects.setDependsOnIndexStore();
+  }
+
+  void visitSetIndex(SetIndex node) {
+    // Set the change index flag without setting the change length flag.
+    currentLoopSideEffects.setChangesIndex();
+  }
+
+  void visitForeignCode(ForeignCode node) {
+    addSideEffects(node.nativeBehavior.sideEffects);
+  }
+
+  void visitGetLazyStatic(GetLazyStatic node) {
+    // TODO(asgerf): How do we get the side effects of a lazy field initializer?
+    addAllSideEffects();
+  }
+
+  void visitAwait(Await node) {
+    addAllSideEffects();
+  }
+
+  void visitYield(Yield node) {
+    addAllSideEffects();
+  }
+
+  void visitApplyBuiltinMethod(ApplyBuiltinMethod node) {
+    currentLoopChangesLength = true; // Push and pop.
+  }
+}
diff --git a/pkg/compiler/lib/src/cps_ir/loop_hierarchy.dart b/pkg/compiler/lib/src/cps_ir/loop_hierarchy.dart
index fc63944..3aa5bc9 100644
--- a/pkg/compiler/lib/src/cps_ir/loop_hierarchy.dart
+++ b/pkg/compiler/lib/src/cps_ir/loop_hierarchy.dart
@@ -7,21 +7,21 @@
 import 'cps_ir_nodes.dart';
 
 /// Determines the effective nesting of loops.
-/// 
+///
 /// The effective nesting of loops is different from the lexical nesting, since
-/// recursive continuations can generally contain all the code following 
+/// recursive continuations can generally contain all the code following
 /// after the loop in addition to the looping code itself.
-/// 
+///
 /// For example, the 'else' branch below is not effectively part of the loop:
-/// 
-///   let rec kont x = 
-///     if (<loop condition>) 
+///
+///   let rec kont x =
+///     if (<loop condition>)
 ///       <loop body>
 ///       InvokeContinuation kont x'
-///     else 
+///     else
 ///       <after loop>
 ///       return p.foo()
-/// 
+///
 /// We use the term "loop" to mean recursive continuation.
 /// The `null` value is used to represent a context not part of any loop.
 class LoopHierarchy {
@@ -36,7 +36,7 @@
   int currentDepth = 0;
 
   /// Computes the loop hierarchy for the given function.
-  /// 
+  ///
   /// Parent pointers must be computed for [node].
   LoopHierarchy(FunctionDefinition node) {
     _processBlock(node.body, null);
@@ -47,21 +47,21 @@
     return cont.isRecursive ? cont : loopTarget[cont];
   }
 
-  /// Returns the innermost loop which the given loop is part of, other
+  /// Returns the innermost loop which the given continuation is part of, other
   /// than itself.
-  Continuation getEnclosingLoop(Continuation loop) {
-    return loopTarget[loop];
+  Continuation getEnclosingLoop(Continuation cont) {
+    return loopTarget[cont];
   }
 
   /// Marks the innermost loop as a subloop of the other loop.
-  /// 
+  ///
   /// Returns the innermost loop.
-  /// 
+  ///
   /// Both continuations, [c1] and [c2] may be null (i.e. no loop).
-  /// 
+  ///
   /// A loop is said to be a subloop of an enclosing loop if it can invoke
   /// that loop recursively. This information is stored in [loopTarget].
-  /// 
+  ///
   /// This method is only invoked with two distinct loops if there is a
   /// point that can reach a recursive invocation of both loops.
   /// This implies that one loop is nested in the other, because they must
@@ -83,7 +83,7 @@
 
   /// Analyzes the body of [cont] and returns the innermost loop
   /// that can be invoked recursively from [cont] (other than [cont] itself).
-  /// 
+  ///
   /// [catchLoop] is the innermost loop that can be invoked recursively
   /// from the current exception handler.
   Continuation _processContinuation(Continuation cont, Continuation catchLoop) {
diff --git a/pkg/compiler/lib/src/cps_ir/optimizers.dart b/pkg/compiler/lib/src/cps_ir/optimizers.dart
index 336806d..37e8b3c 100644
--- a/pkg/compiler/lib/src/cps_ir/optimizers.dart
+++ b/pkg/compiler/lib/src/cps_ir/optimizers.dart
@@ -15,6 +15,7 @@
 export 'mutable_ssa.dart' show MutableVariableEliminator;
 export 'insert_refinements.dart' show InsertRefinements;
 export 'remove_refinements.dart' show RemoveRefinements;
+export 'share_final_fields.dart' show ShareFinalFields;
 export 'share_interceptors.dart' show ShareInterceptors;
 export 'bounds_checker.dart' show BoundsChecker;
 export 'parent_visitor.dart' show ParentVisitor;
diff --git a/pkg/compiler/lib/src/cps_ir/remove_refinements.dart b/pkg/compiler/lib/src/cps_ir/remove_refinements.dart
index 98f1c17..2d49c95 100644
--- a/pkg/compiler/lib/src/cps_ir/remove_refinements.dart
+++ b/pkg/compiler/lib/src/cps_ir/remove_refinements.dart
@@ -23,7 +23,11 @@
     Expression next = node.body;
     if (node.primitive is Refinement) {
       Refinement refinement = node.primitive;
-      refinement.value.definition.substituteFor(refinement);
+      Primitive value = refinement.value.definition;
+      if (refinement.hint != null && value.hint == null) {
+        value.hint = refinement.hint;
+      }
+      value.substituteFor(refinement);
       refinement.destroy();
       node.remove();
     }
diff --git a/pkg/compiler/lib/src/cps_ir/scalar_replacement.dart b/pkg/compiler/lib/src/cps_ir/scalar_replacement.dart
index 0ff315c..9d5ce4f 100644
--- a/pkg/compiler/lib/src/cps_ir/scalar_replacement.dart
+++ b/pkg/compiler/lib/src/cps_ir/scalar_replacement.dart
@@ -18,7 +18,7 @@
 
 /**
  * Replaces aggregates with a set of local values.  Performs inlining of
- * single-use closures to generate more replacable aggregates.
+ * single-use closures to generate more replaceable aggregates.
  */
 class ScalarReplacer extends Pass {
   String get passName => 'Scalar replacement';
@@ -41,7 +41,7 @@
 
 /**
  * Do scalar replacement of aggregates on instances. Since scalar replacement
- * can create new candidiates, iterate until all scalar replacements are done.
+ * can create new candidates, iterate until all scalar replacements are done.
  */
 class ScalarReplacementVisitor extends TrampolineRecursiveVisitor {
 
@@ -104,7 +104,8 @@
         (ClassElement enclosingClass, FieldElement field) {
           Primitive argument = allocation.arguments[i++].definition;
           fieldInitialValues[field] = argument;
-        });
+        },
+        includeSuperAndInjectedMembers: true);
     }
 
     // Create [MutableVariable]s for each written field. Initialize the
diff --git a/pkg/compiler/lib/src/cps_ir/share_final_fields.dart b/pkg/compiler/lib/src/cps_ir/share_final_fields.dart
new file mode 100644
index 0000000..3308c00
--- /dev/null
+++ b/pkg/compiler/lib/src/cps_ir/share_final_fields.dart
@@ -0,0 +1,181 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.cps_ir.share_final_fields;
+
+import 'optimizers.dart';
+import 'cps_ir_nodes.dart';
+import 'loop_hierarchy.dart';
+import '../elements/elements.dart';
+import '../js_backend/js_backend.dart' show JavaScriptBackend;
+import '../types/types.dart' show TypeMask;
+
+/// Removes redundant GetField operations.
+///
+/// The pass performs these optimizations for field loads:
+/// - share GetFields of final fields when one is in scope of the other.
+/// - pull GetField operations of final fields out of loops when safe (object is
+///   not null).
+///
+/// This pass only optimizes final fields and should be replaced with a full
+/// load elimination pass.
+class ShareFinalFields extends TrampolineRecursiveVisitor implements Pass {
+  String get passName => 'Share final fields';
+
+  /// The innermost loop containing a given primitive.
+  final Map<Primitive, Continuation> loopHeaderFor =
+      <Primitive, Continuation>{};
+
+  // field -> receiver -> GetField
+  Map<FieldElement, Map<Primitive, Primitive>> fieldValues =
+      <FieldElement, Map<Primitive, Primitive>>{};
+
+  /// Interceptors that have been hoisted out of a given loop.
+  final Map<Continuation, List<GetField>> loopHoistedGetters =
+      <Continuation, List<GetField>>{};
+
+  JavaScriptBackend backend;
+  LoopHierarchy loopHierarchy;
+  Continuation currentLoopHeader;
+
+  ShareFinalFields(this.backend);
+
+  void rewrite(FunctionDefinition node) {
+    loopHierarchy = new LoopHierarchy(node);
+    visit(node.body);
+  }
+
+  @override
+  Expression traverseContinuation(Continuation cont) {
+    Continuation oldLoopHeader = currentLoopHeader;
+    currentLoopHeader = loopHierarchy.getLoopHeader(cont);
+    for (Parameter parameter in cont.parameters) {
+      loopHeaderFor[parameter] = currentLoopHeader;
+    }
+    if (cont.isRecursive) {
+      pushAction(() {
+        // After the loop body has been processed, all values hoisted to this
+        // loop fall out of scope and should be removed from the environment.
+        List<GetField> hoisted = loopHoistedGetters[cont];
+        if (hoisted != null) {
+          for (GetField primitive in hoisted) {
+            Primitive refinedReceiver = primitive.object.definition;
+            Primitive receiver = refinedReceiver.effectiveDefinition;
+            var map = fieldValues[primitive.field];
+            assert(map[receiver] == primitive);
+            map.remove(receiver);
+          }
+        }
+      });
+    }
+    pushAction(() {
+      currentLoopHeader = oldLoopHeader;
+    });
+    return cont.body;
+  }
+
+  Continuation getCurrentOuterLoop({Continuation scope}) {
+    Continuation inner = null, outer = currentLoopHeader;
+    while (outer != scope) {
+      inner = outer;
+      outer = loopHierarchy.getEnclosingLoop(outer);
+    }
+    return inner;
+  }
+
+  @override
+  Expression traverseLetPrim(LetPrim node) {
+    loopHeaderFor[node.primitive] = currentLoopHeader;
+    Expression next = node.body;
+    if (node.primitive is! GetField) {
+      return next;
+    }
+    GetField primitive = node.primitive;
+    FieldElement field = primitive.field;
+
+    if (!shouldShareField(field)) {
+      return next;
+    }
+
+    Primitive refinedReceiver = primitive.object.definition;
+    Primitive receiver = refinedReceiver.effectiveDefinition;
+
+    // Try to reuse an existing load for the same input.
+    var map = fieldValues.putIfAbsent(field, () => <Primitive,Primitive>{});
+    Primitive existing = map[receiver];
+    if (existing != null) {
+      existing.substituteFor(primitive);
+      primitive.destroy();
+      node.remove();
+      return next;
+    }
+
+    map[receiver] = primitive;
+
+    if (primitive.objectIsNotNull) {
+      // Determine how far the GetField can be lifted. The outermost loop that
+      // contains the input binding should also contain the load.
+      // Don't move above a refinement guard since that might be unsafe.
+
+      // TODO(sra): We can move above a refinement guard provided the input is
+      // still in scope and safe (non-null). We will have to replace
+      // primitive.object with the most constrained refinement still in scope.
+      Continuation referencedLoop =
+          lowestCommonAncestor(loopHeaderFor[refinedReceiver],
+                               currentLoopHeader);
+      if (referencedLoop != currentLoopHeader) {
+        Continuation hoistTarget = getCurrentOuterLoop(scope: referencedLoop);
+        LetCont loopBinding = hoistTarget.parent;
+        node.remove();
+        node.insertAbove(loopBinding);
+        // Remove the hoisted operations from the environment after processing
+        // the loop.
+        loopHoistedGetters
+            .putIfAbsent(hoistTarget, () => <GetField>[])
+            .add(primitive);
+        return next;
+      }
+    }
+
+    pushAction(() {
+        var map = fieldValues[field];
+        assert(map[receiver] == primitive);
+        map.remove(receiver);
+      });
+    return next;
+  }
+
+  bool shouldShareField(FieldElement field) {
+    // TODO(24781): This query is incorrect for fields assigned only via
+    //
+    //     super.field = ...
+    //
+    // return backend.compiler.world.fieldNeverChanges(field);
+
+    // Native fields are getters with side effects (e.g. layout).
+    if (backend.isNative(field)) return false;
+    return field.isFinal || field.isConst;
+  }
+
+  /// Returns the the innermost loop that effectively encloses both
+  /// c1 and c2 (or `null` if there is no such loop).
+  Continuation lowestCommonAncestor(Continuation c1, Continuation c2) {
+    int d1 = getDepth(c1), d2 = getDepth(c2);
+    while (c1 != c2) {
+      if (d1 <= d2) {
+        c2 = loopHierarchy.getEnclosingLoop(c2);
+        d2 = getDepth(c2);
+      } else {
+        c1 = loopHierarchy.getEnclosingLoop(c1);
+        d1 = getDepth(c1);
+      }
+    }
+    return c1;
+  }
+
+  int getDepth(Continuation loop) {
+    if (loop == null) return -1;
+    return loopHierarchy.loopDepth[loop];
+  }
+}
diff --git a/pkg/compiler/lib/src/cps_ir/share_interceptors.dart b/pkg/compiler/lib/src/cps_ir/share_interceptors.dart
index 3706725..1fbbba3 100644
--- a/pkg/compiler/lib/src/cps_ir/share_interceptors.dart
+++ b/pkg/compiler/lib/src/cps_ir/share_interceptors.dart
@@ -7,10 +7,16 @@
 import 'optimizers.dart';
 import 'cps_ir_nodes.dart';
 import 'loop_hierarchy.dart';
+import 'cps_fragment.dart';
 import '../constants/values.dart';
+import '../elements/elements.dart';
+import '../js_backend/backend_helpers.dart' show BackendHelpers;
+import '../js_backend/js_backend.dart' show JavaScriptBackend;
+import '../types/types.dart' show TypeMask;
+import '../io/source_information.dart' show SourceInformation;
 
 /// Removes redundant `getInterceptor` calls.
-/// 
+///
 /// The pass performs three optimizations for interceptors:
 ///- pull interceptors out of loops
 ///- replace interceptors with constants
@@ -23,31 +29,29 @@
       <Primitive, Continuation>{};
 
   /// An interceptor currently in scope for a given primitive.
-  final Map<Primitive, Primitive> interceptorFor =
-      <Primitive, Primitive>{};
+  final Map<Primitive, Interceptor> interceptorFor = <Primitive, Interceptor>{};
 
-  /// A primitive currently in scope holding a given interceptor constant.
-  final Map<ConstantValue, Primitive> sharedConstantFor =
-      <ConstantValue, Primitive>{};
+  /// Interceptors that have been hoisted out of a given loop.
+  final Map<Continuation, List<Interceptor>> loopHoistedInterceptors =
+      <Continuation, List<Interceptor>>{};
 
-  /// Interceptors to be hoisted out of the given loop.
-  final Map<Continuation, List<Primitive>> loopHoistedInterceptors =
-      <Continuation, List<Primitive>>{};
-
+  JavaScriptBackend backend;
   LoopHierarchy loopHierarchy;
   Continuation currentLoopHeader;
 
+  ShareInterceptors(this.backend);
+
+  BackendHelpers get helpers => backend.helpers;
+
   void rewrite(FunctionDefinition node) {
     loopHierarchy = new LoopHierarchy(node);
     visit(node.body);
+    new ShareConstants().visit(node);
   }
 
   @override
   Expression traverseContinuation(Continuation cont) {
     Continuation oldLoopHeader = currentLoopHeader;
-    pushAction(() {
-      currentLoopHeader = oldLoopHeader;
-    });
     currentLoopHeader = loopHierarchy.getLoopHeader(cont);
     for (Parameter param in cont.parameters) {
       loopHeaderFor[param] = currentLoopHeader;
@@ -57,26 +61,118 @@
         // After the loop body has been processed, all interceptors hoisted
         // to this loop fall out of scope and should be removed from the
         // environment.
-        List<Primitive> hoisted = loopHoistedInterceptors[cont];
+        List<Interceptor> hoisted = loopHoistedInterceptors[cont];
         if (hoisted != null) {
-          for (Primitive interceptor in hoisted) {
-            if (interceptor is Interceptor) {
-              Primitive input = interceptor.input.definition;
-              assert(interceptorFor[input] == interceptor);
-              interceptorFor.remove(input);
-            } else if (interceptor is Constant) {
-              assert(sharedConstantFor[interceptor.value] == interceptor);
-              sharedConstantFor.remove(interceptor.value);
-            } else {
-              throw "Unexpected interceptor: $interceptor";
-            }
+          for (Interceptor interceptor in hoisted) {
+            Primitive input = interceptor.input.definition;
+            assert(interceptorFor[input] == interceptor);
+            interceptorFor.remove(input);
+            constifyInterceptor(interceptor);
           }
         }
       });
     }
+    pushAction(() {
+      currentLoopHeader = oldLoopHeader;
+    });
     return cont.body;
   }
 
+  /// If only one method table can be returned by the given interceptor,
+  /// returns a constant for that method table.
+  InterceptorConstantValue getInterceptorConstant(Interceptor node) {
+    if (node.interceptedClasses.length == 1 &&
+        node.isInterceptedClassAlwaysExact) {
+      ClassElement interceptorClass = node.interceptedClasses.single;
+      return new InterceptorConstantValue(interceptorClass.rawType);
+    }
+    return null;
+  }
+
+  bool hasNoFalsyValues(ClassElement class_) {
+    return class_ != helpers.jsInterceptorClass &&
+       class_ != helpers.jsNullClass &&
+       class_ != helpers.jsBoolClass &&
+       class_ != helpers.jsStringClass &&
+       !class_.isSubclassOf(helpers.jsNumberClass);
+  }
+
+  Continuation getCurrentOuterLoop({Continuation scope}) {
+    Continuation inner = null, outer = currentLoopHeader;
+    while (outer != scope) {
+      inner = outer;
+      outer = loopHierarchy.getEnclosingLoop(outer);
+    }
+    return inner;
+  }
+
+  /// Binds the given constant in a primitive, in scope of the [useSite].
+  ///
+  /// The constant will be hoisted out of loops, and shared with other requests
+  /// for the same constant as long as it is in scope.
+  Primitive makeConstantFor(ConstantValue constant,
+                            {Expression useSite,
+                             TypeMask type,
+                             SourceInformation sourceInformation,
+                             Entity hint}) {
+    Constant prim =
+        new Constant(constant, sourceInformation: sourceInformation);
+    prim.hint = hint;
+    prim.type = type;
+    LetPrim letPrim = new LetPrim(prim);
+    Continuation loop = getCurrentOuterLoop();
+    if (loop != null) {
+      LetCont loopBinding = loop.parent;
+      letPrim.insertAbove(loopBinding);
+    } else {
+      letPrim.insertAbove(useSite);
+    }
+    return prim;
+  }
+
+  void constifyInterceptor(Interceptor interceptor) {
+    LetPrim let = interceptor.parent;
+    InterceptorConstantValue constant = getInterceptorConstant(interceptor);
+
+    if (constant == null) return;
+
+    if (interceptor.isAlwaysIntercepted) {
+      Primitive constantPrim = makeConstantFor(constant,
+          useSite: let,
+          type: interceptor.type,
+          sourceInformation: interceptor.sourceInformation);
+      constantPrim.useElementAsHint(interceptor.hint);
+      constantPrim.substituteFor(interceptor);
+      interceptor.destroy();
+      let.remove();
+    } else if (interceptor.isAlwaysNullOrIntercepted) {
+      Primitive input = interceptor.input.definition;
+      Primitive constantPrim = makeConstantFor(constant,
+          useSite: let,
+          type: interceptor.type.nonNullable(),
+          sourceInformation: interceptor.sourceInformation);
+      CpsFragment cps = new CpsFragment(interceptor.sourceInformation);
+      Parameter param = new Parameter(interceptor.hint);
+      Continuation cont = cps.letCont(<Parameter>[param]);
+      if (interceptor.interceptedClasses.every(hasNoFalsyValues)) {
+        // If null is the only falsy value, compile as "x && CONST".
+        cps.ifFalsy(input).invokeContinuation(cont, [input]);
+      } else {
+        // If there are other falsy values compile as "x == null ? x : CONST".
+        Primitive condition = cps.applyBuiltin(
+            BuiltinOperator.LooseEq,
+            [input, cps.makeNull()]);
+        cps.ifTruthy(condition).invokeContinuation(cont, [input]);
+      }
+      cps.invokeContinuation(cont, [constantPrim]);
+      cps.context = cont;
+      cps.insertAbove(let);
+      param.substituteFor(interceptor);
+      interceptor.destroy();
+      let.remove();
+    }
+  }
+
   @override
   Expression traverseLetPrim(LetPrim node) {
     loopHeaderFor[node.primitive] = currentLoopHeader;
@@ -88,88 +184,45 @@
     Primitive input = interceptor.input.definition;
 
     // Try to reuse an existing interceptor for the same input.
-    Primitive existing = interceptorFor[input];
+    Interceptor existing = interceptorFor[input];
     if (existing != null) {
-      if (existing is Interceptor) {
-        existing.interceptedClasses.addAll(interceptor.interceptedClasses);
-      }
+      existing.interceptedClasses.addAll(interceptor.interceptedClasses);
+      existing.flags |= interceptor.flags;
       existing.substituteFor(interceptor);
       interceptor.destroy();
       node.remove();
       return next;
     }
 
-    // There is no interceptor obtained from this particular input, but
-    // there might one obtained from another input that is known to
-    // have the same result, so try to reuse that.
-    InterceptorConstantValue constant = interceptor.constantValue;
-    if (constant != null) {
-      existing = sharedConstantFor[constant];
-      if (existing != null) {
-        existing.substituteFor(interceptor);
-        interceptor.destroy();
-        node.remove();
-        return next;
-      }
+    // Put this interceptor in the environment.
+    interceptorFor[input] = interceptor;
 
-      // The interceptor could not be shared. Replace it with a constant.
-      Constant constantPrim = new Constant(constant);
-      node.primitive = constantPrim;
-      constantPrim.parent = node;
-      constantPrim.hint = interceptor.hint;
-      constantPrim.type = interceptor.type;
-      constantPrim.substituteFor(interceptor);
-      interceptor.destroy();
-      sharedConstantFor[constant] = constantPrim;
-    } else {
-      interceptorFor[input] = interceptor;
-    }
-
-    // Determine the outermost loop where the input to the interceptor call
-    // is available.  Constant interceptors take no input and can thus be
-    // hoisted all way to the top-level.
-    Continuation referencedLoop = constant != null
-        ? null
-        : lowestCommonAncestor(loopHeaderFor[input], currentLoopHeader);
+    // Determine how far the interceptor can be lifted. The outermost loop
+    // that contains the input binding should also contain the interceptor
+    // binding.
+    Continuation referencedLoop =
+        lowestCommonAncestor(loopHeaderFor[input], currentLoopHeader);
     if (referencedLoop != currentLoopHeader) {
-      // [referencedLoop] contains the binding for [input], so we cannot hoist
-      // the interceptor outside that loop.  Find the loop nested one level
-      // inside referencedLoop, and hoist the interceptor just outside that one.
-      Continuation loop = currentLoopHeader;
-      Continuation enclosing = loopHierarchy.getEnclosingLoop(loop);
-      while (enclosing != referencedLoop) {
-        assert(loop != null);
-        loop = enclosing;
-        enclosing = loopHierarchy.getEnclosingLoop(loop);
-      }
-      assert(loop != null);
-
-      // Move the LetPrim above the loop binding.
-      LetCont loopBinding = loop.parent;
+      Continuation hoistTarget = getCurrentOuterLoop(scope: referencedLoop);
+      LetCont loopBinding = hoistTarget.parent;
       node.remove();
       node.insertAbove(loopBinding);
-
-      // A different loop now contains the interceptor.
-      loopHeaderFor[node.primitive] = enclosing;
-
-      // Register the interceptor as hoisted to that loop, so it will be
-      // removed from the environment when it falls out of scope.
+      // Remove the interceptor from the environment after processing the loop.
       loopHoistedInterceptors
-          .putIfAbsent(loop, () => <Primitive>[])
-          .add(node.primitive);
-    } else if (constant != null) {
-      // The LetPrim was not hoisted. Remove the bound interceptor from the
-      // environment when leaving the LetPrim body.
-      pushAction(() {
-        assert(sharedConstantFor[constant] == node.primitive);
-        sharedConstantFor.remove(constant);
-      });
+          .putIfAbsent(hoistTarget, () => <Interceptor>[])
+          .add(interceptor);
     } else {
+      // Remove the interceptor from the environment when it falls out of scope.
       pushAction(() {
-        assert(interceptorFor[input] == node.primitive);
+        assert(interceptorFor[input] == interceptor);
         interceptorFor.remove(input);
+
+        // Now that the final set of intercepted classes has been seen, try to
+        // replace it with a constant.
+        constifyInterceptor(interceptor);
       });
     }
+
     return next;
   }
 
@@ -194,3 +247,32 @@
     return loopHierarchy.loopDepth[loop];
   }
 }
+
+class ShareConstants extends TrampolineRecursiveVisitor {
+  Map<ConstantValue, Constant> sharedConstantFor = <ConstantValue, Constant>{};
+
+  Expression traverseLetPrim(LetPrim node) {
+    Expression next = node.body;
+    if (node.primitive is Constant && shouldShareConstant(node.primitive)) {
+      Constant prim = node.primitive;
+      Constant existing = sharedConstantFor[prim.value];
+      if (existing != null) {
+        existing.substituteFor(prim);
+        existing.useElementAsHint(prim.hint);
+        prim.destroy();
+        node.remove();
+        return next;
+      }
+      sharedConstantFor[prim.value] = prim;
+      pushAction(() {
+        assert(sharedConstantFor[prim.value] == prim);
+        sharedConstantFor.remove(prim.value);
+      });
+    }
+    return next;
+  }
+
+  bool shouldShareConstant(Constant constant) {
+    return constant.value.isInterceptor;
+  }
+}
diff --git a/pkg/compiler/lib/src/cps_ir/type_mask_system.dart b/pkg/compiler/lib/src/cps_ir/type_mask_system.dart
index ba44ed1..a36f284 100644
--- a/pkg/compiler/lib/src/cps_ir/type_mask_system.dart
+++ b/pkg/compiler/lib/src/cps_ir/type_mask_system.dart
@@ -9,10 +9,12 @@
 import '../constants/values.dart';
 import '../dart_types.dart' as types;
 import '../elements/elements.dart';
+import '../js_backend/backend_helpers.dart' show BackendHelpers;
 import '../js_backend/js_backend.dart' show JavaScriptBackend;
 import '../types/types.dart';
 import '../types/constants.dart' show computeTypeMask;
 import '../universe/selector.dart' show Selector;
+import '../universe/call_structure.dart' show CallStructure;
 import '../world.dart' show World;
 
 enum AbstractBool {
@@ -24,6 +26,13 @@
   final World classWorld;
   final JavaScriptBackend backend;
 
+  TypeMask _numStringBoolType;
+  TypeMask _fixedLengthType;
+  TypeMask _interceptorType;
+  TypeMask _interceptedTypes; // Does not include null.
+
+  TypeMask __indexableTypeTest;
+
   TypeMask get dynamicType => inferrer.dynamicType;
   TypeMask get typeType => inferrer.typeType;
   TypeMask get functionType => inferrer.functionType;
@@ -36,49 +45,95 @@
   TypeMask get mapType => inferrer.mapType;
   TypeMask get nonNullType => inferrer.nonNullType;
   TypeMask get nullType => inferrer.nullType;
-  TypeMask get extendableNativeListType => backend.extendableArrayType;
+  TypeMask get extendableArrayType => backend.extendableArrayType;
+  TypeMask get fixedArrayType => backend.fixedArrayType;
+  TypeMask get arrayType =>
+      new TypeMask.nonNullSubclass(helpers.jsArrayClass, classWorld);
 
   TypeMask get uint31Type => inferrer.uint31Type;
   TypeMask get uint32Type => inferrer.uint32Type;
   TypeMask get uintType => inferrer.positiveIntType;
 
-  TypeMask numStringBoolType;
-  TypeMask fixedLengthType;
-  TypeMask interceptorType;
+  TypeMask get numStringBoolType {
+    if (_numStringBoolType == null) {
+      // Build the number+string+bool type. To make containment tests more
+      // inclusive, we use the num, String, bool types for this, not
+      // the JSNumber, JSString, JSBool subclasses.
+      TypeMask anyNum =
+          new TypeMask.nonNullSubtype(classWorld.numClass, classWorld);
+      TypeMask anyString =
+          new TypeMask.nonNullSubtype(classWorld.stringClass, classWorld);
+      TypeMask anyBool =
+          new TypeMask.nonNullSubtype(classWorld.boolClass, classWorld);
+      _numStringBoolType =
+          new TypeMask.unionOf(<TypeMask>[anyNum, anyString, anyBool],
+              classWorld);
+    }
+    return _numStringBoolType;
+  }
 
-  ClassElement get jsNullClass => backend.jsNullClass;
+  TypeMask get fixedLengthType {
+    if (_fixedLengthType == null) {
+      List<TypeMask> fixedLengthTypes =
+          <TypeMask>[stringType, backend.fixedArrayType];
+      if (classWorld.isInstantiated(helpers.typedArrayClass)) {
+        fixedLengthTypes.add(nonNullSubclass(helpers.typedArrayClass));
+      }
+      _fixedLengthType = new TypeMask.unionOf(fixedLengthTypes, classWorld);
+    }
+    return _fixedLengthType;
+  }
+
+  TypeMask get interceptorType {
+    if (_interceptorType == null) {
+      _interceptorType =
+        new TypeMask.nonNullSubtype(helpers.jsInterceptorClass, classWorld);
+    }
+    return _interceptorType;
+  }
+
+  TypeMask get interceptedTypes { // Does not include null.
+    if (_interceptedTypes == null) {
+      // We redundantly include subtypes of num/string/bool as intercepted
+      // types, because the type system does not infer that their
+      // implementations are all subclasses of Interceptor.
+      _interceptedTypes = new TypeMask.unionOf(
+          <TypeMask>[interceptorType, numStringBoolType], classWorld);
+    }
+    return _interceptedTypes;
+  }
+
+  TypeMask get _indexableTypeTest {
+    if (__indexableTypeTest == null) {
+      // Make a TypeMask containing Indexable and (redundantly) subtypes of
+      // string because the type inference does not infer that all strings are
+      // indexables.
+      TypeMask indexable =
+          new TypeMask.nonNullSubtype(helpers.jsIndexableClass, classWorld);
+      TypeMask anyString =
+          new TypeMask.nonNullSubtype(classWorld.stringClass, classWorld);
+      __indexableTypeTest = new TypeMask.unionOf(
+          <TypeMask>[indexable, anyString],
+          classWorld);
+    }
+    return __indexableTypeTest;
+  }
+
+  ClassElement get jsNullClass => helpers.jsNullClass;
+
+  BackendHelpers get helpers => backend.helpers;
 
   // TODO(karlklose): remove compiler here.
   TypeMaskSystem(dart2js.Compiler compiler)
       : inferrer = compiler.typesTask,
         classWorld = compiler.world,
         backend = compiler.backend {
-
-    // Build the number+string+bool type. To make containment tests more
-    // inclusive, we use the num, String, bool types for this, not
-    // the JSNumber, JSString, JSBool subclasses.
-    TypeMask anyNum =
-        new TypeMask.nonNullSubtype(classWorld.numClass, classWorld);
-    TypeMask anyString =
-        new TypeMask.nonNullSubtype(classWorld.stringClass, classWorld);
-    TypeMask anyBool =
-        new TypeMask.nonNullSubtype(classWorld.boolClass, classWorld);
-    numStringBoolType =
-        new TypeMask.unionOf(<TypeMask>[anyNum, anyString, anyBool],
-            classWorld);
-    interceptorType =
-        new TypeMask.nonNullSubtype(backend.jsInterceptorClass, classWorld);
-
-    TypeMask typedArray = nonNullSubclass(backend.typedArrayClass);
-    fixedLengthType = new TypeMask.unionOf(
-            <TypeMask>[stringType, backend.fixedArrayType, typedArray],
-            classWorld);
   }
 
   bool methodUsesReceiverArgument(FunctionElement function) {
     assert(backend.isInterceptedMethod(function));
     ClassElement clazz = function.enclosingClass.declaration;
-    return clazz.isSubclassOf(backend.jsInterceptorClass) ||
+    return clazz.isSubclassOf(helpers.jsInterceptorClass) ||
            classWorld.isUsedAsMixin(clazz);
   }
 
@@ -133,6 +188,12 @@
     return a.union(b, classWorld);
   }
 
+  TypeMask intersection(TypeMask a, TypeMask b) {
+    if (a == null) return b;
+    if (b == null) return a;
+    return a.intersection(b, classWorld);
+  }
+
   TypeMask getTypeOf(ConstantValue constant) {
     return computeTypeMask(inferrer.compiler, constant);
   }
@@ -207,61 +268,58 @@
   bool isDefinitelyNonNegativeInt(TypeMask t, {bool allowNull: false}) {
     if (!allowNull && t.isNullable) return false;
     // The JSPositiveInt class includes zero, despite the name.
-    return t.satisfies(backend.jsPositiveIntClass, classWorld);
+    return t.satisfies(helpers.jsPositiveIntClass, classWorld);
   }
 
   bool isDefinitelyInt(TypeMask t, {bool allowNull: false}) {
     if (!allowNull && t.isNullable) return false;
-    return t.satisfies(backend.jsIntClass, classWorld);
+    return t.nonNullable().containsOnlyInt(classWorld);
   }
 
   bool isDefinitelyUint31(TypeMask t, {bool allowNull: false}) {
     if (!allowNull && t.isNullable) return false;
-    return t.satisfies(backend.jsUInt31Class, classWorld);
+    return t.satisfies(helpers.jsUInt31Class, classWorld);
   }
 
   bool isDefinitelyUint32(TypeMask t, {bool allowNull: false}) {
     if (!allowNull && t.isNullable) return false;
-    return t.satisfies(backend.jsUInt32Class, classWorld);
+    return t.satisfies(helpers.jsUInt32Class, classWorld);
   }
 
   bool isDefinitelyUint(TypeMask t, {bool allowNull: false}) {
     if (!allowNull && t.isNullable) return false;
-    return t.satisfies(backend.jsPositiveIntClass, classWorld);
+    return t.satisfies(helpers.jsPositiveIntClass, classWorld);
   }
 
-  // TODO(sra): Find a better name.  'NativeList' is a bad name because there
-  // are many native classes in dart:html that implement List but are not (and
-  // should not be) included in this predicate.
-  bool isDefinitelyNativeList(TypeMask t, {bool allowNull: false}) {
+  bool isDefinitelyArray(TypeMask t, {bool allowNull: false}) {
     if (!allowNull && t.isNullable) return false;
-    return t.nonNullable().satisfies(backend.jsArrayClass, classWorld);
+    return t.nonNullable().satisfies(helpers.jsArrayClass, classWorld);
   }
 
-  bool isDefinitelyMutableNativeList(TypeMask t, {bool allowNull: false}) {
+  bool isDefinitelyMutableArray(TypeMask t, {bool allowNull: false}) {
     if (!allowNull && t.isNullable) return false;
-    return t.nonNullable().satisfies(backend.jsMutableArrayClass, classWorld);
+    return t.nonNullable().satisfies(helpers.jsMutableArrayClass, classWorld);
   }
 
-  bool isDefinitelyFixedNativeList(TypeMask t, {bool allowNull: false}) {
+  bool isDefinitelyFixedArray(TypeMask t, {bool allowNull: false}) {
     if (!allowNull && t.isNullable) return false;
-    return t.nonNullable().satisfies(backend.jsFixedArrayClass, classWorld);
+    return t.nonNullable().satisfies(helpers.jsFixedArrayClass, classWorld);
   }
 
-  bool isDefinitelyExtendableNativeList(TypeMask t, {bool allowNull: false}) {
+  bool isDefinitelyExtendableArray(TypeMask t, {bool allowNull: false}) {
     if (!allowNull && t.isNullable) return false;
-    return t.nonNullable().satisfies(backend.jsExtendableArrayClass,
+    return t.nonNullable().satisfies(helpers.jsExtendableArrayClass,
                                      classWorld);
   }
 
   bool isDefinitelyIndexable(TypeMask t, {bool allowNull: false}) {
     if (!allowNull && t.isNullable) return false;
-    return t.nonNullable().satisfies(backend.jsIndexableClass, classWorld);
+    return _indexableTypeTest.containsMask(t.nonNullable(), classWorld);
   }
 
   bool isDefinitelyMutableIndexable(TypeMask t, {bool allowNull: false}) {
     if (!allowNull && t.isNullable) return false;
-    return t.nonNullable().satisfies(backend.jsMutableIndexableClass,
+    return t.nonNullable().satisfies(helpers.jsMutableIndexableClass,
         classWorld);
   }
 
@@ -270,6 +328,24 @@
     return fixedLengthType.containsMask(t.nonNullable(), classWorld);
   }
 
+  bool isDefinitelyIntercepted(TypeMask t, {bool allowNull}) {
+    assert(allowNull != null);
+    if (!allowNull && t.isNullable) return false;
+    return interceptedTypes.containsMask(t.nonNullable(), classWorld);
+  }
+
+  /// Given a class from the interceptor hierarchy, returns a [TypeMask]
+  /// matching all values with that interceptor (or a subtype thereof).
+  TypeMask getInterceptorSubtypes(ClassElement class_) {
+    if (class_ == helpers.jsInterceptorClass) {
+      return interceptorType.nullable();
+    } else if (class_ == helpers.jsNullClass) {
+      return nullType;
+    } else {
+      return nonNullSubclass(class_);
+    }
+  }
+
   bool areDisjoint(TypeMask leftType, TypeMask rightType) {
     TypeMask intersection = leftType.intersection(rightType, classWorld);
     return intersection.isEmpty && !intersection.isNullable;
@@ -372,8 +448,8 @@
     if (isDefinitelyString(type)) {
       return stringType;
     }
-    if (type.satisfies(backend.typedArrayClass, classWorld)) {
-      if (type.satisfies(backend.typedArrayOfIntClass, classWorld)) {
+    if (type.satisfies(helpers.typedArrayClass, classWorld)) {
+      if (type.satisfies(helpers.typedArrayOfIntClass, classWorld)) {
         return intType;
       }
       return numType;
diff --git a/pkg/compiler/lib/src/cps_ir/type_propagation.dart b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
index 5784d3d..9d1a335 100644
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
@@ -19,6 +19,8 @@
 import '../elements/elements.dart';
 import '../io/source_information.dart' show
     SourceInformation;
+import '../js_backend/backend_helpers.dart' show
+    BackendHelpers;
 import '../js_backend/js_backend.dart' show
     JavaScriptBackend;
 import '../js_backend/codegen/task.dart' show
@@ -142,30 +144,30 @@
         typeSystem.isDefinitelyUint(value.type, allowNull: allowNull);
   }
 
-  bool isDefinitelyNativeList(AbstractValue value,
+  bool isDefinitelyArray(AbstractValue value,
                               {bool allowNull: false}) {
     return value.isNothing ||
-        typeSystem.isDefinitelyNativeList(value.type, allowNull: allowNull);
+        typeSystem.isDefinitelyArray(value.type, allowNull: allowNull);
   }
 
-  bool isDefinitelyMutableNativeList(AbstractValue value,
+  bool isDefinitelyMutableArray(AbstractValue value,
                                      {bool allowNull: false}) {
     return value.isNothing ||
-         typeSystem.isDefinitelyMutableNativeList(value.type,
+         typeSystem.isDefinitelyMutableArray(value.type,
                                                   allowNull: allowNull);
   }
 
-  bool isDefinitelyFixedNativeList(AbstractValue value,
+  bool isDefinitelyFixedArray(AbstractValue value,
                                    {bool allowNull: false}) {
     return value.isNothing ||
-        typeSystem.isDefinitelyFixedNativeList(value.type,
+        typeSystem.isDefinitelyFixedArray(value.type,
                                                allowNull: allowNull);
   }
 
-  bool isDefinitelyExtendableNativeList(AbstractValue value,
+  bool isDefinitelyExtendableArray(AbstractValue value,
                                         {bool allowNull: false}) {
     return value.isNothing ||
-        typeSystem.isDefinitelyExtendableNativeList(value.type,
+        typeSystem.isDefinitelyExtendableArray(value.type,
                                                     allowNull: allowNull);
   }
 
@@ -243,8 +245,15 @@
   ///
   /// This method returns `null` if a good result could not be found. In that
   /// case, it is best to fall back on interprocedural type information.
-  AbstractValue unaryOp(UnaryOperator operator,
-                        AbstractValue value) {
+  AbstractValue unaryOp(UnaryOperator operator, AbstractValue value) {
+    switch (operator.kind) {
+      case UnaryOperatorKind.COMPLEMENT:
+        return bitNotSpecial(value);
+      case UnaryOperatorKind.NEGATE:
+        return negateSpecial(value);
+      default:
+        break;
+    }
     // TODO(asgerf): Also return information about whether this can throw?
     if (value.isNothing) {
       return nothing;
@@ -334,6 +343,27 @@
     return null; // The caller will use return type from type inference.
   }
 
+  AbstractValue foldUnary(UnaryOperation operation, AbstractValue value) {
+    if (value.isNothing) return nothing;
+    if (value.isConstant) {
+      ConstantValue result = operation.fold(value.constant);
+      if (result != null) return constant(result);
+    }
+    return null;
+  }
+
+  AbstractValue bitNotSpecial(AbstractValue value) {
+    return foldUnary(constantSystem.bitNot, value);
+  }
+
+  AbstractValue negateSpecial(AbstractValue value) {
+    AbstractValue folded = foldUnary(constantSystem.negate, value);
+    if (folded != null) return folded;
+    if (isDefinitelyInt(value)) return nonConstant(typeSystem.intType);
+    return null;
+  }
+
+
   AbstractValue foldBinary(BinaryOperation operation,
       AbstractValue left, AbstractValue right) {
     if (left.isNothing || right.isNothing) return nothing;
@@ -492,7 +522,6 @@
     return foldBinary(constantSystem.greaterEqual, left, right);
   }
 
-
   AbstractValue stringConstant(String value) {
     return constant(new StringConstantValue(new ast.DartString.literal(value)));
   }
@@ -637,8 +666,10 @@
   final CpsFunctionCompiler functionCompiler;
 
   JavaScriptBackend get backend => compiler.backend;
+  BackendHelpers get helpers => backend.helpers;
   TypeMaskSystem get typeSystem => lattice.typeSystem;
   types.DartTypes get dartTypes => lattice.dartTypes;
+  World get classWorld => typeSystem.classWorld;
   Map<Variable, ConstantValue> get values => analyzer.values;
 
   final InternalErrorFunction internalError;
@@ -938,17 +969,26 @@
   /// Returns `true` if the node was replaced.
   bool specializeOperatorCall(InvokeMethod node) {
     Continuation cont = node.continuation.definition;
-    bool replaceWithBinary(BuiltinOperator operator,
-                           Primitive left,
-                           Primitive right) {
-      Primitive prim =
-          new ApplyBuiltinOperator(operator, <Primitive>[left, right],
-                                   node.sourceInformation);
+    bool replaceWithPrimitive(Primitive prim) {
       LetPrim let = makeLetPrimInvoke(prim, cont);
       replaceSubtree(node, let);
       push(let);
       return true; // So returning early is more convenient.
     }
+    bool replaceWithBinary(BuiltinOperator operator,
+                           Primitive left,
+                           Primitive right) {
+      return replaceWithPrimitive(
+          new ApplyBuiltinOperator(
+              operator, <Primitive>[left, right], node.sourceInformation));
+    }
+    bool replaceWithUnary(BuiltinOperator operator, Primitive argument) {
+      return replaceWithPrimitive(
+          new ApplyBuiltinOperator(
+              operator, <Primitive>[argument], node.sourceInformation));
+    }
+
+    bool trustPrimitives = compiler.trustPrimitives;
 
     if (node.selector.isOperator && node.arguments.length == 2) {
       Primitive leftArg = getDartReceiver(node);
@@ -971,8 +1011,8 @@
         for (Element target in getAllTargets(left.type, node.selector)) {
           ClassElement clazz = target.enclosingClass.declaration;
           if (clazz != compiler.world.objectClass &&
-              clazz != backend.jsInterceptorClass &&
-              clazz != backend.jsNullClass) {
+              clazz != helpers.jsInterceptorClass &&
+              clazz != helpers.jsNullClass) {
             behavesLikeIdentical = false;
             break;
           }
@@ -982,8 +1022,8 @@
                                    leftArg, rightArg);
         }
       } else {
-        if (lattice.isDefinitelyNum(left, allowNull: false) &&
-            lattice.isDefinitelyNum(right, allowNull: false)) {
+        if (lattice.isDefinitelyNum(left, allowNull: trustPrimitives) &&
+            lattice.isDefinitelyNum(right, allowNull: trustPrimitives)) {
           // Try to insert a numeric operator.
           BuiltinOperator operator = NumBinaryBuiltins[opname];
           if (operator != null) {
@@ -994,7 +1034,7 @@
           // shift count.
           // Try to insert a shift-left operator.
           if (opname == '<<' &&
-              lattice.isDefinitelyInt(left) &&
+              lattice.isDefinitelyInt(left, allowNull: trustPrimitives) &&
               lattice.isDefinitelyIntInRange(right, min: 0, max: 31)) {
             return replaceWithBinary(BuiltinOperator.NumShl, leftArg, rightArg);
           }
@@ -1002,14 +1042,14 @@
           // consistent with Dart's only for left operands in the unsigned
           // 32-bit range.
           if (opname == '>>' &&
-              lattice.isDefinitelyUint32(left) &&
+              lattice.isDefinitelyUint32(left, allowNull: trustPrimitives) &&
               lattice.isDefinitelyIntInRange(right, min: 0, max: 31)) {
             return replaceWithBinary(BuiltinOperator.NumShr, leftArg, rightArg);
           }
           // Try to use remainder for '%'. Both operands must be non-negative
           // and the divisor must be non-zero.
           if (opname == '%' &&
-              lattice.isDefinitelyUint(left) &&
+              lattice.isDefinitelyUint(left, allowNull: trustPrimitives) &&
               lattice.isDefinitelyUint(right) &&
               lattice.isDefinitelyIntInRange(right, min: 1)) {
             return replaceWithBinary(
@@ -1017,21 +1057,35 @@
           }
 
           if (opname == '~/' &&
-              lattice.isDefinitelyUint32(left) &&
+              lattice.isDefinitelyUint32(left, allowNull: trustPrimitives) &&
               lattice.isDefinitelyIntInRange(right, min: 2)) {
             return replaceWithBinary(
                 BuiltinOperator.NumTruncatingDivideToSigned32,
                 leftArg, rightArg);
           }
         }
-        if (lattice.isDefinitelyString(left, allowNull: false) &&
-            lattice.isDefinitelyString(right, allowNull: false) &&
+        if (lattice.isDefinitelyString(left, allowNull: trustPrimitives) &&
+            lattice.isDefinitelyString(right, allowNull: trustPrimitives) &&
             opname == '+') {
           return replaceWithBinary(BuiltinOperator.StringConcatenate,
                                    leftArg, rightArg);
         }
       }
     }
+    if (node.selector.isOperator && node.arguments.length == 1) {
+      Primitive argument = getDartReceiver(node);
+      AbstractValue value = getValue(argument);
+
+      if (lattice.isDefinitelyNum(value, allowNull: false)) {
+        String opname = node.selector.name;
+        if (opname == '~') {
+          return replaceWithUnary(BuiltinOperator.NumBitNot, argument);
+        }
+        if (opname == 'unary-') {
+          return replaceWithUnary(BuiltinOperator.NumNegate, argument);
+        }
+      }
+    }
     if (node.selector.isCall) {
       String name = node.selector.name;
       Primitive receiver = getDartReceiver(node);
@@ -1092,7 +1146,9 @@
     if (target is! FieldElement) return false;
     // TODO(asgerf): Inlining native fields will make some tests pass for the
     // wrong reason, so for testing reasons avoid inlining them.
-    if (target.isNative || target.isJsInterop) return false;
+    if (backend.isNative(target) || backend.isJsInterop(target)) {
+      return false;
+    }
     Continuation cont = node.continuation.definition;
     if (node.selector.isGetter) {
       GetField get = new GetField(getDartReceiver(node), target);
@@ -1125,6 +1181,9 @@
                               Primitive index,
                               SourceInformation sourceInfo) {
     CpsFragment cps = new CpsFragment(sourceInfo);
+    if (compiler.trustPrimitives) {
+      return cps;
+    }
     Continuation fail = cps.letCont();
     Primitive isTooSmall = cps.applyBuiltin(
         BuiltinOperator.NumLt,
@@ -1135,7 +1194,7 @@
         <Primitive>[index, cps.letPrim(new GetLength(list))]);
     cps.ifTruthy(isTooLarge).invokeContinuation(fail);
     cps.insideContinuation(fail).invokeStaticThrower(
-        backend.helpers.throwIndexOutOfBoundsError,
+        helpers.throwIndexOutOfBoundsError,
         <Primitive>[list, index]);
     return cps;
   }
@@ -1153,7 +1212,7 @@
         BuiltinOperator.StrictNeq,
         <Primitive>[originalLength, cps.letPrim(new GetLength(list))]);
     cps.ifTruthy(lengthChanged).invokeStaticThrower(
-        backend.helpers.throwConcurrentModificationError,
+        helpers.throwConcurrentModificationError,
         <Primitive>[list]);
     return cps;
   }
@@ -1190,8 +1249,8 @@
         return true;
 
       case '[]=':
-        if (receiverValue.isNullable) return false;
-        if (!typeSystem.isDefinitelyMutableIndexable(receiverValue.type)) {
+        if (!typeSystem.isDefinitelyMutableIndexable(receiverValue.type,
+                allowNull: true)) {
           return false;
         }
         Primitive index = getDartArgument(node, 0);
@@ -1218,15 +1277,15 @@
     Primitive list = getDartReceiver(node);
     AbstractValue listValue = getValue(list);
     // Ensure that the object is a native list or null.
-    if (!lattice.isDefinitelyNativeList(listValue, allowNull: true)) {
+    if (!lattice.isDefinitelyArray(listValue, allowNull: true)) {
       return false;
     }
     bool isFixedLength =
-        lattice.isDefinitelyFixedNativeList(listValue, allowNull: true);
+        lattice.isDefinitelyFixedArray(listValue, allowNull: true);
     bool isMutable =
-        lattice.isDefinitelyMutableNativeList(listValue, allowNull: true);
+        lattice.isDefinitelyMutableArray(listValue, allowNull: true);
     bool isExtendable =
-        lattice.isDefinitelyExtendableNativeList(listValue, allowNull: true);
+        lattice.isDefinitelyExtendableArray(listValue, allowNull: true);
     SourceInformation sourceInfo = node.sourceInformation;
     Continuation cont = node.continuation.definition;
     switch (node.selector.name) {
@@ -1260,7 +1319,7 @@
             [length, cps.makeZero()]);
         CpsFragment fail = cps.ifTruthy(isEmpty);
         fail.invokeStaticThrower(
-            backend.helpers.throwIndexOutOfBoundsError,
+            helpers.throwIndexOutOfBoundsError,
             [list, fail.makeConstant(new IntConstantValue(-1))]);
         Primitive removedItem = cps.invokeBuiltin(BuiltinMethod.Pop,
             list,
@@ -1718,6 +1777,9 @@
     if (specializeSingleUseClosureCall(node)) return;
     if (specializeClosureCall(node)) return;
 
+    node.mask =
+      typeSystem.intersection(node.mask, getValue(getDartReceiver(node)).type);
+
     AbstractValue receiver = getValue(node.receiver.definition);
 
     if (node.receiverIsIntercepted &&
@@ -1828,6 +1890,11 @@
     // The target might not have an AST, for example if it deferred.
     if (!node.target.hasNode) return false;
 
+    if (node.target.asyncMarker != AsyncMarker.SYNC) {
+      // Inlining of async/sync*/async* methods is currently not supported.
+      return false;
+    }
+
     // True if an expression is non-expansive, in the sense defined by this
     // predicate.
     bool isNonExpansive(ast.Expression expr) {
@@ -2147,38 +2214,155 @@
 
   Primitive visitInterceptor(Interceptor node) {
     AbstractValue value = getValue(node.input.definition);
-    // If the exact class of the input is known, replace with a constant
-    // or the input itself.
-    ClassElement singleClass;
-    if (lattice.isDefinitelyInt(value)) {
-      // Classes like JSUInt31 and JSUInt32 do not exist at runtime, so ensure
-      // all the int classes get mapped tor their runtime class.
-      singleClass = backend.jsIntClass;
-    } else if (lattice.isDefinitelyNativeList(value)) {
-      // Ensure all the array subclasses get mapped to the array class.
-      singleClass = backend.jsArrayClass;
-    } else {
-      singleClass = typeSystem.singleClass(value.type);
-    }
-    if (singleClass != null &&
-        singleClass.isSubclassOf(backend.jsInterceptorClass)) {
-      node.constantValue = new InterceptorConstantValue(singleClass.rawType);
-    }
-    // Filter out intercepted classes that do not match the input type.
-    node.interceptedClasses.retainWhere((ClassElement clazz) {
-      if (clazz == typeSystem.jsNullClass) {
-        return value.isNullable;
-      } else {
-        TypeMask classMask = typeSystem.nonNullSubclass(clazz);
-        return !typeSystem.areDisjoint(value.type, classMask);
+    TypeMask interceptedInputs = value.type.intersection(
+        typeSystem.interceptorType.nullable(), classWorld);
+    bool interceptNull =
+        node.interceptedClasses.contains(helpers.jsNullClass) ||
+        node.interceptedClasses.contains(helpers.jsInterceptorClass);
+
+    void filterInterceptedClasses() {
+      if (lattice.isDefinitelyInt(value, allowNull: !interceptNull)) {
+        node.interceptedClasses..clear()..add(helpers.jsIntClass);
+        return;
       }
-    });
+      if (lattice.isDefinitelyNum(value, allowNull: !interceptNull) &&
+                  jsNumberClassSuffices(node)) {
+        node.interceptedClasses..clear()..add(helpers.jsNumberClass);
+        return;
+      }
+      TypeMask interceptedClassesType = new TypeMask.unionOf(
+          node.interceptedClasses.map(typeSystem.getInterceptorSubtypes),
+          classWorld);
+      TypeMask interceptedAndCaught =
+          interceptedInputs.intersection(interceptedClassesType, classWorld);
+      ClassElement single = interceptedAndCaught.singleClass(classWorld);
+      if (single != null) {
+        node.interceptedClasses..clear()..add(backend.getRuntimeClass(single));
+        return;
+      }
+
+      // Filter out intercepted classes that do not match the input type.
+      node.interceptedClasses.retainWhere((ClassElement clazz) {
+        return !typeSystem.areDisjoint(
+            value.type,
+            typeSystem.getInterceptorSubtypes(clazz));
+      });
+
+      // The interceptor root class will usually not be filtered out because all
+      // intercepted values are subtypes of it.  But it can be "shadowed" by a
+      // more specific interceptor classes if all possible intercepted values
+      // will hit one of the more specific classes.
+      //
+      // For example, if all classes can respond to a given call, but we know
+      // the input is a string or an unknown JavaScript object, we want to
+      // use a specialized interceptor:
+      //
+      //   getInterceptor(x).get$hashCode(x);
+      //     ==>
+      //   getInterceptor$su(x).get$hashCode(x)
+      //
+      // In this case, the intercepted classes that were not filtered out above
+      // are {UnknownJavaScriptObject, JSString, Interceptor}, but there is no
+      // need to include the Interceptor class.
+      //
+      // We only do this optimization if the resulting interceptor call is
+      // sufficiently specialized to be worth it (#classes <= 2).
+      // TODO(asgerf): Reconsider when TypeTest interceptors don't intercept
+      //               ALL interceptor classes.
+      if (node.interceptedClasses.length > 1 &&
+          node.interceptedClasses.length < 4 &&
+          node.interceptedClasses.contains(helpers.jsInterceptorClass)) {
+        TypeMask specificInterceptors = new TypeMask.unionOf(
+            node.interceptedClasses
+              .where((cl) => cl != helpers.jsInterceptorClass)
+              .map(typeSystem.getInterceptorSubtypes),
+            classWorld);
+        if (specificInterceptors.containsMask(interceptedInputs, classWorld)) {
+          // All possible inputs are caught by an Interceptor subclass (or are
+          // self-interceptors), so there is no need to have the check for
+          // the Interceptor root class (which is expensive).
+          node.interceptedClasses.remove(helpers.jsInterceptorClass);
+        }
+      }
+    }
+
+    filterInterceptedClasses();
+
     // Remove the interceptor call if it can only return its input.
     if (node.interceptedClasses.isEmpty) {
       node.input.definition.substituteFor(node);
+      return null;
+    }
+
+    node.flags = Interceptor.ALL_FLAGS;
+
+    // If there is only one caught interceptor class, determine more precisely
+    // how this might resolve at runtime.  Later optimizations depend on this,
+    // but do not have refined type information available.
+    if (node.interceptedClasses.length == 1) {
+      ClassElement class_ = node.interceptedClasses.single;
+      if (value.isDefinitelyNotNull) {
+        node.clearFlag(Interceptor.NULL);
+      } else if (interceptNull) {
+        node.clearFlag(Interceptor.NULL_BYPASS);
+        if (class_ == helpers.jsNullClass) {
+          node.clearFlag(Interceptor.NULL_INTERCEPT_SUBCLASS);
+        } else {
+          node.clearFlag(Interceptor.NULL_INTERCEPT_EXACT);
+        }
+      } else {
+        node.clearFlag(Interceptor.NULL_INTERCEPT);
+      }
+      if (typeSystem.isDefinitelyIntercepted(value.type, allowNull: true)) {
+        node.clearFlag(Interceptor.SELF_INTERCEPT);
+      }
+      TypeMask interceptedInputsNonNullable = interceptedInputs.nonNullable();
+      TypeMask interceptedType = typeSystem.getInterceptorSubtypes(class_);
+      if (interceptedType.containsMask(interceptedInputsNonNullable,
+              classWorld)) {
+        node.clearFlag(Interceptor.NON_NULL_BYPASS);
+      }
+      if (class_ == helpers.jsNumberClass) {
+        // See [jsNumberClassSuffices].  We know that JSInt and JSDouble are
+        // not intercepted classes so JSNumber is sufficient.
+        node.clearFlag(Interceptor.NON_NULL_INTERCEPT_SUBCLASS);
+      } else if (class_ == helpers.jsArrayClass) {
+        // JSArray has compile-time subclasses like JSFixedArray, but should
+        // still be considered "exact" if the input is any subclass of JSArray.
+        if (typeSystem.isDefinitelyArray(interceptedInputsNonNullable)) {
+          node.clearFlag(Interceptor.NON_NULL_INTERCEPT_SUBCLASS);
+        }
+      } else {
+        TypeMask exactInterceptedType = typeSystem.nonNullExact(class_);
+        if (exactInterceptedType.containsMask(interceptedInputsNonNullable,
+                classWorld)) {
+          node.clearFlag(Interceptor.NON_NULL_INTERCEPT_SUBCLASS);
+        }
+      }
     }
     return null;
   }
+
+  bool jsNumberClassSuffices(Interceptor node) {
+    // No methods on JSNumber call 'down' to methods on JSInt or JSDouble.  If
+    // all uses of the interceptor are for methods is defined only on JSNumber
+    // then JSNumber will suffice in place of choosing between JSInt or
+    // JSDouble.
+    for (Reference ref = node.firstRef; ref != null; ref = ref.next) {
+      if (ref.parent is InvokeMethod) {
+        InvokeMethod invoke = ref.parent;
+        if (invoke.receiver != ref) return false;
+        var interceptedClasses =
+            functionCompiler.glue.getInterceptedClassesOn(invoke.selector);
+        if (interceptedClasses.contains(helpers.jsDoubleClass)) return false;
+        if (interceptedClasses.contains(helpers.jsIntClass)) return false;
+        continue;
+      }
+      // Other uses need full distinction.
+      return false;
+    }
+    return true;
+  }
 }
 
 /**
@@ -2210,6 +2394,8 @@
 
   JavaScriptBackend get backend => typeSystem.backend;
 
+  dart2js.Compiler get compiler => backend.compiler;
+
   World get classWorld => typeSystem.classWorld;
 
   AbstractValue get nothing => lattice.nothing;
@@ -2447,6 +2633,19 @@
     if (receiver.isNothing) {
       return;  // And come back later.
     }
+
+    // Constant fold known length of containers.
+    if (node.selector == Selectors.length) {
+      AbstractValue object = getValue(getDartReceiver(node));
+      if (typeSystem.isDefinitelyIndexable(object.type, allowNull: true)) {
+        int length = typeSystem.getContainerLength(object.type.nonNullable());
+        if (length != null) {
+          setResult(node, constantValue(new IntConstantValue(length)),
+              canReplace: !object.isNullable);
+        }
+      }
+    }
+
     if (!node.selector.isOperator) {
       // TODO(jgruber): Handle known methods on constants such as String.length.
       setResult(node, lattice.getInvokeReturnType(node.selector, node.mask));
@@ -2483,6 +2682,12 @@
 
   void visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
 
+    void unaryOp(AbstractValue operation(AbstractValue argument),
+                 TypeMask defaultType) {
+      AbstractValue value = getValue(node.arguments[0].definition);
+      setValue(node, operation(value) ?? nonConstant(defaultType));
+    }
+
     void binaryOp(
         AbstractValue operation(AbstractValue left, AbstractValue right),
         TypeMask defaultType) {
@@ -2624,6 +2829,14 @@
         binaryBoolOp(lattice.greaterEqualSpecial);
         break;
 
+      case BuiltinOperator.NumBitNot:
+        unaryOp(lattice.bitNotSpecial, typeSystem.uint32Type);
+        break;
+
+      case BuiltinOperator.NumNegate:
+        unaryOp(lattice.negateSpecial, typeSystem.numType);
+        break;
+
       case BuiltinOperator.StrictNeq:
       case BuiltinOperator.LooseNeq:
       case BuiltinOperator.IsFalsy:
@@ -2659,7 +2872,11 @@
   }
 
   void visitInvokeConstructor(InvokeConstructor node) {
-    setResult(node, nonConstant(typeSystem.getReturnType(node.target)));
+    if (node.allocationSiteType != null) {
+      setResult(node, nonConstant(node.allocationSiteType));
+    } else {
+      setResult(node, nonConstant(typeSystem.getReturnType(node.target)));
+    }
   }
 
   void visitThrow(Throw node) {
@@ -2744,7 +2961,7 @@
         setReachable(cont);
         // Narrow type of output to those that survive the cast.
         TypeMask type = input.type.intersection(
-            typeSystem.subtypesOf(node.dartType),
+            typeSystem.subtypesOf(node.dartType).nullable(),
             classWorld);
         setValue(cont.parameters.single, nonConstant(type));
         break;
@@ -2756,9 +2973,11 @@
   }
 
   void visitLiteralList(LiteralList node) {
-    // Constant lists are translated into (Constant ListConstant(...)) IR nodes,
-    // and thus LiteralList nodes are NonConst.
-    setValue(node, nonConstant(typeSystem.extendableNativeListType));
+    if (node.allocationSiteType != null) {
+      setValue(node, nonConstant(node.allocationSiteType));
+    } else {
+      setValue(node, nonConstant(typeSystem.extendableArrayType));
+    }
   }
 
   void visitLiteralMap(LiteralMap node) {
@@ -2819,7 +3038,7 @@
     if (value.isNothing) {
       setValue(node, nothing);
     } else if (value.isNullable &&
-        !node.interceptedClasses.contains(backend.jsNullClass)) {
+        !node.interceptedClasses.contains(backend.helpers.jsNullClass)) {
       // If the input is null and null is not mapped to an interceptor then
       // null gets returned.
       // TODO(asgerf): Add the NullInterceptor when it enables us to
@@ -2832,7 +3051,7 @@
 
   void visitGetField(GetField node) {
     node.objectIsNotNull = getValue(node.object.definition).isDefinitelyNotNull;
-    setValue(node, nonConstant(typeSystem.getFieldType(node.field)));
+    setValue(node, lattice.fromMask(typeSystem.getFieldType(node.field)));
   }
 
   void visitSetField(SetField node) {}
@@ -2884,7 +3103,7 @@
       // own bounds-check elimination?
       setValue(node, constantValue(new IntConstantValue(length)));
     } else {
-      setValue(node, nonConstant(typeSystem.intType));
+      setValue(node, nonConstant(typeSystem.uint32Type));
     }
   }
 
@@ -2969,6 +3188,7 @@
   bool get isNonConst => (kind == NONCONST);
   bool get isNullConstant => kind == CONSTANT && constant.isNull;
   bool get isTrueConstant => kind == CONSTANT && constant.isTrue;
+  bool get isFalseConstant => kind == CONSTANT && constant.isFalse;
 
   bool get isNullable => kind != NOTHING && type.isNullable;
   bool get isDefinitelyNotNull => kind == NOTHING || !type.isNullable;
diff --git a/pkg/compiler/lib/src/dart_backend/backend.dart b/pkg/compiler/lib/src/dart_backend/backend.dart
index 5001b54..7d99b21 100644
--- a/pkg/compiler/lib/src/dart_backend/backend.dart
+++ b/pkg/compiler/lib/src/dart_backend/backend.dart
@@ -42,7 +42,7 @@
 
   DartConstantTask constantCompilerTask;
 
-  DartResolutionCallbacks resolutionCallbacks;
+  DartImpactTransformer impactTransformer;
 
   final Set<ClassElement> usedTypeLiterals = new Set<ClassElement>();
 
@@ -113,7 +113,7 @@
             multiFile: multiFile,
             enableMinification: compiler.enableMinification),
         super(compiler) {
-    resolutionCallbacks = new DartResolutionCallbacks(this);
+    impactTransformer = new DartImpactTransformer(this);
   }
 
 
@@ -137,16 +137,18 @@
     }
     // Enqueue the methods that the VM might invoke on user objects because
     // we don't trust the resolution to always get these included.
-    world.registerInvocation(new UniverseSelector(Selectors.toString_, null));
-    world.registerInvokedGetter(
-        new UniverseSelector(Selectors.hashCode_, null));
-    world.registerInvocation(
-        new UniverseSelector(new Selector.binaryOperator('=='), null));
-    world.registerInvocation(
-        new UniverseSelector(Selectors.compareTo, null));
+    world.registerDynamicUse(new DynamicUse(Selectors.toString_, null));
+    world.registerDynamicUse(
+        new DynamicUse(Selectors.hashCode_, null));
+    world.registerDynamicUse(
+        new DynamicUse(new Selector.binaryOperator('=='), null));
+    world.registerDynamicUse(
+        new DynamicUse(Selectors.compareTo, null));
   }
 
-  WorldImpact codegen(CodegenWorkItem work) => const WorldImpact();
+  WorldImpact codegen(CodegenWorkItem work) {
+    return const WorldImpact();
+  }
 
   /**
    * Tells whether we should output given element. Corelib classes like
@@ -263,10 +265,7 @@
                                 Enqueuer enqueuer,
                                 Registry registry,
                                 {bool mirrorUsage: false}) {
-    registerPlatformMembers(type,
-        registerGetter: registry.registerDynamicGetter,
-        registerSetter: registry.registerDynamicSetter,
-        registerInvocation: registry.registerDynamicInvocation);
+    registerPlatformMembers(type, registerUse: registry.registerDynamicUse);
     super.registerInstantiatedType(
         type, enqueuer, registry, mirrorUsage: mirrorUsage);
   }
@@ -275,9 +274,7 @@
   /// of types defined in the platform libraries.
   void registerPlatformMembers(
       InterfaceType type,
-      {void registerGetter(UniverseSelector selector),
-       void registerSetter(UniverseSelector selector),
-       void registerInvocation(UniverseSelector selector)}) {
+      {void registerUse(DynamicUse dynamicUse)}) {
 
     // Without patching, dart2dart has no way of performing sound tree-shaking
     // in face external functions. Therefore we employ another scheme:
@@ -329,16 +326,8 @@
               FunctionElement function = element.asFunctionElement();
               element.computeType(resolution);
               Selector selector = new Selector.fromElement(element);
-              if (selector.isGetter) {
-                registerGetter(
-                    new UniverseSelector(selector, null));
-              } else if (selector.isSetter) {
-                registerSetter(
-                    new UniverseSelector(selector, null));
-              } else {
-                registerInvocation(
-                    new UniverseSelector(selector, null));
-              }
+              registerUse(
+                  new DynamicUse(selector, null));
             });
           }
         }
@@ -353,30 +342,32 @@
         node, MessageKind.DEFERRED_LIBRARY_DART_2_DART);
     return false;
   }
-}
-
-class DartResolutionCallbacks extends ResolutionCallbacks {
-  final DartBackend backend;
-
-  DartResolutionCallbacks(this.backend);
 
   @override
-  WorldImpact transformImpact(ResolutionImpact worldImpact) {
+  Uri resolvePatchUri(String libraryName, Uri) {
+    // Dart2dart does not use patches.
+    return null;
+  }
+}
+
+class DartImpactTransformer extends ImpactTransformer {
+  final DartBackend backend;
+
+  DartImpactTransformer(this.backend);
+
+  @override
+  WorldImpact transformResolutionImpact(ResolutionImpact worldImpact) {
     TransformedWorldImpact transformed =
         new TransformedWorldImpact(worldImpact);
-    for (DartType typeLiteral in worldImpact.typeLiterals) {
-      if (typeLiteral.isInterfaceType) {
-        backend.usedTypeLiterals.add(typeLiteral.element);
+    for (TypeUse typeUse in worldImpact.typeUses) {
+      if (typeUse.kind == TypeUseKind.TYPE_LITERAL &&
+          typeUse.type.isInterfaceType) {
+        backend.usedTypeLiterals.add(typeUse.type.element);
       }
-    }
-    for (InterfaceType instantiatedType in worldImpact.instantiatedTypes) {
-      // TODO(johnniwinther): Remove this when dependency tracking is done on
-      // the world impact itself.
-      transformed.registerInstantiatedType(instantiatedType);
-      backend.registerPlatformMembers(instantiatedType,
-          registerGetter: transformed.registerDynamicGetter,
-          registerSetter: transformed.registerDynamicSetter,
-          registerInvocation: transformed.registerDynamicInvocation);
+      if (typeUse.kind == TypeUseKind.INSTANTIATION) {
+        backend.registerPlatformMembers(typeUse.type,
+            registerUse: transformed.registerDynamicUse);
+      }
     }
     return transformed;
   }
diff --git a/pkg/compiler/lib/src/dart_backend/dart_backend.dart b/pkg/compiler/lib/src/dart_backend/dart_backend.dart
index 57b7af5..ee653f0 100644
--- a/pkg/compiler/lib/src/dart_backend/dart_backend.dart
+++ b/pkg/compiler/lib/src/dart_backend/dart_backend.dart
@@ -11,7 +11,8 @@
     CompilerOutputProvider;
 import '../common.dart';
 import '../common/backend_api.dart' show
-    Backend;
+    Backend,
+    ImpactTransformer;
 import '../common/codegen.dart' show
     CodegenWorkItem;
 import '../common/names.dart' show
@@ -21,9 +22,7 @@
     Registry;
 import '../common/resolution.dart' show
     Resolution,
-    ResolutionCallbacks,
-    ResolutionImpact,
-    TransformedWorldImpact;
+    ResolutionImpact;
 import '../common/tasks.dart' show
     CompilerTask;
 import '../compiler.dart' show
@@ -36,8 +35,7 @@
 import '../elements/elements.dart';
 import '../enqueue.dart' show
     Enqueuer,
-    ResolutionEnqueuer,
-    WorldImpact;
+    ResolutionEnqueuer;
 import '../library_loader.dart' show
     LoadedLibraries;
 import '../mirror_renamer/mirror_renamer.dart';
@@ -49,8 +47,13 @@
 import '../tree/tree.dart';
 import '../universe/selector.dart' show
     Selector;
-import '../universe/universe.dart' show
-    UniverseSelector;
+import '../universe/use.dart' show
+    DynamicUse,
+    TypeUse,
+    TypeUseKind;
+import '../universe/world_impact.dart' show
+    WorldImpact,
+    TransformedWorldImpact;
 import '../util/util.dart';
 import 'backend_ast_to_frontend_ast.dart' as backend2frontend;
 
diff --git a/pkg/compiler/lib/src/dart_backend/placeholder_collector.dart b/pkg/compiler/lib/src/dart_backend/placeholder_collector.dart
index 42c15f9..0a2d0e1 100644
--- a/pkg/compiler/lib/src/dart_backend/placeholder_collector.dart
+++ b/pkg/compiler/lib/src/dart_backend/placeholder_collector.dart
@@ -97,7 +97,7 @@
 
   visitDynamicSend(Send node) {
     final element = elements[node];
-    if (element == null || !element.isErroneous) {
+    if (element == null || !element.isMalformed) {
       collector.tryMakeMemberPlaceholder(node.selector);
     }
   }
@@ -107,7 +107,7 @@
     // element == null means dynamic property access.
     if (element == null) {
       collector.tryMakeMemberPlaceholder(node.selector);
-    } else if (element.isErroneous) {
+    } else if (element.isMalformed) {
       collector.makeUnresolvedPlaceholder(node);
       return;
     } else if (element.isPrefix) {
@@ -489,7 +489,7 @@
     Element constructor = treeElements[send];
     assert(constructor != null);
     assert(send.receiver == null);
-    if (!Elements.isErroneous(constructor)) {
+    if (!Elements.isMalformed(constructor)) {
       tryMakeConstructorPlaceholder(node.send.selector, constructor);
       // TODO(smok): Should this be in visitNamedArgument?
       // Field names can be exposed as names of optional arguments, e.g.
@@ -530,7 +530,7 @@
 
   visitSendSet(SendSet send) {
     Element element = treeElements[send];
-    if (Elements.isErroneous(element)) {
+    if (Elements.isMalformed(element)) {
       // Complicated case: constructs like receiver.selector++ can resolve
       // to ErroneousElement.  Fortunately, receiver.selector still
       // can be resoved via treeElements[send.selector], that's all
@@ -540,7 +540,7 @@
     tryMakePrivateIdentifier(send.selector, element);
     if (element == null) {
       if (send.receiver != null) tryMakeMemberPlaceholder(send.selector);
-    } else if (!element.isErroneous) {
+    } else if (!element.isMalformed) {
       if (Elements.isStaticOrTopLevel(element)) {
         // TODO(smok): Worth investigating why sometimes we get getter/setter
         // here and sometimes abstract field.
diff --git a/pkg/compiler/lib/src/dart_backend/renamer.dart b/pkg/compiler/lib/src/dart_backend/renamer.dart
index 02f9365..6465af8 100644
--- a/pkg/compiler/lib/src/dart_backend/renamer.dart
+++ b/pkg/compiler/lib/src/dart_backend/renamer.dart
@@ -135,7 +135,7 @@
 
   String _renameGlobal(Entity entity) {
     assert(entity is! Element ||
-           Elements.isErroneous(entity) ||
+           Elements.isMalformed(entity) ||
            Elements.isStaticOrTopLevel(entity) ||
            entity is TypeVariableElement);
     // TODO(smok): We may want to reuse class static field and method names.
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index 4e095df..78c0a37 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -32,8 +32,6 @@
     PrefixElement,
     ScopeContainerElement,
     TypedefElement;
-import 'enqueue.dart' show
-    WorldImpact;
 import 'js_backend/js_backend.dart' show
     JavaScriptBackend;
 import 'resolution/resolution.dart' show
@@ -49,6 +47,12 @@
     LiteralString,
     NewExpression,
     Node;
+import 'universe/use.dart' show
+    StaticUse,
+    TypeUse,
+    TypeUseKind;
+import 'universe/world_impact.dart' show
+    WorldImpact;
 import 'util/setlet.dart' show
     Setlet;
 import 'util/uri_extras.dart' as uri_extras;
@@ -74,7 +78,6 @@
   final bool isMainOutput;
 
   /// A unique name representing this [OutputUnit].
-  /// Based on the set of [imports].
   String name;
 
   OutputUnit({this.isMainOutput: false});
@@ -128,7 +131,10 @@
   /// can be loaded in parallel. And finally lib1 can be loaded.
   final Map<String, List<OutputUnit>> hunksToLoad =
       new Map<String, List<OutputUnit>>();
-  final Map<_DeferredImport, String> _importDeferName =
+
+  /// A cache of the result of calling `computeImportDeferName` on the keys of
+  /// this map.
+  final Map<_DeferredImport, String> importDeferName =
       <_DeferredImport, String>{};
 
   /// A mapping from elements and constants to their output unit. Query this via
@@ -149,7 +155,7 @@
 
   /// Because the token-stream is forgotten later in the program, we cache a
   /// description of each deferred import.
-  final Map<_DeferredImport, ImportDescription>_deferredImportDescriptions =
+  final Map<_DeferredImport, ImportDescription> _deferredImportDescriptions =
       <_DeferredImport, ImportDescription>{};
 
   // For each deferred import we want to know exactly what elements have to
@@ -198,7 +204,7 @@
   /// Returns the unique name for the deferred import of [prefix].
   String getImportDeferName(Spannable node, PrefixElement prefix) {
     String name =
-        _importDeferName[new _DeclaredDeferredImport(prefix.deferredImport)];
+        importDeferName[new _DeclaredDeferredImport(prefix.deferredImport)];
     if (name == null) {
       reporter.internalError(node, "No deferred name for $prefix.");
     }
@@ -259,8 +265,8 @@
       Set<ConstantValue> constants,
       isMirrorUsage) {
 
-    if (element.isErroneous) {
-      // Erroneous elements are ignored.
+    if (element.isMalformed) {
+      // Malformed elements are ignored.
       return;
     }
 
@@ -312,24 +318,34 @@
 
         WorldImpact worldImpact =
             compiler.resolution.getWorldImpact(analyzableElement);
-        elements.addAll(worldImpact.staticUses);
-        elements.addAll(worldImpact.closures);
-        for (DartType type in worldImpact.typeLiterals) {
-          if (type.isTypedef || type.isInterfaceType) {
-            elements.add(type.element);
+        worldImpact.staticUses.forEach((StaticUse staticUse) {
+          elements.add(staticUse.element);
+        });
+        for (TypeUse typeUse in worldImpact.typeUses) {
+          DartType type = typeUse.type;
+          switch (typeUse.kind) {
+            case TypeUseKind.TYPE_LITERAL:
+              if (type.isTypedef || type.isInterfaceType) {
+                elements.add(type.element);
+              }
+              break;
+            case TypeUseKind.INSTANTIATION:
+            case TypeUseKind.IS_CHECK:
+            case TypeUseKind.AS_CAST:
+            case TypeUseKind.CATCH_TYPE:
+              collectTypeDependencies(type);
+              break;
+            case TypeUseKind.CHECKED_MODE_CHECK:
+              if (compiler.enableTypeAssertions) {
+                collectTypeDependencies(type);
+              }
+              break;
           }
         }
-        for (InterfaceType type in worldImpact.instantiatedTypes) {
-          elements.add(type.element);
-        }
 
         TreeElements treeElements = analyzableElement.resolvedAst.elements;
         assert(treeElements != null);
 
-        for (DartType type in treeElements.requiredTypes) {
-          collectTypeDependencies(type);
-        }
-
         treeElements.forEachConstantNode((Node node, _) {
           // Explicitly depend on the backend constants.
           ConstantValue value =
@@ -557,7 +573,7 @@
     void computeImportDeferName(_DeferredImport import) {
       String result = import.computeImportDeferName(compiler);
       assert(result != null);
-      _importDeferName[import] = makeUnique(result, usedImportNames);
+      importDeferName[import] = makeUnique(result, usedImportNames);
     }
 
     int counter = 1;
@@ -579,25 +595,25 @@
     // Sort the output units in descending order of the number of imports they
     // include.
 
-    // The loading of the output units mut be ordered because a superclass needs
-    // to be initialized before its subclass.
+    // The loading of the output units must be ordered because a superclass
+    // needs to be initialized before its subclass.
     // But a class can only depend on another class in an output unit shared by
     // a strict superset of the imports:
     // By contradiction: Assume a class C in output unit shared by imports in
     // the set S1 = (lib1,.., lib_n) depends on a class D in an output unit
     // shared by S2 such that S2 not a superset of S1. Let lib_s be a library in
-    // S1 not in S2. lib_s must depend on C, and then in turn on D therefore D
+    // S1 not in S2. lib_s must depend on C, and then in turn on D. Therefore D
     // is not in the right output unit.
     sortedOutputUnits.sort((a, b) => b.imports.length - a.imports.length);
 
     // For each deferred import we find out which outputUnits to load.
     for (_DeferredImport import in _allDeferredImports.keys) {
       if (import == _fakeMainImport) continue;
-      hunksToLoad[_importDeferName[import]] = new List<OutputUnit>();
+      hunksToLoad[importDeferName[import]] = new List<OutputUnit>();
       for (OutputUnit outputUnit in sortedOutputUnits) {
         if (outputUnit == mainOutputUnit) continue;
         if (outputUnit.imports.contains(import)) {
-          hunksToLoad[_importDeferName[import]].add(outputUnit);
+          hunksToLoad[importDeferName[import]].add(outputUnit);
         }
       }
     }
@@ -620,7 +636,7 @@
       _mapDependencies(element: compiler.mainFunction, import: _fakeMainImport);
 
       // Also add "global" dependencies to the main OutputUnit.  These are
-      // things that the backend need but cannot associate with a particular
+      // things that the backend needs but cannot associate with a particular
       // element, for example, startRootIsolate.  This set also contains
       // elements for which we lack precise information.
       for (Element element in compiler.globalDependencies.otherDependencies) {
@@ -850,8 +866,8 @@
   /// Where
   ///
   /// - <library uri> is the relative uri of the library making a deferred
-  ///   import
-  /// - <library name> is the name of the libary, and "<unnamed>" if it is
+  ///   import.
+  /// - <library name> is the name of the library, and "<unnamed>" if it is
   ///   unnamed.
   /// - <prefix> is the `as` prefix used for a given deferred import.
   /// - <list of files> is a list of the filenames the must be loaded when that
@@ -861,14 +877,14 @@
     Map<String, Map<String, dynamic>> mapping =
         new Map<String, Map<String, dynamic>>();
     _deferredImportDescriptions.keys.forEach((_DeferredImport import) {
-      List<OutputUnit> outputUnits = hunksToLoad[_importDeferName[import]];
+      List<OutputUnit> outputUnits = hunksToLoad[importDeferName[import]];
       ImportDescription description = _deferredImportDescriptions[import];
       Map<String, dynamic> libraryMap =
           mapping.putIfAbsent(description.importingUri,
               () => <String, dynamic>{"name": description.importingLibraryName,
                                       "imports": <String, List<String>>{}});
 
-      libraryMap["imports"][description.prefix] = outputUnits.map(
+      libraryMap["imports"][importDeferName[import]] = outputUnits.map(
             (OutputUnit outputUnit) {
           return backend.deferredPartFileName(outputUnit.name);
         }).toList();
diff --git a/pkg/compiler/lib/src/diagnostics/messages.dart b/pkg/compiler/lib/src/diagnostics/messages.dart
index 900ef01..5913cb0 100644
--- a/pkg/compiler/lib/src/diagnostics/messages.dart
+++ b/pkg/compiler/lib/src/diagnostics/messages.dart
@@ -107,6 +107,7 @@
   CANNOT_EXTEND_ENUM,
   CANNOT_EXTEND_MALFORMED,
   CANNOT_FIND_CONSTRUCTOR,
+  CANNOT_FIND_UNNAMED_CONSTRUCTOR,
   CANNOT_IMPLEMENT,
   CANNOT_IMPLEMENT_ENUM,
   CANNOT_IMPLEMENT_MALFORMED,
@@ -237,6 +238,7 @@
   INHERITED_EXPLICIT_GETTER,
   INHERITED_IMPLICIT_GETTER,
   INHERITED_METHOD,
+  INJECTED_PUBLIC_MEMBER,
   INIT_STATIC_FIELD,
   INITIALIZING_FORMAL_NOT_ALLOWED,
   INSTANCE_STATIC_SAME_NAME,
@@ -279,6 +281,7 @@
   JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER,
   JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS,
   JS_INTEROP_METHOD_WITH_NAMED_ARGUMENTS,
+  JS_PLACEHOLDER_CAPTURE,
   LIBRARY_NAME_MISMATCH,
   LIBRARY_NOT_FOUND,
   LIBRARY_NOT_SUPPORTED,
@@ -402,12 +405,14 @@
   SETTER_NOT_FOUND_IN_SUPER,
   STATIC_FUNCTION_BLOAT,
   STRING_EXPECTED,
+  SUPER_CALL_TO_FACTORY,
   SUPER_INITIALIZER_IN_OBJECT,
   SWITCH_CASE_FORBIDDEN,
   SWITCH_CASE_TYPES_NOT_EQUAL,
   SWITCH_CASE_TYPES_NOT_EQUAL_CASE,
   SWITCH_CASE_VALUE_OVERRIDES_EQUALS,
   TERNARY_OPERATOR_BAD_ARITY,
+  THIS_CALL_TO_FACTORY,
   THIS_IS_THE_DECLARATION,
   THIS_IS_THE_METHOD,
   THIS_IS_THE_PART_OF_TAG,
@@ -895,7 +900,13 @@
 
       MessageKind.CANNOT_FIND_CONSTRUCTOR:
         const MessageTemplate(MessageKind.CANNOT_FIND_CONSTRUCTOR,
-          "Cannot find constructor '#{constructorName}'."),
+          "Cannot find constructor '#{constructorName}' in class "
+          "'#{className}'."),
+
+      MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR:
+        const MessageTemplate(MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR,
+          "Cannot find unnamed constructor in class "
+          "'#{className}'."),
 
       MessageKind.CYCLIC_CLASS_HIERARCHY:
         const MessageTemplate(MessageKind.CYCLIC_CLASS_HIERARCHY,
@@ -977,6 +988,62 @@
         const MessageTemplate(MessageKind.DUPLICATE_SUPER_INITIALIZER,
           "Cannot have more than one super initializer."),
 
+      MessageKind.SUPER_CALL_TO_FACTORY:
+        const MessageTemplate(MessageKind.SUPER_CALL_TO_FACTORY,
+          "The target of the superinitializer must be a generative "
+          "constructor.",
+          howToFix: "Try calling another constructor on the superclass.",
+          examples: const ["""
+class Super {
+  factory Super() => null;
+}
+class Class extends Super {}
+main() => new Class();
+""", """
+class Super {
+  factory Super() => null;
+}
+class Class extends Super {
+  Class();
+}
+main() => new Class();
+""", """
+class Super {
+  factory Super() => null;
+}
+class Class extends Super {
+  Class() : super();
+}
+main() => new Class();
+""", """
+class Super {
+  factory Super.foo() => null;
+}
+class Class extends Super {
+  Class() : super.foo();
+}
+main() => new Class();
+"""]),
+
+      MessageKind.THIS_CALL_TO_FACTORY:
+        const MessageTemplate(MessageKind.THIS_CALL_TO_FACTORY,
+          "The target of the redirection clause must be a generative "
+          "constructor",
+        howToFix: "Try redirecting to another constructor.",
+        examples: const ["""
+class Class {
+  factory Class() => null;
+  Class.foo() : this();
+}
+main() => new Class.foo();
+""", """
+class Class {
+  factory Class.foo() => null;
+  Class() : this.foo();
+}
+main() => new Class();
+"""]),
+
       MessageKind.INVALID_CONSTRUCTOR_ARGUMENTS:
         const MessageTemplate(MessageKind.INVALID_CONSTRUCTOR_ARGUMENTS,
           "Arguments do not match the expected parameters of constructor "
@@ -2502,6 +2569,14 @@
               "Try adding '@MirrorsUsed(...)' as described at "
               "https://goo.gl/Akrrog."),
 
+      MessageKind.JS_PLACEHOLDER_CAPTURE:
+        const MessageTemplate(
+            MessageKind.JS_PLACEHOLDER_CAPTURE,
+            "JS code must not use '#' placeholders inside functions.",
+            howToFix:
+            "Use an immediately called JavaScript function to capture the"
+            " the placeholder values as JavaScript function parameters."),
+
       MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT:
         const MessageTemplate(
           MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT,
@@ -3376,6 +3451,10 @@
           "Cannot patch non-function with function patch "
           "'#{functionName}'."),
 
+      MessageKind.INJECTED_PUBLIC_MEMBER:
+        const MessageTemplate(MessageKind.INJECTED_PUBLIC_MEMBER,
+            "Non-patch members in patch libraries must be private."),
+
       MessageKind.EXTERNAL_WITH_BODY:
         const MessageTemplate(MessageKind.EXTERNAL_WITH_BODY,
           "External function '#{functionName}' cannot have a function body.",
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index 22fa2f0..09ab8e5 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -10,24 +10,18 @@
 import 'package:dart2js_info/info.dart';
 
 import 'common.dart';
-import 'common/tasks.dart' show
-    CompilerTask;
-import 'constants/values.dart' show ConstantValue;
-import 'compiler.dart' show
-    Compiler;
+import 'common/tasks.dart' show CompilerTask;
+import 'constants/values.dart' show ConstantValue, InterceptorConstantValue;
+import 'compiler.dart' show Compiler;
 import 'elements/elements.dart';
 import 'elements/visitor.dart';
-import 'types/types.dart' show
-    TypeMask;
-import 'deferred_load.dart' show
-    OutputUnit;
-import 'js_backend/js_backend.dart' show
-    JavaScriptBackend;
-import 'js_emitter/full_emitter/emitter.dart' as full show
-    Emitter;
+import 'types/types.dart' show TypeMask;
+import 'deferred_load.dart' show OutputUnit;
+import 'js_backend/js_backend.dart' show JavaScriptBackend;
+import 'js_emitter/full_emitter/emitter.dart' as full show Emitter;
 import 'js/js.dart' as jsAst;
-import 'universe/universe.dart' show
-    UniverseSelector;
+import 'universe/universe.dart' show ReceiverConstraint;
+import 'universe/world_impact.dart' show WorldImpact;
 import 'info/send_info.dart' show collectSendMeasurements;
 
 class ElementInfoCollector extends BaseElementVisitor<Info, dynamic> {
@@ -45,10 +39,10 @@
       // TODO(sigmund): add dependencies on other constants
       var size = compiler.dumpInfoTask._nodeToSize[node];
       var code = jsAst.prettyPrint(node, compiler).getText();
-      var info = new ConstantInfo(size: size, code: code);
+      var info = new ConstantInfo(
+          size: size, code: code, outputUnit: _unitInfoForConstant(constant));
       _constantToInfo[constant] = info;
       result.constants.add(info);
-
     });
     compiler.libraryLoader.libraries.forEach(visit);
   }
@@ -58,10 +52,10 @@
   /// Whether to emit information about [element].
   ///
   /// By default we emit information for any element that contributes to the
-  /// output size. Either becuase the it is a function being emitted or inlined,
+  /// output size. Either because the it is a function being emitted or inlined,
   /// or because it is an element that holds dependencies to other elements.
   bool shouldKeep(Element element) {
-    return compiler.dumpInfoTask.selectorsFromElement.containsKey(element) ||
+    return compiler.dumpInfoTask.impacts.containsKey(element) ||
         compiler.dumpInfoTask.inlineCount.containsKey(element);
   }
 
@@ -82,7 +76,7 @@
     String libname = element.hasLibraryName ? element.libraryName : "<unnamed>";
     int size = compiler.dumpInfoTask.sizeOf(element);
     LibraryInfo info =
-      new LibraryInfo(libname, element.canonicalUri, null, size);
+        new LibraryInfo(libname, element.canonicalUri, null, size);
     _elementToInfo[element] = info;
 
     LibraryElement realElement = element.isPatched ? element.patch : element;
@@ -113,8 +107,8 @@
 
   TypedefInfo visitTypedefElement(TypedefElement element, _) {
     if (!element.isResolved) return null;
-    TypedefInfo info = new TypedefInfo(element.name, '${element.alias}',
-        _unitInfoForElement(element));
+    TypedefInfo info = new TypedefInfo(
+        element.name, '${element.alias}', _unitInfoForElement(element));
     _elementToInfo[element] = info;
     result.typedefs.add(info);
     return info;
@@ -284,6 +278,7 @@
 
     FunctionInfo info = new FunctionInfo(
         name: name,
+        functionKind: kind,
         // We use element.hashCode because it is globally unique and it is
         // available while we are doing codegen.
         coverageId: '${element.hashCode}',
@@ -323,9 +318,7 @@
     return info;
   }
 
-  OutputUnitInfo _unitInfoForElement(Element element) {
-    OutputUnit outputUnit =
-      compiler.deferredLoadTask.outputUnitForElement(element);
+  OutputUnitInfo _infoFromOutputUnit(OutputUnit outputUnit) {
     return _outputToInfo.putIfAbsent(outputUnit, () {
       // Dump-info currently only works with the full emitter. If another
       // emitter is used it will fail here.
@@ -333,15 +326,32 @@
       full.Emitter emitter = backend.emitter.emitter;
       OutputUnitInfo info = new OutputUnitInfo(
           outputUnit.name, emitter.outputBuffers[outputUnit].length);
+      info.imports.addAll(outputUnit.imports
+          .map((d) => compiler.deferredLoadTask.importDeferName[d]));
       result.outputUnits.add(info);
       return info;
     });
   }
+
+  OutputUnitInfo _unitInfoForElement(Element element) {
+    return _infoFromOutputUnit(
+        compiler.deferredLoadTask.outputUnitForElement(element));
+  }
+
+  OutputUnitInfo _unitInfoForConstant(ConstantValue constant) {
+    OutputUnit outputUnit =
+        compiler.deferredLoadTask.outputUnitForConstant(constant);
+    if (outputUnit == null) {
+      assert(constant is InterceptorConstantValue);
+      return null;
+    }
+    return _infoFromOutputUnit(outputUnit);
+  }
 }
 
 class Selection {
   final Element selectedElement;
-  final TypeMask mask;
+  final ReceiverConstraint mask;
   Selection(this.selectedElement, this.mask);
 }
 
@@ -378,12 +388,13 @@
   // pretty-printed contents.
   final Map<jsAst.Node, int> _nodeToSize = <jsAst.Node, int>{};
 
-  final Map<Element, Set<UniverseSelector>> selectorsFromElement = {};
   final Map<Element, int> inlineCount = <Element, int>{};
   // A mapping from an element to a list of elements that are
   // inlined inside of it.
   final Map<Element, List<Element>> inlineMap = <Element, List<Element>>{};
 
+  final Map<Element, WorldImpact> impacts = <Element, WorldImpact>{};
+
   /// Register the size of the generated output.
   void reportSize(int programSize) {
     _programSize = programSize;
@@ -396,40 +407,35 @@
     inlineMap[inlinedFrom].add(element);
   }
 
-  /**
-   * Registers that a function uses a selector in the
-   * function body
-   */
-  void elementUsesSelector(Element element, UniverseSelector selector) {
-    if (compiler.dumpInfo) {
-      selectorsFromElement
-          .putIfAbsent(element, () => new Set<UniverseSelector>())
-          .add(selector);
-    }
-  }
-
   final Map<Element, Set<Element>> _dependencies = {};
   void registerDependency(Element source, Element target) {
     _dependencies.putIfAbsent(source, () => new Set()).add(target);
   }
 
+  void registerImpact(Element element, WorldImpact impact) {
+    if (compiler.dumpInfo) {
+      impacts[element] = impact;
+    }
+  }
+
   /**
    * Returns an iterable of [Selection]s that are used by
    * [element].  Each [Selection] contains an element that is
    * used and the selector that selected the element.
    */
   Iterable<Selection> getRetaining(Element element) {
-    if (!selectorsFromElement.containsKey(element)) {
-      return const <Selection>[];
-    } else {
-      return selectorsFromElement[element].expand((UniverseSelector selector) {
-        return compiler.world.allFunctions
-            .filter(selector.selector, selector.mask)
-            .map((element) {
-          return new Selection(element, selector.mask);
-        });
-      });
-    }
+    var impact = impacts[element];
+    if (impact == null) return const <Selection>[];
+
+    var selections = <Selection>[];
+    selections.addAll(impact.dynamicUses.expand((dynamicUse) {
+      return compiler.world.allFunctions
+          .filter(dynamicUse.selector, dynamicUse.mask)
+          .map((e) => new Selection(e, dynamicUse.mask));
+    }));
+    selections.addAll(impact.staticUses
+        .map((staticUse) => new Selection(staticUse.element, null)));
+    return selections;
   }
 
   // Returns true if we care about tracking the size of
@@ -547,9 +553,9 @@
       var a = infoCollector._elementToInfo[element];
       if (a == null) continue;
       result.dependencies[a] = _dependencies[element]
-        .map((o) => infoCollector._elementToInfo[o])
-        .where((o) => o != null)
-        .toList();
+          .map((o) => infoCollector._elementToInfo[o])
+          .where((o) => o != null)
+          .toList();
     }
 
     result.deferredFiles = compiler.deferredLoadTask.computeDeferredMap();
@@ -567,7 +573,7 @@
 
     ChunkedConversionSink<Object> sink = encoder.startChunkedConversion(
         new StringConversionSink.fromStringSink(buffer));
-    sink.add(result.toJson());
+    sink.add(new AllInfoJsonCodec().encode(result));
     reporter.reportInfo(NO_LOCATION_SPANNABLE, MessageKind.GENERIC, {
       'text': "View the dumped .info.json file at "
           "https://dart-lang.github.io/dump-info-visualizer"
diff --git a/pkg/compiler/lib/src/elements/common.dart b/pkg/compiler/lib/src/elements/common.dart
index f9c4e59..1e24ff0 100644
--- a/pkg/compiler/lib/src/elements/common.dart
+++ b/pkg/compiler/lib/src/elements/common.dart
@@ -60,6 +60,9 @@
   bool get isGenerativeConstructorBody =>
       kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY;
 
+  bool get isFactoryConstructor =>
+      kind == ElementKind.FACTORY_CONSTRUCTOR;
+
   @override
   bool get isVariable => kind == ElementKind.VARIABLE;
 
@@ -76,12 +79,15 @@
   bool get isInitializingFormal => kind == ElementKind.INITIALIZING_FORMAL;
 
   @override
-  bool get isErroneous => kind == ElementKind.ERROR;
+  bool get isError => kind == ElementKind.ERROR;
 
   @override
   bool get isAmbiguous => kind == ElementKind.AMBIGUOUS;
 
   @override
+  bool get isMalformed => false;
+
+  @override
   bool get isWarnOnUse => kind == ElementKind.WARN_ON_USE;
 
   @override
diff --git a/pkg/compiler/lib/src/elements/elements.dart b/pkg/compiler/lib/src/elements/elements.dart
index 60fcb20..c25e955 100644
--- a/pkg/compiler/lib/src/elements/elements.dart
+++ b/pkg/compiler/lib/src/elements/elements.dart
@@ -84,10 +84,10 @@
       const ElementKind('class', ElementCategory.CLASS);
   static const ElementKind GENERATIVE_CONSTRUCTOR =
       const ElementKind('generative_constructor', ElementCategory.FACTORY);
+  static const ElementKind FACTORY_CONSTRUCTOR =
+      const ElementKind('factory_constructor', ElementCategory.FACTORY);
   static const ElementKind FIELD =
       const ElementKind('field', ElementCategory.VARIABLE);
-  static const ElementKind FIELD_LIST =
-      const ElementKind('field_list', ElementCategory.NONE);
   static const ElementKind GENERATIVE_CONSTRUCTOR_BODY =
       const ElementKind('generative_constructor_body', ElementCategory.NONE);
   static const ElementKind COMPILATION_UNIT =
@@ -212,8 +212,8 @@
   /// `true` if this element is a top level function, static or instance
   /// method, local function or closure defined by a function expression.
   ///
-  /// This property is `true` for operator methods and factory constructors but
-  /// `false` for getter and setter methods, and generative constructors.
+  /// This property is `true` for operator methods but `false` for getter and
+  /// setter methods, and generative and factory constructors.
   ///
   /// See also [isConstructor], [isGenerativeConstructor], and
   /// [isFactoryConstructor] for constructor properties, and [isAccessor],
@@ -272,7 +272,7 @@
   bool get isInitializingFormal;
 
   /// `true` if this element represents a resolution error.
-  bool get isErroneous;
+  bool get isError;
 
   /// `true` if this element represents an ambiguous name.
   ///
@@ -281,6 +281,10 @@
   /// is produced.
   bool get isAmbiguous;
 
+  /// True if there has been errors during resolution or parsing of this
+  /// element.
+  bool get isMalformed;
+
   /// `true` if this element represents an entity whose access causes one or
   /// more warnings.
   bool get isWarnOnUse;
@@ -305,8 +309,6 @@
   /// as all other classes.
   bool get isTopLevel;
   bool get isAssignable;
-  bool get isNative;
-  bool get isJsInterop;
 
   bool get isDeferredLoaderGetter;
 
@@ -401,11 +403,6 @@
   bool get isSynthesized;
   bool get isMixinApplication;
 
-  bool get hasFixedBackendName;
-  String get fixedBackendName;
-
-  String get jsInteropName;
-
   bool get isAbstract;
 
   Scope buildScope();
@@ -415,16 +412,20 @@
   AnalyzableElement get analyzableElement;
 
   accept(ElementVisitor visitor, arg);
-
-  void setJsInteropName(String name);
-  void markAsJsInterop();
 }
 
 class Elements {
   static bool isUnresolved(Element e) {
-    return e == null || e.isErroneous;
+    return e == null || e.isMalformed;
   }
-  static bool isErroneous(Element e) => e != null && e.isErroneous;
+
+  static bool isError(Element e) {
+    return e != null && e.isError;
+  }
+
+  static bool isMalformed(Element e) {
+    return e != null && e.isMalformed;
+  }
 
   /// Unwraps [element] reporting any warnings attached to it, if any.
   static Element unwrap(Element element,
@@ -499,8 +500,7 @@
   }
 
   static bool isStaticOrTopLevelFunction(Element element) {
-    return isStaticOrTopLevel(element)
-           && (identical(element.kind, ElementKind.FUNCTION));
+    return isStaticOrTopLevel(element) && element.isFunction;
   }
 
   static bool isInstanceMethod(Element element) {
@@ -520,13 +520,6 @@
         (element.isFunction || element.isAccessor);
   }
 
-  static bool isNativeOrExtendsNative(ClassElement element) {
-    if (element == null) return false;
-    if (element.isNative || element.isJsInterop) return true;
-    assert(element.isResolved);
-    return isNativeOrExtendsNative(element.superclass);
-  }
-
   static bool isInstanceSend(Send send, TreeElements elements) {
     Element element = elements[send];
     if (element == null) return !isClosureSend(send, element);
@@ -746,9 +739,9 @@
     constructor = constructor.effectiveTarget;
     ClassElement cls = constructor.enclosingClass;
     return cls.library == compiler.typedDataLibrary
-        && cls.isNative
+        && compiler.backend.isNative(cls)
         && compiler.world.isSubtypeOf(cls, compiler.typedDataClass)
-        && compiler.world.isSubtypeOf(cls, compiler.listClass)
+        && compiler.world.isSubtypeOf(cls, compiler.coreClasses.listClass)
         && constructor.name == '';
   }
 
@@ -786,7 +779,7 @@
 /// or otherwise invalid.
 ///
 /// Accessing any field or calling any method defined on [ErroneousElement]
-/// except [isErroneous] will currently throw an exception. (This might
+/// except [isError] will currently throw an exception. (This might
 /// change when we actually want more information on the erroneous element,
 /// e.g., the name of the element we were trying to resolve.)
 ///
@@ -904,7 +897,6 @@
    */
   bool get isInternalLibrary;
 
-  bool get canUseNative;
   bool get exportsHandled;
 
   LibraryElement get implementation;
@@ -1257,8 +1249,6 @@
   /// constructor so its immediate redirection target is `null`.
   ConstructorElement get immediateRedirectionTarget;
 
-  bool get isCyclicRedirection;
-
   /// The prefix of the immediateRedirectionTarget, if it is deferred.
   /// [null] if it is not deferred.
   PrefixElement get redirectionDeferredPrefix;
@@ -1269,6 +1259,25 @@
   /// Is `true` if this constructor is a redirecting factory constructor.
   bool get isRedirectingFactory;
 
+  /// Is `true` if this constructor is a redirecting factory constructor that is
+  /// part of a redirection cycle.
+  bool get isCyclicRedirection;
+
+  /// Is `true` if the effective target of this constructor is malformed.
+  ///
+  /// A constructor is considered malformed if any of the following applies:
+  ///
+  ///     * the constructor is undefined,
+  ///     * the type of the constructor is undefined,
+  ///     * the constructor is a redirecting factory and either
+  ///       - it is part of a redirection cycle,
+  ///       - the effective target is a generative constructor on an abstract
+  ///         class, or
+  ///       - this constructor is constant but the effective target is not,
+  ///       - the arguments to this constructor are incompatible with the
+  ///         parameters of the effective target.
+  bool get isEffectiveTargetMalformed;
+
   /// Compute the type of the effective target of this constructor for an
   /// instantiation site with type [:newType:].
   InterfaceType computeEffectiveTargetType(InterfaceType newType);
@@ -1394,8 +1403,6 @@
   ClassElement get declaration;
   ClassElement get implementation;
 
-  String get nativeTagInfo;
-
   /// `true` if this class is an enum declaration.
   bool get isEnumClass;
 
diff --git a/pkg/compiler/lib/src/elements/modelx.dart b/pkg/compiler/lib/src/elements/modelx.dart
index 6dfd751..95b2b2a 100644
--- a/pkg/compiler/lib/src/elements/modelx.dart
+++ b/pkg/compiler/lib/src/elements/modelx.dart
@@ -58,7 +58,7 @@
   List<MetadataAnnotation> metadataInternal;
 
   ElementX(this.name, this.kind, this.enclosingElement) {
-    assert(isErroneous || implementationLibrary != null);
+    assert(isError || implementationLibrary != null);
   }
 
   Modifiers get modifiers => Modifiers.EMPTY;
@@ -100,7 +100,6 @@
   bool get isInstanceMember => false;
   bool get isDeferredLoaderGetter => false;
 
-  bool get isFactoryConstructor => modifiers.isFactory;
   bool get isConst => modifiers.isConst;
   bool get isFinal => modifiers.isFinal;
   bool get isStatic => modifiers.isStatic;
@@ -122,7 +121,7 @@
 
   bool get isAssignable {
     if (isFinal || isConst) return false;
-    if (isFunction || isGenerativeConstructor) return false;
+    if (isFunction || isConstructor) return false;
     return true;
   }
 
@@ -232,62 +231,6 @@
     }
   }
 
-  String _fixedBackendName = null;
-  bool _isNative = false;
-  String _jsInteropName = null;
-  bool _isJsInterop = false;
-
-  /// Whether the element is implemented via typed JavaScript interop.
-  bool get isJsInterop => _isJsInterop;
-  /// JavaScript name for the element if it is implemented via typed JavaScript
-  /// interop.
-  String get jsInteropName => _jsInteropName;
-
-  void markAsJsInterop() {
-    _isJsInterop = true;
-  }
-
-  void setJsInteropName(String name) {
-    assert(invariant(this,
-        _isJsInterop,
-        message: 'Element is not js interop but given a js interop name.'));
-    _jsInteropName = name;
-  }
-
-  /// Whether the element corresponds to a native JavaScript construct either
-  /// through the existing [setNative] mechanism which is only allowed
-  /// for internal libraries or via the new typed JavaScriptInterop mechanism
-  /// which is allowed for user libraries.
-  bool get isNative => _isNative || isJsInterop;
-  bool get hasFixedBackendName => fixedBackendName != null || isJsInterop;
-
-  String _jsNameHelper(Element e) {
-    assert(invariant(this,
-        !(_isJsInterop &&  _jsInteropName == null),
-        message:
-            'Element is js interop but js interop name has not yet been'
-            'computed.'));
-    if (e.jsInteropName != null && e.jsInteropName.isNotEmpty) {
-      return e.jsInteropName;
-    }
-    return e.isLibrary ? 'self' : e.name;
-  }
-
-  String get fixedBackendName {
-    if (_fixedBackendName == null && isJsInterop) {
-      // If an element isJsInterop but _isJsInterop is false that means it is
-      // considered interop as the parent class is interop.
-      _fixedBackendName =  _jsNameHelper(isConstructor ? enclosingClass : this);
-    }
-    return _fixedBackendName;
-  }
-
-  // Marks this element as a native element.
-  void setNative(String name) {
-    _isNative = true;
-    _fixedBackendName = name;
-  }
-
   FunctionElement asFunctionElement() => null;
 
   bool get isAbstract => modifiers.isAbstract;
@@ -323,6 +266,8 @@
 
   bool get isCyclicRedirection => false;
 
+  bool get isMalformed => true;
+
   PrefixElement get redirectionDeferredPrefix => null;
 
   AbstractFieldElement abstractField;
@@ -377,6 +322,11 @@
   }
 
   @override
+  get isEffectiveTargetMalformed {
+    throw new UnsupportedError("isEffectiveTargetMalformed");
+  }
+
+  @override
   bool get isFromEnvironmentConstructor => false;
 }
 
@@ -397,89 +347,133 @@
       Element enclosing)
       : super(messageKind, messageArguments, name, enclosing);
 
+  @override
   bool get isRedirectingGenerative => false;
 
+  @override
   void set isRedirectingGenerative(_) {
     throw new UnsupportedError("isRedirectingGenerative");
   }
 
+  @override
   bool get isRedirectingFactory => false;
 
+  @override
   get definingElement {
     throw new UnsupportedError("definingElement");
   }
 
+  @override
   get asyncMarker {
     throw new UnsupportedError("asyncMarker");
   }
 
+  @override
   set asyncMarker(_) {
     throw new UnsupportedError("asyncMarker=");
   }
 
-  get internalEffectiveTarget {
-    throw new UnsupportedError("internalEffectiveTarget");
+  @override
+  get effectiveTargetInternal {
+    throw new UnsupportedError("effectiveTargetInternal");
   }
 
-  set internalEffectiveTarget(_) {
-    throw new UnsupportedError("internalEffectiveTarget=");
+  @override
+  set effectiveTargetInternal(_) {
+    throw new UnsupportedError("effectiveTargetInternal=");
   }
 
+  @override
+  get _effectiveTargetType {
+    throw new UnsupportedError("_effectiveTargetType");
+  }
+
+  @override
+  set _effectiveTargetType(_) {
+    throw new UnsupportedError("_effectiveTargetType=");
+  }
+
+  @override
   get effectiveTargetType {
     throw new UnsupportedError("effectiveTargetType");
   }
 
-  set effectiveTargetType(_) {
-    throw new UnsupportedError("effectiveTargetType=");
+  @override
+  get _isEffectiveTargetMalformed {
+    throw new UnsupportedError("_isEffectiveTargetMalformed");
   }
 
+  @override
+  set _isEffectiveTargetMalformed(_) {
+    throw new UnsupportedError("_isEffectiveTargetMalformed=");
+  }
+
+  @override
+  get isEffectiveTargetMalformed {
+    throw new UnsupportedError("isEffectiveTargetMalformed");
+  }
+
+  @override
+  void setEffectiveTarget(ConstructorElement target,
+                            InterfaceType type,
+                            {bool isMalformed: false}) {
+    throw new UnsupportedError("setEffectiveTarget");
+  }
+
+  @override
   void _computeSignature(Resolution resolution) {
     throw new UnsupportedError("_computeSignature");
   }
 
+  @override
   get typeCache {
     throw new UnsupportedError("typeCache");
   }
 
+  @override
   set typeCache(_) {
     throw new UnsupportedError("typeCache=");
   }
 
+  @override
   get immediateRedirectionTarget {
     throw new UnsupportedError("immediateRedirectionTarget");
   }
 
+  @override
   set immediateRedirectionTarget(_) {
     throw new UnsupportedError("immediateRedirectionTarget=");
   }
 
+  @override
   get _functionSignatureCache {
     throw new UnsupportedError("functionSignatureCache");
   }
 
+  @override
   set _functionSignatureCache(_) {
     throw new UnsupportedError("functionSignatureCache=");
   }
 
+  @override
   set functionSignature(_) {
     throw new UnsupportedError("functionSignature=");
   }
 
+  @override
   get nestedClosures {
     throw new UnsupportedError("nestedClosures");
   }
 
+  @override
   set nestedClosures(_) {
     throw new UnsupportedError("nestedClosures=");
   }
 
+  @override
   set redirectionDeferredPrefix(_) {
     throw new UnsupportedError("redirectionDeferredPrefix=");
   }
-
-  void set effectiveTarget(_) {
-    throw new UnsupportedError("effectiveTarget=");
-  }
 }
 
 /// A message attached to a [WarnOnUseElementX].
@@ -636,7 +630,7 @@
       : super(messageKind, messageArguments, enclosingElement, existingElement,
               newElement);
 
-  bool get isErroneous => true;
+  bool get isMalformed => true;
 }
 
 class ScopeX {
@@ -1054,7 +1048,6 @@
   LinkBuilder<LibraryTag> tagsBuilder = new LinkBuilder<LibraryTag>();
   List<LibraryTag> tagsCache;
   LibraryName libraryTag;
-  bool canUseNative = false;
   Link<Element> localMembers = const Link<Element>();
   final ScopeX localScope = new ScopeX();
   final ImportScope importScope = new ImportScope();
@@ -1707,7 +1700,7 @@
 
   get initializer => null;
 
-  bool get isErroneous => true;
+  bool get isMalformed => true;
 
   get nestedClosures {
     throw new UnsupportedError("nestedClosures");
@@ -1913,7 +1906,7 @@
 
   bool get isLocal => false;
 
-  bool get isErroneous => true;
+  bool get isMalformed => true;
 
   DynamicType get type => const DynamicType();
 }
@@ -2053,18 +2046,6 @@
     typeCache = _functionSignatureCache.type;
   }
 
-  /// An function is part of JsInterop in the following cases:
-  /// * It has a jsInteropName annotation
-  /// * It is external member of a class or library tagged as JsInterop.
-  bool get isJsInterop {
-    if (!isExternal) return false;
-
-    if (super.isJsInterop) return true;
-    if (isClassMember) return contextClass.isJsInterop;
-    if (isTopLevel) return library.isJsInterop;
-    return false;
-  }
-
   List<ParameterElement> get parameters {
     // TODO(johnniwinther): Store the list directly, possibly by using List
     // instead of Link in FunctionSignature.
@@ -2120,6 +2101,25 @@
 
   MemberElement get memberContext => this;
 
+  @override
+  SourceSpan get sourcePosition {
+    SourceSpan span = super.sourcePosition;
+    if (span != null && hasNode) {
+      FunctionExpression functionExpression = node.asFunctionExpression();
+      if (functionExpression != null) {
+        Token begin = functionExpression.getBeginToken();
+        Token end;
+        if (functionExpression.parameters != null) {
+          end = functionExpression.parameters.getEndToken();
+        } else {
+          end = functionExpression.name.getEndToken();
+        }
+        span = new SourceSpan.fromTokens(span.uri, begin, end);
+      }
+    }
+    return span;
+  }
+
   void reuseElement() {
     super.reuseElement();
     nestedClosures.clear();
@@ -2270,35 +2270,55 @@
   // generative constructors.
   bool get isCyclicRedirection => effectiveTarget.isRedirectingFactory;
 
-  /// This field is set by the post process queue when checking for cycles.
-  ConstructorElement internalEffectiveTarget;
-  DartType effectiveTargetType;
+  /// These fields are set by the post process queue when checking for cycles.
+  ConstructorElement effectiveTargetInternal;
+  DartType _effectiveTargetType;
+  bool _isEffectiveTargetMalformed;
 
-  void set effectiveTarget(ConstructorElement constructor) {
-    assert(constructor != null && internalEffectiveTarget == null);
-    internalEffectiveTarget = constructor;
+  void setEffectiveTarget(ConstructorElement target,
+                          DartType type,
+                          {bool isMalformed: false}) {
+    assert(invariant(this, target != null,
+        message: 'No effective target provided for $this.'));
+    assert(invariant(this, effectiveTargetInternal == null,
+        message: 'Effective target has already been computed for $this.'));
+    effectiveTargetInternal = target;
+    _effectiveTargetType = type;
+    _isEffectiveTargetMalformed = isMalformed;
   }
 
   ConstructorElement get effectiveTarget {
-    if (Elements.isErroneous(immediateRedirectionTarget)) {
+    if (Elements.isMalformed(immediateRedirectionTarget)) {
       return immediateRedirectionTarget;
     }
-    assert(!isRedirectingFactory || internalEffectiveTarget != null);
-    if (isRedirectingFactory) return internalEffectiveTarget;
+    assert(!isRedirectingFactory || effectiveTargetInternal != null);
+    if (isRedirectingFactory) {
+      return effectiveTargetInternal;
+    }
     if (isPatched) {
-      return internalEffectiveTarget ?? this;
+      return effectiveTargetInternal ?? this;
     }
     return this;
   }
 
+  InterfaceType get effectiveTargetType {
+    assert(invariant(this, _effectiveTargetType != null,
+        message: 'Effective target type has not yet been computed for $this.'));
+    return _effectiveTargetType;
+  }
+
   InterfaceType computeEffectiveTargetType(InterfaceType newType) {
     if (!isRedirectingFactory) return newType;
-    assert(invariant(this, effectiveTargetType != null,
-        message: 'Redirection target type has not yet been computed for '
-                 '$this.'));
     return effectiveTargetType.substByContext(newType);
   }
 
+  bool get isEffectiveTargetMalformed {
+    if (!isRedirectingFactory) return false;
+    assert(invariant(this, _isEffectiveTargetMalformed != null,
+            message: 'Malformedness has not yet been computed for $this.'));
+    return _isEffectiveTargetMalformed == true;
+  }
+
   accept(ElementVisitor visitor, arg) {
     return visitor.visitConstructorElement(this, arg);
   }
@@ -2435,7 +2455,7 @@
 
   void _computeSignature(Resolution resolution) {
     if (hasFunctionSignature) return;
-    if (definingConstructor.isErroneous) {
+    if (definingConstructor.isMalformed) {
       functionSignature = new FunctionSignatureX(
           type: new FunctionType.synthesized(enclosingClass.thisType));
     }
@@ -2557,7 +2577,6 @@
 
   DartType supertype;
   Link<DartType> interfaces;
-  String nativeTagInfo;
   int supertypeLoadState;
   int resolutionState;
   bool isProxy = false;
@@ -2682,20 +2701,8 @@
   }
 
   bool implementsFunction(Compiler compiler) {
-    return asInstanceOf(compiler.functionClass) != null || callType != null;
-  }
-
-  bool get isNative => nativeTagInfo != null || isJsInterop;
-
-  void setNative(String name) {
-    // TODO(johnniwinther): Assert that this is only called once. The memory
-    // compiler copies pre-processed elements into a new compiler through
-    // [Compiler.onLibraryScanned] and thereby causes multiple calls to this
-    // method.
-    assert(invariant(this, nativeTagInfo == null || nativeTagInfo == name,
-        message: "Native tag info set inconsistently on $this: "
-                 "Existing name '$nativeTagInfo', new name '$name'."));
-    nativeTagInfo = name;
+    return asInstanceOf(compiler.coreClasses.functionClass) != null ||
+        callType != null;
   }
 
   // TODO(johnniwinther): Remove these when issue 18630 is fixed.
diff --git a/pkg/compiler/lib/src/enqueue.dart b/pkg/compiler/lib/src/enqueue.dart
index 522bb29..53796dc 100644
--- a/pkg/compiler/lib/src/enqueue.dart
+++ b/pkg/compiler/lib/src/enqueue.dart
@@ -51,6 +51,14 @@
 import 'universe/selector.dart' show
     Selector;
 import 'universe/universe.dart';
+import 'universe/use.dart' show
+    DynamicUse,
+    StaticUse,
+    StaticUseKind,
+    TypeUse,
+    TypeUseKind;
+import 'universe/world_impact.dart' show
+    WorldImpact;
 import 'util/util.dart' show
     Link,
     Setlet;
@@ -86,61 +94,6 @@
   }
 }
 
-class WorldImpact {
-  const WorldImpact();
-
-  Iterable<UniverseSelector> get dynamicInvocations =>
-      const <UniverseSelector>[];
-  Iterable<UniverseSelector> get dynamicGetters => const <UniverseSelector>[];
-  Iterable<UniverseSelector> get dynamicSetters => const <UniverseSelector>[];
-
-  // TODO(johnniwinther): Split this into more precise subsets.
-  Iterable<Element> get staticUses => const <Element>[];
-
-  // TODO(johnniwinther): Replace this by called constructors with type
-  // arguments.
-  Iterable<InterfaceType> get instantiatedTypes => const <InterfaceType>[];
-
-  // TODO(johnniwinther): Collect checked types for checked mode separately to
-  // support serialization.
-  Iterable<DartType> get isChecks => const <DartType>[];
-
-  Iterable<DartType> get checkedModeChecks => const <DartType>[];
-
-  Iterable<DartType> get asCasts => const <DartType>[];
-
-  Iterable<MethodElement> get closurizedFunctions => const <MethodElement>[];
-
-  Iterable<LocalFunctionElement> get closures => const <LocalFunctionElement>[];
-
-  Iterable<DartType> get typeLiterals => const <DartType>[];
-
-  String toString() {
-    StringBuffer sb = new StringBuffer();
-
-    void add(String title, Iterable iterable) {
-      if (iterable.isNotEmpty) {
-        sb.write('\n $title:');
-        iterable.forEach((e) => sb.write('\n  $e'));
-      }
-    }
-
-    add('dynamic invocations', dynamicInvocations);
-    add('dynamic getters', dynamicGetters);
-    add('dynamic setters', dynamicSetters);
-    add('static uses', staticUses);
-    add('instantiated types', instantiatedTypes);
-    add('is-checks', isChecks);
-    add('checked-mode checks', checkedModeChecks);
-    add('as-casts', asCasts);
-    add('closurized functions', closurizedFunctions);
-    add('closures', closures);
-    add('type literals', typeLiterals);
-
-    return sb.toString();
-  }
-}
-
 abstract class Enqueuer {
   final String name;
   final Compiler compiler; // TODO(ahe): Remove this dependency.
@@ -214,34 +167,29 @@
   /// Apply the [worldImpact] of processing [element] to this enqueuer.
   void applyImpact(Element element, WorldImpact worldImpact) {
     // TODO(johnniwinther): Optimize the application of the world impact.
-    worldImpact.dynamicInvocations.forEach(registerDynamicInvocation);
-    worldImpact.dynamicGetters.forEach(registerDynamicGetter);
-    worldImpact.dynamicSetters.forEach(registerDynamicSetter);
+    worldImpact.dynamicUses.forEach(registerDynamicUse);
     worldImpact.staticUses.forEach(registerStaticUse);
-    worldImpact.instantiatedTypes.forEach(registerInstantiatedType);
-    worldImpact.isChecks.forEach(registerIsCheck);
-    worldImpact.asCasts.forEach(registerIsCheck);
-    if (compiler.enableTypeAssertions) {
-      worldImpact.checkedModeChecks.forEach(registerIsCheck);
-    }
-    worldImpact.closurizedFunctions.forEach(registerGetOfStaticFunction);
-    worldImpact.closures.forEach(registerClosure);
+    worldImpact.typeUses.forEach(registerTypeUse);
   }
 
-  // TODO(johnniwinther): Remove the need for passing the [registry].
   void registerInstantiatedType(InterfaceType type,
                                 {bool mirrorUsage: false}) {
     task.measure(() {
       ClassElement cls = type.element;
       cls.ensureResolved(resolution);
+      bool isNative = compiler.backend.isNative(cls);
       universe.registerTypeInstantiation(
           type,
+          isNative: isNative,
           byMirrors: mirrorUsage,
           onImplemented: (ClassElement cls) {
         compiler.backend.registerImplementedClass(
                     cls, this, compiler.globalDependencies);
       });
-      processInstantiatedClass(cls);
+      // TODO(johnniwinther): Share this reasoning with [Universe].
+      if (!cls.isAbstract || isNative || mirrorUsage) {
+        processInstantiatedClass(cls);
+      }
     });
   }
 
@@ -267,7 +215,7 @@
       // its metadata parsed and analyzed.
       // Note: this assumes that there are no non-native fields on native
       // classes, which may not be the case when a native class is subclassed.
-      if (cls.isNative) {
+      if (compiler.backend.isNative(cls)) {
         compiler.world.registerUsedElement(member);
         nativeEnqueuer.handleFieldAnnotations(member);
         if (universe.hasInvokedGetter(member, compiler.world) ||
@@ -390,33 +338,18 @@
             superclass, this, compiler.globalDependencies);
       }
 
-      while (cls != null) {
-        processClass(cls);
-        cls = cls.superclass;
+      ClassElement superclass = cls;
+      while (superclass != null) {
+        processClass(superclass);
+        superclass = superclass.superclass;
       }
     });
   }
 
-  void registerInvocation(UniverseSelector selector) {
+  void registerDynamicUse(DynamicUse dynamicUse) {
     task.measure(() {
-      if (universe.registerInvocation(selector)) {
-        handleUnseenSelector(selector);
-      }
-    });
-  }
-
-  void registerInvokedGetter(UniverseSelector selector) {
-    task.measure(() {
-      if (universe.registerInvokedGetter(selector)) {
-        handleUnseenSelector(selector);
-      }
-    });
-  }
-
-  void registerInvokedSetter(UniverseSelector selector) {
-    task.measure(() {
-      if (universe.registerInvokedSetter(selector)) {
-        handleUnseenSelector(selector);
+      if (universe.registerDynamicUse(dynamicUse)) {
+        handleUnseenSelector(dynamicUse);
       }
     });
   }
@@ -452,7 +385,7 @@
           this,
           compiler.mirrorDependencies,
           mirrorUsage: true);
-      registerStaticUse(ctor.declaration);
+      registerStaticUse(new StaticUse.foreignUse(ctor.declaration));
     }
   }
 
@@ -469,19 +402,19 @@
         typedef.ensureResolved(resolution);
         compiler.world.allTypedefs.add(element);
       } else if (Elements.isStaticOrTopLevel(element)) {
-        registerStaticUse(element.declaration);
+        registerStaticUse(new StaticUse.foreignUse(element.declaration));
       } else if (element.isInstanceMember) {
         // We need to enqueue all members matching this one in subclasses, as
         // well.
         // TODO(herhut): Use TypedSelector.subtype for enqueueing
-        UniverseSelector selector = new UniverseSelector(
+        DynamicUse dynamicUse = new DynamicUse(
             new Selector.fromElement(element), null);
-        registerSelectorUse(selector);
+        registerDynamicUse(dynamicUse);
         if (element.isField) {
-          UniverseSelector selector = new UniverseSelector(
+          DynamicUse dynamicUse = new DynamicUse(
               new Selector.setter(new Name(
                   element.name, element.library, isSetter: true)), null);
-          registerInvokedSetter(selector);
+          registerDynamicUse(dynamicUse);
         }
       }
     }
@@ -626,19 +559,19 @@
     processSet(instanceFunctionsByName, n, f);
   }
 
-  void handleUnseenSelector(UniverseSelector universeSelector) {
-    strategy.processSelector(this, universeSelector);
+  void handleUnseenSelector(DynamicUse universeSelector) {
+    strategy.processDynamicUse(this, universeSelector);
   }
 
-  void handleUnseenSelectorInternal(UniverseSelector universeSelector) {
-    Selector selector = universeSelector.selector;
+  void handleUnseenSelectorInternal(DynamicUse dynamicUse) {
+    Selector selector = dynamicUse.selector;
     String methodName = selector.name;
     processInstanceMembers(methodName, (Element member) {
-      if (universeSelector.appliesUnnamed(member, compiler.world)) {
+      if (dynamicUse.appliesUnnamed(member, compiler.world)) {
         if (member.isFunction && selector.isGetter) {
           registerClosurizedMember(member);
         }
-        if (member.isField && member.enclosingClass.isNative) {
+        if (member.isField && compiler.backend.isNative(member.enclosingClass)) {
           if (selector.isGetter || selector.isCall) {
             nativeEnqueuer.registerFieldLoad(member);
             // We have to also handle storing to the field because we only get
@@ -663,7 +596,7 @@
     });
     if (selector.isGetter) {
       processInstanceFunctions(methodName, (Element member) {
-        if (universeSelector.appliesUnnamed(member, compiler.world)) {
+        if (dynamicUse.appliesUnnamed(member, compiler.world)) {
           registerClosurizedMember(member);
           return true;
         }
@@ -677,63 +610,62 @@
    *
    * Invariant: [element] must be a declaration element.
    */
-  void registerStaticUse(Element element) {
-    if (element == null) return;
-    strategy.processStaticUse(this, element);
+  void registerStaticUse(StaticUse staticUse) {
+    strategy.processStaticUse(this, staticUse);
   }
 
-  void registerStaticUseInternal(Element element) {
+  void registerStaticUseInternal(StaticUse staticUse) {
+    Element element = staticUse.element;
     assert(invariant(element, element.isDeclaration,
         message: "Element ${element} is not the declaration."));
-    if (Elements.isStaticOrTopLevel(element) && element.isField) {
-      universe.registerStaticFieldUse(element);
-    }
-    addToWorkList(element);
+    universe.registerStaticUse(staticUse);
     compiler.backend.registerStaticUse(element, this);
-  }
-
-  void registerGetOfStaticFunction(FunctionElement element) {
-    registerStaticUse(element);
-    compiler.backend.registerGetOfStaticFunction(this);
-    universe.staticFunctionsNeedingGetter.add(element);
-  }
-
-  void registerDynamicInvocation(UniverseSelector selector) {
-    assert(selector != null);
-    registerInvocation(selector);
-  }
-
-  void registerSelectorUse(UniverseSelector universeSelector) {
-    if (universeSelector.selector.isGetter) {
-      registerInvokedGetter(universeSelector);
-    } else if (universeSelector.selector.isSetter) {
-      registerInvokedSetter(universeSelector);
-    } else {
-      registerInvocation(universeSelector);
+    bool addElement = true;
+    switch (staticUse.kind) {
+      case StaticUseKind.STATIC_TEAR_OFF:
+        compiler.backend.registerGetOfStaticFunction(this);
+        break;
+      case StaticUseKind.FIELD_GET:
+      case StaticUseKind.FIELD_SET:
+      case StaticUseKind.CLOSURE:
+        // TODO(johnniwinther): Avoid this. Currently [FIELD_GET] and
+        // [FIELD_SET] contains [BoxFieldElement]s which we cannot enqueue.
+        // Also [CLOSURE] contains [LocalFunctionElement] which we cannot
+        // enqueue.
+        addElement = false;
+        break;
+      case StaticUseKind.SUPER_TEAR_OFF:
+      case StaticUseKind.GENERAL:
+        break;
+    }
+    if (addElement) {
+      addToWorkList(element);
     }
   }
 
-  void registerDynamicGetter(UniverseSelector selector) {
-    registerInvokedGetter(selector);
+  void registerTypeUse(TypeUse typeUse) {
+    DartType type = typeUse.type;
+    switch (typeUse.kind) {
+      case TypeUseKind.INSTANTIATION:
+        registerInstantiatedType(type);
+        break;
+      case TypeUseKind.INSTANTIATION:
+      case TypeUseKind.IS_CHECK:
+      case TypeUseKind.AS_CAST:
+      case TypeUseKind.CATCH_TYPE:
+        _registerIsCheck(type);
+        break;
+      case TypeUseKind.CHECKED_MODE_CHECK:
+        if (compiler.enableTypeAssertions) {
+          _registerIsCheck(type);
+        }
+        break;
+      case TypeUseKind.TYPE_LITERAL:
+        break;
+    }
   }
 
-  void registerDynamicSetter(UniverseSelector selector) {
-    registerInvokedSetter(selector);
-  }
-
-  void registerGetterForSuperMethod(Element element) {
-    universe.methodsNeedingSuperGetter.add(element);
-  }
-
-  void registerFieldGetter(Element element) {
-    universe.fieldGetters.add(element);
-  }
-
-  void registerFieldSetter(Element element) {
-    universe.fieldSetters.add(element);
-  }
-
-  void registerIsCheck(DartType type) {
+  void _registerIsCheck(DartType type) {
     type = universe.registerIsCheck(type, compiler);
     // Even in checked mode, type annotations for return type and argument
     // types do not imply type checks, so there should never be a check
@@ -758,10 +690,6 @@
     universe.closurizedMembers.add(element);
   }
 
-  void registerClosure(LocalFunctionElement element) {
-    universe.allClosures.add(element);
-  }
-
   void forEach(void f(WorkItem work)) {
     do {
       while (queue.isNotEmpty) {
@@ -852,7 +780,7 @@
   }
 
   bool internalAddToWorkList(Element element) {
-    if (element.isErroneous) return false;
+    if (element.isMalformed) return false;
 
     assert(invariant(element, element is AnalyzableElement,
         message: 'Element $element is not analyzable.'));
@@ -960,12 +888,11 @@
 /// [Enqueuer] which is specific to code generation.
 class CodegenEnqueuer extends Enqueuer {
   final Queue<CodegenWorkItem> queue;
-  final Map<Element, js.Expression> generatedCode =
-      new Map<Element, js.Expression>();
+  final Map<Element, js.Expression> generatedCode = <Element, js.Expression>{};
 
   final Set<Element> newlyEnqueuedElements;
 
-  final Set<UniverseSelector> newlySeenSelectors;
+  final Set<DynamicUse> newlySeenSelectors;
 
   bool enabledNoSuchMethod = false;
 
@@ -1043,11 +970,11 @@
     }
   }
 
-  void handleUnseenSelector(UniverseSelector selector) {
+  void handleUnseenSelector(DynamicUse dynamicUse) {
     if (compiler.hasIncrementalSupport) {
-      newlySeenSelectors.add(selector);
+      newlySeenSelectors.add(dynamicUse);
     }
-    super.handleUnseenSelector(selector);
+    super.handleUnseenSelector(dynamicUse);
   }
 }
 
@@ -1087,11 +1014,11 @@
   /// Process a class instantiated in live code.
   void processInstantiatedClass(Enqueuer enqueuer, ClassElement cls) {}
 
-  /// Process an element statically accessed in live code.
-  void processStaticUse(Enqueuer enqueuer, Element element) {}
+  /// Process a static use of and element in live code.
+  void processStaticUse(Enqueuer enqueuer, StaticUse staticUse) {}
 
-  /// Process a selector for a call site in live code.
-  void processSelector(Enqueuer enqueuer, UniverseSelector selector) {}
+  /// Process a dynamic use for a call site in live code.
+  void processDynamicUse(Enqueuer enqueuer, DynamicUse dynamicUse) {}
 }
 
 class TreeShakingEnqueuerStrategy implements EnqueuerStrategy {
@@ -1103,12 +1030,12 @@
   }
 
   @override
-  void processStaticUse(Enqueuer enqueuer, Element element) {
-    enqueuer.registerStaticUseInternal(element);
+  void processStaticUse(Enqueuer enqueuer, StaticUse staticUse) {
+    enqueuer.registerStaticUseInternal(staticUse);
   }
 
   @override
-  void processSelector(Enqueuer enqueuer, UniverseSelector selector) {
-    enqueuer.handleUnseenSelectorInternal(selector);
+  void processDynamicUse(Enqueuer enqueuer, DynamicUse dynamicUse) {
+    enqueuer.handleUnseenSelectorInternal(dynamicUse);
   }
 }
diff --git a/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart b/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
index 7daed4e..f9dc9eb 100644
--- a/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
+++ b/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
@@ -16,8 +16,6 @@
 import '../elements/elements.dart';
 import '../resolution/operators.dart';
 import '../resolution/semantic_visitor.dart';
-import '../resolution/send_resolver.dart' show
-    SendResolverMixin;
 import '../resolution/tree_elements.dart' show
     TreeElements;
 import '../tree/tree.dart';
@@ -55,6 +53,9 @@
   T get constMapType;
   T get stringType;
   T get typeType;
+  T get syncStarIterableType;
+  T get asyncFutureType; // Subtype of Future returned by async methods.
+  T get asyncStarStreamType;
 
   T stringLiteralType(DartString value);
   T boolLiteralType(LiteralBool value);
@@ -603,25 +604,33 @@
   void mergeAfterBreaks(List<LocalsHandler<T>> handlers,
                         {bool keepOwnLocals: true}) {
     Node level = locals.block;
+    // Use a separate locals handler to perform the merge in, so that Phi
+    // creation does not invalidate previous type knowledge while we might
+    // still look it up.
+    LocalsHandler merged = new LocalsHandler.from(this, level);
     Set<Local> seenLocals = new Setlet<Local>();
-    // If we want to keep the locals, we first merge [this] into itself to
-    // create the required Phi nodes.
-    if (keepOwnLocals && !seenReturnOrThrow) {
-      mergeHandler(this, seenLocals);
-    }
     bool allBranchesAbort = true;
     // Merge all other handlers.
     for (LocalsHandler handler in handlers) {
       allBranchesAbort = allBranchesAbort && handler.seenReturnOrThrow;
-      mergeHandler(handler, seenLocals);
+      merged.mergeHandler(handler, seenLocals);
     }
-    // Clean up Phi nodes with single input.
-    locals.forEachLocal((Local variable, T type) {
-      if (!seenLocals.contains(variable)) return;
-      T newType = types.simplifyPhi(level, variable, type);
-      if (newType != type) {
-        locals[variable] = newType;
+    // If we want to keep own locals, we merge [seenLocals] from [this] into
+    // [merged] to update the Phi nodes with original values.
+    if (keepOwnLocals && !seenReturnOrThrow) {
+      for (Local variable in seenLocals) {
+        T originalType = locals[variable];
+        if (originalType != null) {
+          merged.locals[variable] = types.addPhiInput(variable,
+                                                      merged.locals[variable],
+                                                      originalType);
+        }
       }
+    }
+    // Clean up Phi nodes with single input and store back result into
+    // actual locals handler.
+    merged.locals.forEachOwnLocal((Local variable, T type) {
+      locals[variable] = types.simplifyPhi(level, variable, type);
     });
     seenReturnOrThrow = allBranchesAbort &&
                         (!keepOwnLocals || seenReturnOrThrow);
@@ -692,8 +701,7 @@
 
 abstract class InferrerVisitor<T, E extends MinimalInferrerEngine<T>>
     extends Visitor<T>
-    with SendResolverMixin,
-         SemanticSendResolvedMixin<T, dynamic>,
+    with SemanticSendResolvedMixin<T, dynamic>,
          CompoundBulkMixin<T, dynamic>,
          SetIfNullBulkMixin<T, dynamic>,
          PrefixBulkMixin<T, dynamic>,
@@ -871,7 +879,7 @@
     // TODO(kasperl): We should be able to tell that the type of a literal
     // symbol is always a non-null exact symbol implementation -- not just
     // any non-null subtype of the symbol interface.
-    return types.nonNullSubtype(compiler.symbolClass);
+    return types.nonNullSubtype(compiler.coreClasses.symbolClass);
   }
 
   @override
@@ -1066,7 +1074,7 @@
           }
         } else {
           // Narrow the elements to a non-null type.
-          DartType objectType = compiler.objectClass.rawType;
+          DartType objectType = compiler.coreTypes.objectType;
           if (Elements.isLocal(receiverElement)) {
             narrow(receiverElement, objectType, node);
           }
diff --git a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
index 5e817af..61f8595 100644
--- a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
@@ -15,6 +15,9 @@
 import '../constants/values.dart' show
     ConstantValue,
     IntConstantValue;
+import '../core_types.dart' show
+    CoreClasses,
+    CoreTypes;
 import '../cps_ir/cps_ir_nodes.dart' as cps_ir show
     Node;
 import '../dart_types.dart' show
@@ -62,7 +65,7 @@
                       DartType annotation,
                       {bool isNullable: true}) {
     if (annotation.treatAsDynamic) return type;
-    if (annotation.element == compiler.objectClass) return type;
+    if (annotation.isObject) return type;
     TypeMask otherType;
     if (annotation.isTypedef || annotation.isFunctionType) {
       otherType = functionType;
@@ -117,6 +120,9 @@
   TypeMask get constMapType => compiler.typesTask.constMapType;
   TypeMask get stringType => compiler.typesTask.stringType;
   TypeMask get typeType => compiler.typesTask.typeType;
+  TypeMask get syncStarIterableType => compiler.typesTask.syncStarIterableType;
+  TypeMask get asyncFutureType => compiler.typesTask.asyncFutureType;
+  TypeMask get asyncStarStreamType => compiler.typesTask.asyncStarStreamType;
   bool isNull(TypeMask mask) => mask.isEmpty && mask.isNullable;
 
   TypeMask stringLiteralType(ast.DartString value) => stringType;
@@ -207,6 +213,10 @@
       : this.compiler = compiler,
         this.classWorld = compiler.world;
 
+  CoreClasses get coreClasses => compiler.coreClasses;
+
+  CoreTypes get coreTypes => compiler.coreTypes;
+
   /**
    * Records the default type of parameter [parameter].
    */
@@ -388,20 +398,20 @@
     for (var type in typesReturned) {
       T mappedType;
       if (type == native.SpecialType.JsObject) {
-        mappedType = types.nonNullExact(compiler.objectClass);
-      } else if (type.element == compiler.stringClass) {
+        mappedType = types.nonNullExact(coreClasses.objectClass);
+      } else if (type == coreTypes.stringType) {
         mappedType = types.stringType;
-      } else if (type.element == compiler.intClass) {
+      } else if (type == coreTypes.intType) {
         mappedType = types.intType;
-      } else if (type.element == compiler.numClass ||
-                 type.element == compiler.doubleClass) {
+      } else if (type == coreTypes.numType ||
+                 type == coreTypes.doubleType) {
         // Note: the backend double class is specifically for non-integer
         // doubles, and a native behavior returning 'double' does not guarantee
         // a non-integer return type, so we return the number type for those.
         mappedType = types.numType;
-      } else if (type.element == compiler.boolClass) {
+      } else if (type == coreTypes.boolType) {
         mappedType = types.boolType;
-      } else if (type.element == compiler.nullClass) {
+      } else if (type == coreTypes.nullType) {
         mappedType = types.nullType;
       } else if (type.isVoid) {
         mappedType = types.nullType;
@@ -451,9 +461,9 @@
   }
 
   bool isNativeElement(Element element) {
-    if (element.isNative) return true;
+    if (compiler.backend.isNative(element)) return true;
     return element.isClassMember
-        && element.enclosingClass.isNative
+        && compiler.backend.isNative(element.enclosingClass)
         && element.isField;
   }
 
@@ -555,7 +565,7 @@
       inferrer.setDefaultTypeOfParameter(element, type);
     });
 
-    if (analyzedElement.isNative) {
+    if (compiler.backend.isNative(analyzedElement)) {
       // Native methods do not have a body, and we currently just say
       // they return dynamic.
       return types.dynamicType;
@@ -637,27 +647,55 @@
           }
         });
       }
-      returnType = types.nonNullExact(cls);
+      if (analyzedElement.isGenerativeConstructor && cls.isAbstract) {
+        if (compiler.world.isDirectlyInstantiated(cls)) {
+          returnType = types.nonNullExact(cls);
+        } else if (compiler.world.isIndirectlyInstantiated(cls)) {
+          returnType = types.nonNullSubclass(cls);
+        } else  {
+          // TODO(johnniwinther): Avoid analyzing [analyzedElement] in this
+          // case; it's never called.
+          returnType = types.nonNullEmpty();
+        }
+      } else {
+        returnType = types.nonNullExact(cls);
+      }
     } else {
       signature.forEachParameter((LocalParameterElement element) {
         locals.update(element, inferrer.typeOfElement(element), node);
       });
       visit(node.body);
-      if (function.asyncMarker != AsyncMarker.SYNC) {
-        // TODO(herhut): Should be type Future/Iterable/Stream instead of
-        // dynamic.
-        returnType = inferrer.addReturnTypeFor(
-            analyzedElement, returnType, types.dynamicType);
-      } else if (returnType == null) {
-        // No return in the body.
-        returnType = locals.seenReturnOrThrow
-            ? types.nonNullEmpty()  // Body always throws.
-            : types.nullType;
-      } else if (!locals.seenReturnOrThrow) {
-        // We haven't seen returns on all branches. So the method may
-        // also return null.
-        returnType = inferrer.addReturnTypeFor(
-            analyzedElement, returnType, types.nullType);
+      switch (function.asyncMarker) {
+        case AsyncMarker.SYNC:
+          if (returnType == null) {
+            // No return in the body.
+            returnType = locals.seenReturnOrThrow
+                ? types.nonNullEmpty()  // Body always throws.
+                : types.nullType;
+          } else if (!locals.seenReturnOrThrow) {
+            // We haven't seen returns on all branches. So the method may
+            // also return null.
+            returnType = inferrer.addReturnTypeFor(
+                analyzedElement, returnType, types.nullType);
+          }
+          break;
+
+        case AsyncMarker.SYNC_STAR:
+          // TODO(asgerf): Maybe make a ContainerTypeMask for these? The type
+          //               contained is the method body's return type.
+          returnType = inferrer.addReturnTypeFor(
+              analyzedElement, returnType, types.syncStarIterableType);
+          break;
+
+        case AsyncMarker.ASYNC:
+          returnType = inferrer.addReturnTypeFor(
+                analyzedElement, returnType, types.asyncFutureType);
+          break;
+
+        case AsyncMarker.ASYNC_STAR:
+          returnType = inferrer.addReturnTypeFor(
+                analyzedElement, returnType, types.asyncStarStreamType);
+          break;
       }
     }
 
@@ -901,7 +939,7 @@
       T getterType;
       T newType;
 
-      if (Elements.isErroneous(element)) return types.dynamicType;
+      if (Elements.isMalformed(element)) return types.dynamicType;
 
       if (Elements.isStaticOrTopLevelField(element)) {
         Element getterElement = elements[node.selector];
@@ -1260,7 +1298,7 @@
                           T rhsType,
                           ast.Node rhs) {
     ArgumentsTypes arguments = new ArgumentsTypes<T>([rhsType], null);
-    if (Elements.isErroneous(element)) {
+    if (Elements.isMalformed(element)) {
       // Code will always throw.
     } else if (Elements.isStaticOrTopLevelField(element)) {
       handleStaticSend(node, setterSelector, setterMask, element, arguments);
@@ -2211,7 +2249,7 @@
 
   T visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) {
     Element element = elements.getRedirectingTargetConstructor(node);
-    if (Elements.isErroneous(element)) {
+    if (Elements.isMalformed(element)) {
       recordReturnType(types.dynamicType);
     } else {
       // We don't create a selector for redirecting factories, and
@@ -2276,9 +2314,9 @@
   T visitAsyncForIn(ast.AsyncForIn node) {
     T expressionType = visit(node.expression);
 
-    Selector currentSelector = elements.getCurrentSelector(node);
+    Selector currentSelector = Selectors.current;
     TypeMask currentMask = elements.getCurrentTypeMask(node);
-    Selector moveNextSelector = elements.getMoveNextSelector(node);
+    Selector moveNextSelector = Selectors.moveNext;
     TypeMask moveNextMask = elements.getMoveNextTypeMask(node);
 
     js.JavaScriptBackend backend = compiler.backend;
@@ -2295,11 +2333,11 @@
 
   T visitSyncForIn(ast.SyncForIn node) {
     T expressionType = visit(node.expression);
-    Selector iteratorSelector = elements.getIteratorSelector(node);
+    Selector iteratorSelector = Selectors.iterator;
     TypeMask iteratorMask = elements.getIteratorTypeMask(node);
-    Selector currentSelector = elements.getCurrentSelector(node);
+    Selector currentSelector = Selectors.current;
     TypeMask currentMask = elements.getCurrentTypeMask(node);
-    Selector moveNextSelector = elements.getMoveNextSelector(node);
+    Selector moveNextSelector = Selectors.moveNext;
     TypeMask moveNextMask = elements.getMoveNextTypeMask(node);
 
     T iteratorType = handleDynamicSend(
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
index 86551cb..4a03baf 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
@@ -233,6 +233,27 @@
         getConcreteTypeFor(compiler.typesTask.dynamicType);
   }
 
+  TypeInformation asyncFutureTypeCache;
+  TypeInformation get asyncFutureType {
+    if (asyncFutureTypeCache != null) return asyncFutureTypeCache;
+    return asyncFutureTypeCache =
+        getConcreteTypeFor(compiler.typesTask.asyncFutureType);
+  }
+
+  TypeInformation syncStarIterableTypeCache;
+  TypeInformation get syncStarIterableType {
+    if (syncStarIterableTypeCache != null) return syncStarIterableTypeCache;
+    return syncStarIterableTypeCache =
+        getConcreteTypeFor(compiler.typesTask.syncStarIterableType);
+  }
+
+  TypeInformation asyncStarStreamTypeCache;
+  TypeInformation get asyncStarStreamType {
+    if (asyncStarStreamTypeCache != null) return asyncStarStreamTypeCache;
+    return asyncStarStreamTypeCache =
+        getConcreteTypeFor(compiler.typesTask.asyncStarStreamType);
+  }
+
   TypeInformation nonNullEmptyType;
 
   TypeInformation stringLiteralType(ast.DartString value) {
@@ -1226,7 +1247,7 @@
         assert(invariant(element,
             element.isField ||
             element.isFunction ||
-            element.isGenerativeConstructor ||
+            element.isConstructor ||
             element.isGetter ||
             element.isSetter,
             message: 'Unexpected element kind: ${element.kind}'));
diff --git a/pkg/compiler/lib/src/info/send_info.dart b/pkg/compiler/lib/src/info/send_info.dart
index b29fe96..8292be4 100644
--- a/pkg/compiler/lib/src/info/send_info.dart
+++ b/pkg/compiler/lib/src/info/send_info.dart
@@ -23,7 +23,6 @@
     ElementVisitor;
 import '../resolution/operators.dart';
 import '../resolution/semantic_visitor.dart';
-import '../resolution/send_resolver.dart';
 import '../resolution/tree_elements.dart';
 import '../constants/expressions.dart';
 import '../parser/partial_elements.dart' show
@@ -84,7 +83,7 @@
 
 /// Visitor that categorizes data about an individual send.
 class _StatsVisitor<T> extends Visitor
-    with SendResolverMixin, SemanticSendResolvedMixin<dynamic, T>
+    with SemanticSendResolvedMixin<dynamic, T>
     implements SemanticSendVisitor<dynamic, T> {
 
   // TODO(sigmund): consider passing in several AnalysisResults at once, so we
diff --git a/pkg/compiler/lib/src/io/source_file.dart b/pkg/compiler/lib/src/io/source_file.dart
index d799a9b..f2058ad 100644
--- a/pkg/compiler/lib/src/io/source_file.dart
+++ b/pkg/compiler/lib/src/io/source_file.dart
@@ -137,31 +137,53 @@
     if (colorize == null) {
       colorize = (text) => text;
     }
-    var line = getLine(start);
-    var column = getColumn(line, start);
+    if (end > length) {
+      start = length - 1;
+      end = length;
+    }
 
-    var buf = new StringBuffer('${filename}:');
+    int lineStart = getLine(start);
+    int columnStart = getColumn(lineStart, start);
+    int lineEnd = getLine(end);
+    int columnEnd = getColumn(lineEnd, end);
+
+    StringBuffer buf = new StringBuffer('${filename}:');
     if (start != end || start != 0) {
       // Line/column info is relevant.
-      buf.write('${line + 1}:${column + 1}:');
+      buf.write('${lineStart + 1}:${columnStart + 1}:');
     }
     buf.write('\n$message\n');
 
     if (start != end && includeSourceLine) {
-      String textLine = getLineText(line);
+      if (lineStart == lineEnd) {
+        String textLine = getLineText(lineStart);
 
-      int toColumn = min(column + (end-start), textLine.length);
-      buf.write(textLine.substring(0, column));
-      buf.write(colorize(textLine.substring(column, toColumn)));
-      buf.write(textLine.substring(toColumn));
+        int toColumn = min(columnStart + (end-start), textLine.length);
+        buf.write(textLine.substring(0, columnStart));
+        buf.write(colorize(textLine.substring(columnStart, toColumn)));
+        buf.write(textLine.substring(toColumn));
 
-      int i = 0;
-      for (; i < column; i++) {
-        buf.write(' ');
-      }
+        int i = 0;
+        for (; i < columnStart; i++) {
+          buf.write(' ');
+        }
 
-      for (; i < toColumn; i++) {
-        buf.write(colorize('^'));
+        for (; i < toColumn; i++) {
+          buf.write(colorize('^'));
+        }
+      } else {
+        for (int line = lineStart; line <= lineEnd; line++) {
+          String textLine = getLineText(line);
+          if (line == lineStart) {
+            buf.write(textLine.substring(0, columnStart));
+            buf.write(colorize(textLine.substring(columnStart)));
+          } else if (line == lineEnd) {
+            buf.write(colorize(textLine.substring(0, columnEnd)));
+            buf.write(textLine.substring(columnEnd));
+          } else {
+            buf.write(colorize(textLine));
+          }
+        }
       }
     }
 
diff --git a/pkg/compiler/lib/src/js/rewrite_async.dart b/pkg/compiler/lib/src/js/rewrite_async.dart
index 4be28d1..bbac37f 100644
--- a/pkg/compiler/lib/src/js/rewrite_async.dart
+++ b/pkg/compiler/lib/src/js/rewrite_async.dart
@@ -1023,7 +1023,7 @@
     }
 
     if (node.init != null) {
-      addExpressionStatement(visitExpression(node.init));
+      visitExpressionIgnoreResult(node.init);
     }
     int startLabel = newLabel("for condition");
     // If there is no update, continuing the loop is the same as going to the
@@ -1553,29 +1553,17 @@
 
   @override
   js.Expression visitVariableDeclarationList(js.VariableDeclarationList node) {
-    List<js.Expression> initializations = new List<js.Expression>();
-
-    // Declaration of local variables is hoisted outside the helper but the
-    // initialization is done here.
     for (js.VariableInitialization initialization in node.declarations) {
       js.VariableDeclaration declaration = initialization.declaration;
       localVariables.add(declaration);
       if (initialization.value != null) {
         withExpression(initialization.value, (js.Expression value) {
-          initializations.add(
+          addExpressionStatement(
               new js.Assignment(new js.VariableUse(declaration.name), value));
         }, store: false);
       }
     }
-    if (initializations.isEmpty) {
-      // Dummy expression. Will be dropped by [visitExpressionIgnoreResult].
-      return js.number(0);
-    } else {
-      return initializations.reduce(
-          (js.Expression first, js.Expression second) {
-        return new js.Binary(",", first, second);
-      });
-    }
+    return js.number(0); // Dummy expression.
   }
 
   @override
@@ -2457,12 +2445,12 @@
 
   @override
   bool visitStringConcatenation(js.StringConcatenation node) {
-    return true;
+    return false;
   }
 
   @override
   bool visitName(js.Name node) {
-    return true;
+    return false;
   }
 
   @override
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index 892f819..0fed323 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -220,43 +220,18 @@
 }
 
 class JavaScriptBackend extends Backend {
-  static final Uri DART_JS_HELPER = new Uri(scheme: 'dart', path: '_js_helper');
-  static final Uri DART_INTERCEPTORS =
-      new Uri(scheme: 'dart', path: '_interceptors');
-  static final Uri DART_FOREIGN_HELPER =
-      new Uri(scheme: 'dart', path: '_foreign_helper');
-  static final Uri DART_JS_MIRRORS =
-      new Uri(scheme: 'dart', path: '_js_mirrors');
-  static final Uri DART_JS_NAMES =
-      new Uri(scheme: 'dart', path: '_js_names');
-  static final Uri DART_EMBEDDED_NAMES =
-      new Uri(scheme: 'dart', path: '_js_embedded_names');
-  static final Uri DART_ISOLATE_HELPER =
-      new Uri(scheme: 'dart', path: '_isolate_helper');
-  static final Uri PACKAGE_JS =
-         new Uri(scheme: 'package', path: 'js/js.dart');
-  static final Uri PACKAGE_LOOKUP_MAP =
-      new Uri(scheme: 'package', path: 'lookup_map/lookup_map.dart');
-
-  static const String INVOKE_ON = '_getCachedInvocation';
-  static const String START_ROOT_ISOLATE = 'startRootIsolate';
-
-
   String get patchVersion => emitter.patchVersion;
 
   bool get supportsReflection => emitter.emitter.supportsReflection;
 
   final Annotations annotations;
 
-  /// Reference to the internal library to lookup functions to always inline.
-  LibraryElement internalLibrary;
-
 
   /// Set of classes that need to be considered for reflection although not
   /// otherwise visible during resolution.
   Iterable<ClassElement> get classesRequiredForReflection {
     // TODO(herhut): Clean this up when classes needed for rti are tracked.
-    return [closureClass, jsIndexableClass];
+    return [helpers.closureClass, helpers.jsIndexableClass];
   }
 
   FunctionCompiler functionCompiler;
@@ -272,75 +247,6 @@
 
   FunctionInlineCache inlineCache = new FunctionInlineCache();
 
-  LibraryElement jsHelperLibrary;
-  LibraryElement asyncLibrary;
-  LibraryElement interceptorsLibrary;
-  LibraryElement foreignLibrary;
-  LibraryElement isolateHelperLibrary;
-
-  ClassElement closureClass;
-  ClassElement boundClosureClass;
-  Element assertUnreachableMethod;
-  Element invokeOnMethod;
-
-  ClassElement jsInterceptorClass;
-  ClassElement jsStringClass;
-  ClassElement jsArrayClass;
-  ClassElement jsNumberClass;
-  ClassElement jsIntClass;
-  ClassElement jsDoubleClass;
-  ClassElement jsNullClass;
-  ClassElement jsBoolClass;
-  ClassElement jsPlainJavaScriptObjectClass;
-  ClassElement jsUnknownJavaScriptObjectClass;
-  ClassElement jsJavaScriptFunctionClass;
-  ClassElement jsJavaScriptObjectClass;
-
-  ClassElement jsIndexableClass;
-  ClassElement jsMutableIndexableClass;
-
-  ClassElement jsMutableArrayClass;
-  ClassElement jsFixedArrayClass;
-  ClassElement jsExtendableArrayClass;
-  ClassElement jsUnmodifiableArrayClass;
-  ClassElement jsPositiveIntClass;
-  ClassElement jsUInt32Class;
-  ClassElement jsUInt31Class;
-
-  Element jsIndexableLength;
-  Element jsArrayTypedConstructor;
-  Element jsArrayRemoveLast;
-  Element jsArrayAdd;
-  Element jsStringSplit;
-  Element jsStringToString;
-  Element jsStringOperatorAdd;
-  Element objectEquals;
-
-  ClassElement typeLiteralClass;
-  ClassElement mapLiteralClass;
-  ClassElement constMapLiteralClass;
-  ClassElement typeVariableClass;
-  ConstructorElement mapLiteralConstructor;
-  ConstructorElement mapLiteralConstructorEmpty;
-  Element mapLiteralUntypedMaker;
-  Element mapLiteralUntypedEmptyMaker;
-
-  ClassElement noSideEffectsClass;
-  ClassElement noThrowsClass;
-  ClassElement noInlineClass;
-  ClassElement forceInlineClass;
-  ClassElement irRepresentationClass;
-
-  ClassElement jsAnnotationClass;
-  ClassElement jsAnonymousClass;
-
-  Element getInterceptorMethod;
-
-  ClassElement jsInvocationMirrorClass;
-
-  ClassElement typedArrayClass;
-  ClassElement typedArrayOfIntClass;
-
   /// If [true], the compiler will emit code that logs whenever a method is
   /// called. When TRACE_METHOD is 'console' this will be logged
   /// directly in the JavaScript console. When TRACE_METHOD is 'post' the
@@ -365,8 +271,8 @@
   TypeMask _indexablePrimitiveTypeCache;
   TypeMask get indexablePrimitiveType {
     if (_indexablePrimitiveTypeCache == null) {
-      _indexablePrimitiveTypeCache =
-          new TypeMask.nonNullSubtype(jsIndexableClass, compiler.world);
+      _indexablePrimitiveTypeCache = new TypeMask.nonNullSubtype(
+          helpers.jsIndexableClass, compiler.world);
     }
     return _indexablePrimitiveTypeCache;
   }
@@ -374,8 +280,8 @@
   TypeMask _readableArrayTypeCache;
   TypeMask get readableArrayType {
     if (_readableArrayTypeCache == null) {
-      _readableArrayTypeCache = new TypeMask.nonNullSubclass(jsArrayClass,
-          compiler.world);
+      _readableArrayTypeCache = new TypeMask.nonNullSubclass(
+          helpers.jsArrayClass, compiler.world);
     }
     return _readableArrayTypeCache;
   }
@@ -383,8 +289,8 @@
   TypeMask _mutableArrayTypeCache;
   TypeMask get mutableArrayType {
     if (_mutableArrayTypeCache == null) {
-      _mutableArrayTypeCache = new TypeMask.nonNullSubclass(jsMutableArrayClass,
-          compiler.world);
+      _mutableArrayTypeCache = new TypeMask.nonNullSubclass(
+          helpers.jsMutableArrayClass, compiler.world);
     }
     return _mutableArrayTypeCache;
   }
@@ -392,8 +298,8 @@
   TypeMask _fixedArrayTypeCache;
   TypeMask get fixedArrayType {
     if (_fixedArrayTypeCache == null) {
-      _fixedArrayTypeCache = new TypeMask.nonNullExact(jsFixedArrayClass,
-          compiler.world);
+      _fixedArrayTypeCache = new TypeMask.nonNullExact(
+          helpers.jsFixedArrayClass, compiler.world);
     }
     return _fixedArrayTypeCache;
   }
@@ -401,8 +307,8 @@
   TypeMask _extendableArrayTypeCache;
   TypeMask get extendableArrayType {
     if (_extendableArrayTypeCache == null) {
-      _extendableArrayTypeCache =
-          new TypeMask.nonNullExact(jsExtendableArrayClass, compiler.world);
+      _extendableArrayTypeCache = new TypeMask.nonNullExact(
+          helpers.jsExtendableArrayClass, compiler.world);
     }
     return _extendableArrayTypeCache;
   }
@@ -410,8 +316,8 @@
   TypeMask _unmodifiableArrayTypeCache;
   TypeMask get unmodifiableArrayType {
     if (_unmodifiableArrayTypeCache == null) {
-      _unmodifiableArrayTypeCache =
-          new TypeMask.nonNullExact(jsUnmodifiableArrayClass, compiler.world);
+      _unmodifiableArrayTypeCache = new TypeMask.nonNullExact(
+          helpers.jsUnmodifiableArrayClass, compiler.world);
     }
     return _fixedArrayTypeCache;
   }
@@ -428,24 +334,12 @@
   /// Maps special classes to their implementation (JSXxx) class.
   Map<ClassElement, ClassElement> implementationClasses;
 
-  Element getNativeInterceptorMethod;
   bool needToInitializeIsolateAffinityTag = false;
   bool needToInitializeDispatchProperty = false;
 
-  /// Holds the method "getIsolateAffinityTag" when dart:_js_helper has been
-  /// loaded.
-  FunctionElement getIsolateAffinityTagMarker;
-
   final Namer namer;
 
   /**
-   * Interface used to determine if an object has the JavaScript
-   * indexing behavior. The interface is only visible to specific
-   * libraries.
-   */
-  ClassElement jsIndexingBehaviorInterface;
-
-  /**
    * A collection of selectors that must have a one shot interceptor
    * generated.
    */
@@ -516,35 +410,6 @@
   final RuntimeTypes rti;
   final RuntimeTypesEncoder rtiEncoder;
 
-  /// Holds the method "disableTreeShaking" in js_mirrors when
-  /// dart:mirrors has been loaded.
-  FunctionElement disableTreeShakingMarker;
-
-  /// Holds the method "preserveNames" in js_mirrors when
-  /// dart:mirrors has been loaded.
-  FunctionElement preserveNamesMarker;
-
-  /// Holds the method "preserveMetadata" in js_mirrors when
-  /// dart:mirrors has been loaded.
-  FunctionElement preserveMetadataMarker;
-
-  /// Holds the method "preserveUris" in js_mirrors when
-  /// dart:mirrors has been loaded.
-  FunctionElement preserveUrisMarker;
-
-  /// Holds the method "preserveLibraryNames" in js_mirrors when
-  /// dart:mirrors has been loaded.
-  FunctionElement preserveLibraryNamesMarker;
-
-  /// Holds the method "requiresPreamble" in _js_helper.
-  FunctionElement requiresPreambleMarker;
-
-  /// Holds the class for the [JsGetName] enum.
-  EnumClassElement jsGetNameEnum;
-
-  /// Holds the class for the [JsBuiltins] enum.
-  EnumClassElement jsBuiltinEnum;
-
   /// True if a call to preserveMetadataMarker has been seen.  This means that
   /// metadata must be retained for dart:mirrors to work correctly.
   bool mustRetainMetadata = false;
@@ -631,7 +496,7 @@
 
   JavaScriptConstantTask constantCompilerTask;
 
-  JavaScriptResolutionCallbacks resolutionCallbacks;
+  JavaScriptImpactTransformer impactTransformer;
 
   PatchResolverTask patchResolverTask;
 
@@ -670,7 +535,7 @@
 
     noSuchMethodRegistry = new NoSuchMethodRegistry(this);
     constantCompilerTask = new JavaScriptConstantTask(compiler);
-    resolutionCallbacks = new JavaScriptResolutionCallbacks(this);
+    impactTransformer = new JavaScriptImpactTransformer(this);
     patchResolverTask = new PatchResolverTask(compiler);
     functionCompiler = compiler.useCpsIr
          ? new CpsFunctionCompiler(
@@ -682,6 +547,10 @@
 
   DiagnosticReporter get reporter => compiler.reporter;
 
+  CoreClasses get coreClasses => compiler.coreClasses;
+
+  CoreTypes get coreTypes => compiler.coreTypes;
+
   Resolution get resolution => compiler.resolution;
 
   /// Returns constant environment for the JavaScript interpretation of the
@@ -691,30 +560,17 @@
   }
 
   FunctionElement resolveExternalFunction(FunctionElement element) {
-    if (isForeign(element) || element.isJsInterop) return element;
+    if (isForeign(element) || isJsInterop(element)) return element;
     return patchResolverTask.measure(() {
       return patchResolverTask.resolveExternalFunction(element);
     });
   }
 
-  // TODO(karlklose): Split into findHelperFunction and findHelperClass and
-  // add a check that the element has the expected kind.
-  Element findHelper(String name) => find(jsHelperLibrary, name);
-  Element findAsyncHelper(String name) => find(asyncLibrary, name);
-  Element findInterceptor(String name) => find(interceptorsLibrary, name);
-
-  Element find(LibraryElement library, String name) {
-    Element element = library.implementation.findLocal(name);
-    assert(invariant(library, element != null,
-        message: "Element '$name' not found in '${library.canonicalUri}'."));
-    return element;
-  }
-
-  bool isForeign(Element element) => element.library == foreignLibrary;
+  bool isForeign(Element element) => element.library == helpers.foreignLibrary;
 
   bool isBackendLibrary(LibraryElement library) {
-    return library == interceptorsLibrary ||
-           library == jsHelperLibrary;
+    return library == helpers.interceptorsLibrary ||
+           library == helpers.jsHelperLibrary;
   }
 
   static Namer determineNamer(Compiler compiler) {
@@ -756,7 +612,7 @@
 
   bool isInterceptorClass(ClassElement element) {
     if (element == null) return false;
-    if (Elements.isNativeOrExtendsNative(element)) return true;
+    if (isNativeOrExtendsNative(element)) return true;
     if (interceptedClasses.contains(element)) return true;
     if (classesMixedIntoInterceptedClasses.contains(element)) return true;
     return false;
@@ -799,10 +655,175 @@
     return aliasedSuperMembers.contains(member);
   }
 
+  /// The JavaScript names for elements implemented via typed JavaScript
+  /// interop.
+  Map<Element, String> jsInteropNames = <Element, String>{};
+
+  /// The JavaScript names for native JavaScript elements implemented.
+  Map<Element, String> nativeMemberName = <Element, String>{};
+
+  /// Tag info for native JavaScript classes names. See
+  /// [setNativeClassTagInfo].
+  Map<ClassElement, String> nativeClassTagInfo = <ClassElement, String>{};
+
+  /// Returns `true` if [element] is explicitly marked as part of JsInterop.
+  bool _isJsInterop(Element element) {
+    return jsInteropNames.containsKey(element.declaration);
+  }
+
+  /// Returns [element] as an explicit part of JsInterop. The js interop name is
+  /// expected to be computed later.
+  void markAsJsInterop(Element element) {
+    jsInteropNames[element.declaration] = null;
+  }
+
+  /// Sets the explicit js interop [name] for [element].
+  void setJsInteropName(Element element, String name) {
+    assert(invariant(element,
+        isJsInterop(element),
+        message:
+          'Element $element is not js interop but given a js interop name.'));
+    jsInteropNames[element.declaration] = name;
+  }
+
+  /// Returns the explicit js interop name for [element].
+  String getJsInteropName(Element element) {
+    return jsInteropNames[element.declaration];
+  }
+
+  /// Returns `true` if [element] is part of JsInterop.
+  @override
+  bool isJsInterop(Element element) {
+    // An function is part of JsInterop in the following cases:
+    // * It has a jsInteropName annotation
+    // * It is external member of a class or library tagged as JsInterop.
+    if (element.isFunction || element.isConstructor || element.isAccessor) {
+      FunctionElement function = element;
+      if (!function.isExternal) return false;
+
+      if (_isJsInterop(function)) return true;
+      if (function.isClassMember) return isJsInterop(function.contextClass);
+      if (function.isTopLevel) return isJsInterop(function.library);
+      return false;
+    } else {
+      return _isJsInterop(element);
+    }
+  }
+
+  /// Returns `true` if the name of [element] is fixed for the generated
+  /// JavaScript.
+  bool hasFixedBackendName(Element element) {
+    return isJsInterop(element) ||
+        nativeMemberName.containsKey(element.declaration);
+  }
+
+  String _jsNameHelper(Element element) {
+    String jsInteropName = jsInteropNames[element.declaration];
+    assert(invariant(element,
+        !(_isJsInterop(element) && jsInteropName == null),
+        message:
+            'Element $element is js interop but js interop name has not yet '
+            'been computed.'));
+    if (jsInteropName != null && jsInteropName.isNotEmpty) {
+      return jsInteropName;
+    }
+    return element.isLibrary ? 'self' : element.name;
+  }
+
+  /// Computes the name for [element] to use in the generated JavaScript. This
+  /// is either given through a native annotation or a js interop annotation.
+  String getFixedBackendName(Element element) {
+    String name = nativeMemberName[element.declaration];
+    if (name == null && isJsInterop(element)) {
+      // If an element isJsInterop but _isJsInterop is false that means it is
+      // considered interop as the parent class is interop.
+      name = _jsNameHelper(
+          element.isConstructor ? element.enclosingClass : element);
+      nativeMemberName[element.declaration] = name;
+    }
+    return name;
+  }
+
+  /// Whether [element] corresponds to a native JavaScript construct either
+  /// through the native mechanism (`@Native(...)` or the `native` pseudo
+  /// keyword) which is only allowed for internal libraries or via the typed
+  /// JavaScriptInterop mechanism which is allowed for user libraries.
+  @override
+  bool isNative(Element element) {
+    if (isJsInterop(element)) return true;
+    if (element.isClass) {
+      return nativeClassTagInfo.containsKey(element.declaration);
+    } else {
+      return nativeMemberName.containsKey(element.declaration);
+    }
+  }
+
+  /// Sets the native [name] for the member [element]. This name is used for
+  /// [element] in the generated JavaScript.
+  void setNativeMemberName(MemberElement element, String name) {
+    // TODO(johnniwinther): Avoid setting this more than once. The enqueuer
+    // might enqueue [element] several times (before processing it) and computes
+    // name on each call to `internalAddToWorkList`.
+    assert(invariant(element,
+        nativeMemberName[element.declaration] == null ||
+        nativeMemberName[element.declaration] == name,
+        message:
+          "Native member name set inconsistently on $element: "
+          "Existing name '${nativeMemberName[element.declaration]}', "
+          "new name '$name'."));
+    nativeMemberName[element.declaration] = name;
+  }
+
+  /// Sets the native tag info for [cls].
+  ///
+  /// The tag info string contains comma-separated 'words' which are either
+  /// dispatch tags (having JavaScript identifier syntax) and directives that
+  /// begin with `!`.
+  void setNativeClassTagInfo(ClassElement cls, String tagInfo) {
+    // TODO(johnniwinther): Assert that this is only called once. The memory
+    // compiler copies pre-processed elements into a new compiler through
+    // [Compiler.onLibraryScanned] and thereby causes multiple calls to this
+    // method.
+    assert(invariant(cls,
+        nativeClassTagInfo[cls.declaration] == null ||
+        nativeClassTagInfo[cls.declaration] == tagInfo,
+        message:
+          "Native tag info set inconsistently on $cls: "
+          "Existing tag info '${nativeClassTagInfo[cls.declaration]}', "
+          "new tag info '$tagInfo'."));
+    nativeClassTagInfo[cls.declaration] = tagInfo;
+  }
+
+  /// Returns the list of native tag words for [cls].
+  List<String> getNativeTagsOfClassRaw(ClassElement cls) {
+    String quotedName = nativeClassTagInfo[cls.declaration];
+    return quotedName.substring(1, quotedName.length - 1).split(',');
+  }
+
+  /// Returns the list of non-directive native tag words for [cls].
+  List<String> getNativeTagsOfClass(ClassElement cls) {
+    return getNativeTagsOfClassRaw(cls).where(
+        (s) => !s.startsWith('!')).toList();
+  }
+
+  /// Returns `true` if [cls] has a `!nonleaf` tag word.
+  bool hasNativeTagsForcedNonLeaf(ClassElement cls) {
+    return getNativeTagsOfClassRaw(cls).contains('!nonleaf');
+  }
+
+  bool isNativeOrExtendsNative(ClassElement element) {
+    if (element == null) return false;
+    if (isNative(element) || isJsInterop(element)) {
+      return true;
+    }
+    assert(element.isResolved);
+    return isNativeOrExtendsNative(element.superclass);
+  }
+
   bool isInterceptedMethod(Element element) {
     if (!element.isInstanceMember) return false;
     if (element.isGenerativeConstructorBody) {
-      return Elements.isNativeOrExtendsNative(element.enclosingClass);
+      return isNativeOrExtendsNative(element.enclosingClass);
     }
     return interceptedElements[element.name] != null;
   }
@@ -851,6 +872,26 @@
     });
   }
 
+  /// True if the given class is an internal class used for type inference
+  /// and never exists at runtime.
+  bool isCompileTimeOnlyClass(ClassElement class_) {
+    return class_ == helpers.jsPositiveIntClass ||
+           class_ == helpers.jsUInt32Class ||
+           class_ == helpers.jsUInt31Class ||
+           class_ == helpers.jsFixedArrayClass ||
+           class_ == helpers.jsUnmodifiableArrayClass ||
+           class_ == helpers.jsMutableArrayClass ||
+           class_ == helpers.jsExtendableArrayClass;
+  }
+
+  /// Maps compile-time classes to their runtime class.  The runtime class is
+  /// always a superclass or the class itself.
+  ClassElement getRuntimeClass(ClassElement class_) {
+    if (class_.isSubclassOf(helpers.jsIntClass)) return helpers.jsIntClass;
+    if (class_.isSubclassOf(helpers.jsArrayClass)) return helpers.jsArrayClass;
+    return class_;
+  }
+
   final Map<String, Set<ClassElement>> interceptedClassesCache =
       new Map<String, Set<ClassElement>>();
 
@@ -867,7 +908,8 @@
       Set<ClassElement> result = new Set<ClassElement>();
       for (Element element in intercepted) {
         ClassElement classElement = element.enclosingClass;
-        if (Elements.isNativeOrExtendsNative(classElement)
+        if (isCompileTimeOnlyClass(classElement)) continue;
+        if (isNativeOrExtendsNative(classElement)
             || interceptedClasses.contains(classElement)) {
           result.add(classElement);
         }
@@ -888,7 +930,7 @@
     for (MixinApplicationElement use in uses) {
       Iterable<ClassElement> subclasses = classWorld.strictSubclassesOf(use);
       for (ClassElement subclass in subclasses) {
-        if (Elements.isNativeOrExtendsNative(subclass)) {
+        if (isNativeOrExtendsNative(subclass)) {
           if (result == null) result = new Set<ClassElement>();
           result.add(subclass);
         }
@@ -906,7 +948,7 @@
       ClassElement interceptorClass) {
     if (interceptorClass == null) return;
     interceptorClass.ensureResolved(resolution);
-    compiler.objectClass.forEachMember((_, Element member) {
+    coreClasses.objectClass.forEachMember((_, Element member) {
       if (member.isGenerativeConstructor) return;
       Element interceptorMember = interceptorClass.lookupMember(member.name);
       // Interceptors must override all Object methods due to calling convention
@@ -928,7 +970,7 @@
         }
         if (member.isSynthesized) return;
         // All methods on [Object] are shadowed by [Interceptor].
-        if (classElement == compiler.objectClass) return;
+        if (classElement == coreClasses.objectClass) return;
         Set<Element> set = interceptedElements.putIfAbsent(
             member.name, () => new Set<Element>());
         set.add(member);
@@ -949,12 +991,12 @@
                        Enqueuer enqueuer,
                        Registry registry) {
     if (enqueuer.isResolutionQueue) {
-      _interceptedClasses.add(jsInterceptorClass);
+      _interceptedClasses.add(helpers.jsInterceptorClass);
       _interceptedClasses.add(cls);
       cls.ensureResolved(resolution);
       cls.forEachMember((ClassElement classElement, Element member) {
           // All methods on [Object] are shadowed by [Interceptor].
-          if (classElement == compiler.objectClass) return;
+          if (classElement == coreClasses.objectClass) return;
           Set<Element> set = interceptedElements.putIfAbsent(
               member.name, () => new Set<Element>());
           set.add(member);
@@ -971,7 +1013,7 @@
 
   void registerSpecializedGetInterceptor(Set<ClassElement> classes) {
     jsAst.Name name = namer.nameForGetInterceptor(classes);
-    if (classes.contains(jsInterceptorClass)) {
+    if (classes.contains(helpers.jsInterceptorClass)) {
       // We can't use a specialized [getInterceptorMethod], so we make
       // sure we emit the one with all checks.
       specializedGetInterceptors[name] = interceptedClasses;
@@ -980,8 +1022,7 @@
     }
   }
 
-  void registerCompileTimeConstant(ConstantValue constant, Registry registry,
-      {bool addForEmission: true}) {
+  void registerCompileTimeConstant(ConstantValue constant, Registry registry) {
     registerCompileTimeConstantInternal(constant, registry);
 
     if (!registry.isForResolution &&
@@ -992,11 +1033,12 @@
     }
 
     for (ConstantValue dependency in constant.getDependencies()) {
-      registerCompileTimeConstant(dependency, registry,
-          addForEmission: false);
+      registerCompileTimeConstant(dependency, registry);
     }
+  }
 
-    if (addForEmission) constants.addCompileTimeConstantForEmission(constant);
+  void addCompileTimeConstantForEmission(ConstantValue constant) {
+    constants.addCompileTimeConstantForEmission(constant);
   }
 
   void registerCompileTimeConstantInternal(ConstantValue constant,
@@ -1006,7 +1048,7 @@
 
     if (constant.isFunction) {
       FunctionConstantValue function = constant;
-      registry.registerGetOfStaticFunction(function.element);
+      registry.registerStaticUse(new StaticUse.staticTearOff(function.element));
     } else if (constant.isInterceptor) {
       // An interceptor constant references the class's prototype chain.
       InterceptorConstantValue interceptor = constant;
@@ -1020,17 +1062,24 @@
 
   void registerInstantiatedConstantType(DartType type, Registry registry) {
     DartType instantiatedType =
-        type.isFunctionType ? compiler.functionClass.rawType : type;
+        type.isFunctionType ? coreTypes.functionType : type;
     if (type is InterfaceType) {
       registry.registerInstantiation(instantiatedType);
       if (!type.treatAsRaw && classNeedsRti(type.element)) {
-        registry.registerStaticInvocation(helpers.setRuntimeTypeInfo);
+        registry.registerStaticUse(
+            new StaticUse.staticInvoke(
+                // TODO(johnniwinther): Find the right [CallStructure].
+                helpers.setRuntimeTypeInfo, null));
       }
       if (type.element == typeImplementation) {
         // If we use a type literal in a constant, the compile time
         // constant emitter will generate a call to the createRuntimeType
         // helper so we register a use of that.
-        registry.registerStaticInvocation(helpers.createRuntimeType);
+        registry.registerStaticUse(
+            new StaticUse.staticInvoke(
+                // TODO(johnniwinther): Find the right [CallStructure].
+
+                helpers.createRuntimeType, null));
       }
     }
   }
@@ -1040,7 +1089,7 @@
                                 Registry registry) {
     assert(registry.isForResolution);
     ConstantValue constant = constants.getConstantValueForMetadata(metadata);
-    registerCompileTimeConstant(constant, registry, addForEmission: false);
+    registerCompileTimeConstant(constant, registry);
     metadataConstants.add(new Dependency(constant, annotatedElement));
   }
 
@@ -1066,38 +1115,39 @@
 
     // Register any helper that will be needed by the backend.
     if (enqueuer.isResolutionQueue) {
-      if (cls == compiler.intClass
-          || cls == compiler.doubleClass
-          || cls == compiler.numClass) {
+      if (cls == coreClasses.intClass ||
+          cls == coreClasses.doubleClass ||
+          cls == coreClasses.numClass) {
         // The backend will try to optimize number operations and use the
         // `iae` helper directly.
-        enqueue(enqueuer, findHelper('iae'), registry);
-      } else if (cls == compiler.listClass
-                 || cls == compiler.stringClass) {
+        enqueue(enqueuer, helpers.throwIllegalArgumentException, registry);
+      } else if (cls == coreClasses.listClass ||
+                 cls == coreClasses.stringClass) {
         // The backend will try to optimize array and string access and use the
         // `ioore` and `iae` helpers directly.
-        enqueue(enqueuer, findHelper('ioore'), registry);
-        enqueue(enqueuer, findHelper('iae'), registry);
-      } else if (cls == compiler.functionClass) {
-        enqueueClass(enqueuer, closureClass, registry);
-      } else if (cls == compiler.mapClass) {
+        enqueue(enqueuer, helpers.throwIndexOutOfRangeException, registry);
+        enqueue(enqueuer, helpers.throwIllegalArgumentException, registry);
+      } else if (cls == coreClasses.functionClass) {
+        enqueueClass(enqueuer, helpers.closureClass, registry);
+      } else if (cls == coreClasses.mapClass) {
         // The backend will use a literal list to initialize the entries
         // of the map.
-        enqueueClass(enqueuer, compiler.listClass, registry);
-        enqueueClass(enqueuer, mapLiteralClass, registry);
+        enqueueClass(enqueuer, coreClasses.listClass, registry);
+        enqueueClass(enqueuer, helpers.mapLiteralClass, registry);
         // For map literals, the dependency between the implementation class
         // and [Map] is not visible, so we have to add it manually.
-        rti.registerRtiDependency(mapLiteralClass, cls);
-      } else if (cls == boundClosureClass) {
+        rti.registerRtiDependency(helpers.mapLiteralClass, cls);
+      } else if (cls == helpers.boundClosureClass) {
         // TODO(johnniwinther): Is this a noop?
-        enqueueClass(enqueuer, boundClosureClass, registry);
-      } else if (Elements.isNativeOrExtendsNative(cls)) {
-        enqueue(enqueuer, getNativeInterceptorMethod, registry);
-        enqueueClass(enqueuer, jsInterceptorClass, compiler.globalDependencies);
-        enqueueClass(enqueuer, jsJavaScriptObjectClass, registry);
-        enqueueClass(enqueuer, jsPlainJavaScriptObjectClass, registry);
-        enqueueClass(enqueuer, jsJavaScriptFunctionClass, registry);
-      } else if (cls == mapLiteralClass) {
+        enqueueClass(enqueuer, helpers.boundClosureClass, registry);
+      } else if (isNativeOrExtendsNative(cls)) {
+        enqueue(enqueuer, helpers.getNativeInterceptorMethod, registry);
+        enqueueClass(enqueuer, helpers.jsInterceptorClass,
+            compiler.globalDependencies);
+        enqueueClass(enqueuer, helpers.jsJavaScriptObjectClass, registry);
+        enqueueClass(enqueuer, helpers.jsPlainJavaScriptObjectClass, registry);
+        enqueueClass(enqueuer, helpers.jsJavaScriptFunctionClass, registry);
+      } else if (cls == helpers.mapLiteralClass) {
         // For map literals, the dependency between the implementation class
         // and [Map] is not visible, so we have to add it manually.
         Element getFactory(String name, int arity) {
@@ -1105,13 +1155,14 @@
           // have a patch class.
           ClassElement implementation = cls.patch != null ? cls.patch : cls;
           ConstructorElement ctor = implementation.lookupConstructor(name);
-          if (ctor == null
-              || (Name.isPrivateName(name)
-                  && ctor.library != mapLiteralClass.library)) {
-            reporter.internalError(mapLiteralClass,
-                                   "Map literal class $mapLiteralClass missing "
-                                   "'$name' constructor"
-                                   "  ${mapLiteralClass.constructors}");
+          if (ctor == null ||
+              (Name.isPrivateName(name) &&
+               ctor.library != helpers.mapLiteralClass.library)) {
+            reporter.internalError(
+                helpers.mapLiteralClass,
+                "Map literal class ${helpers.mapLiteralClass} missing "
+                "'$name' constructor"
+                "  ${helpers.mapLiteralClass.constructors}");
           }
           return ctor;
         }
@@ -1121,73 +1172,79 @@
           ClassElement implementation = cls.patch != null ? cls.patch : cls;
           Element element = implementation.lookupLocalMember(name);
           if (element == null || !element.isFunction || !element.isStatic) {
-            reporter.internalError(mapLiteralClass,
-                "Map literal class $mapLiteralClass missing "
+            reporter.internalError(helpers.mapLiteralClass,
+                "Map literal class ${helpers.mapLiteralClass} missing "
                 "'$name' static member function");
           }
           return element;
         }
-        mapLiteralConstructor = getFactory('_literal', 1);
-        mapLiteralConstructorEmpty = getFactory('_empty', 0);
-        enqueueInResolution(mapLiteralConstructor, registry);
-        enqueueInResolution(mapLiteralConstructorEmpty, registry);
+        helpers.mapLiteralConstructor = getFactory('_literal', 1);
+        helpers.mapLiteralConstructorEmpty = getFactory('_empty', 0);
+        enqueueInResolution(helpers.mapLiteralConstructor, registry);
+        enqueueInResolution(helpers.mapLiteralConstructorEmpty, registry);
 
-        mapLiteralUntypedMaker = getMember('_makeLiteral');
-        mapLiteralUntypedEmptyMaker = getMember('_makeEmpty');
-        enqueueInResolution(mapLiteralUntypedMaker, registry);
-        enqueueInResolution(mapLiteralUntypedEmptyMaker, registry);
+        helpers.mapLiteralUntypedMaker = getMember('_makeLiteral');
+        helpers.mapLiteralUntypedEmptyMaker = getMember('_makeEmpty');
+        enqueueInResolution(helpers.mapLiteralUntypedMaker, registry);
+        enqueueInResolution(helpers.mapLiteralUntypedEmptyMaker, registry);
       }
     }
-    if (cls == closureClass) {
-      enqueue(enqueuer, findHelper('closureFromTearOff'), registry);
+    if (cls == helpers.closureClass) {
+      enqueue(enqueuer, helpers.closureFromTearOff, registry);
     }
-    if (cls == compiler.stringClass || cls == jsStringClass) {
-      addInterceptors(jsStringClass, enqueuer, registry);
-    } else if (cls == compiler.listClass ||
-               cls == jsArrayClass ||
-               cls == jsFixedArrayClass ||
-               cls == jsExtendableArrayClass ||
-               cls == jsUnmodifiableArrayClass) {
-      addInterceptors(jsArrayClass, enqueuer, registry);
-      addInterceptors(jsMutableArrayClass, enqueuer, registry);
-      addInterceptors(jsFixedArrayClass, enqueuer, registry);
-      addInterceptors(jsExtendableArrayClass, enqueuer, registry);
-      addInterceptors(jsUnmodifiableArrayClass, enqueuer, registry);
-    } else if (cls == compiler.intClass || cls == jsIntClass) {
-      addInterceptors(jsIntClass, enqueuer, registry);
-      addInterceptors(jsPositiveIntClass, enqueuer, registry);
-      addInterceptors(jsUInt32Class, enqueuer, registry);
-      addInterceptors(jsUInt31Class, enqueuer, registry);
-      addInterceptors(jsNumberClass, enqueuer, registry);
-    } else if (cls == compiler.doubleClass || cls == jsDoubleClass) {
-      addInterceptors(jsDoubleClass, enqueuer, registry);
-      addInterceptors(jsNumberClass, enqueuer, registry);
-    } else if (cls == compiler.boolClass || cls == jsBoolClass) {
-      addInterceptors(jsBoolClass, enqueuer, registry);
-    } else if (cls == compiler.nullClass || cls == jsNullClass) {
-      addInterceptors(jsNullClass, enqueuer, registry);
-    } else if (cls == compiler.numClass || cls == jsNumberClass) {
-      addInterceptors(jsIntClass, enqueuer, registry);
-      addInterceptors(jsPositiveIntClass, enqueuer, registry);
-      addInterceptors(jsUInt32Class, enqueuer, registry);
-      addInterceptors(jsUInt31Class, enqueuer, registry);
-      addInterceptors(jsDoubleClass, enqueuer, registry);
-      addInterceptors(jsNumberClass, enqueuer, registry);
-    } else if (cls == jsJavaScriptObjectClass) {
-      addInterceptors(jsJavaScriptObjectClass, enqueuer, registry);
-    } else if (cls == jsPlainJavaScriptObjectClass) {
-      addInterceptors(jsPlainJavaScriptObjectClass, enqueuer, registry);
-    } else if (cls == jsUnknownJavaScriptObjectClass) {
-      addInterceptors(jsUnknownJavaScriptObjectClass, enqueuer, registry);
-    } else if (cls == jsJavaScriptFunctionClass) {
-      addInterceptors(jsJavaScriptFunctionClass, enqueuer, registry);
-    } else if (Elements.isNativeOrExtendsNative(cls)) {
+    if (cls == coreClasses.stringClass ||
+        cls == helpers.jsStringClass) {
+      addInterceptors(helpers.jsStringClass, enqueuer, registry);
+    } else if (cls == coreClasses.listClass ||
+               cls == helpers.jsArrayClass ||
+               cls == helpers.jsFixedArrayClass ||
+               cls == helpers.jsExtendableArrayClass ||
+               cls == helpers.jsUnmodifiableArrayClass) {
+      addInterceptors(helpers.jsArrayClass, enqueuer, registry);
+      addInterceptors(helpers.jsMutableArrayClass, enqueuer, registry);
+      addInterceptors(helpers.jsFixedArrayClass, enqueuer, registry);
+      addInterceptors(helpers.jsExtendableArrayClass, enqueuer, registry);
+      addInterceptors(helpers.jsUnmodifiableArrayClass, enqueuer, registry);
+    } else if (cls == coreClasses.intClass ||
+               cls == helpers.jsIntClass) {
+      addInterceptors(helpers.jsIntClass, enqueuer, registry);
+      addInterceptors(helpers.jsPositiveIntClass, enqueuer, registry);
+      addInterceptors(helpers.jsUInt32Class, enqueuer, registry);
+      addInterceptors(helpers.jsUInt31Class, enqueuer, registry);
+      addInterceptors(helpers.jsNumberClass, enqueuer, registry);
+    } else if (cls == coreClasses.doubleClass ||
+               cls == helpers.jsDoubleClass) {
+      addInterceptors(helpers.jsDoubleClass, enqueuer, registry);
+      addInterceptors(helpers.jsNumberClass, enqueuer, registry);
+    } else if (cls == coreClasses.boolClass ||
+               cls == helpers.jsBoolClass) {
+      addInterceptors(helpers.jsBoolClass, enqueuer, registry);
+    } else if (cls == coreClasses.nullClass ||
+               cls == helpers.jsNullClass) {
+      addInterceptors(helpers.jsNullClass, enqueuer, registry);
+    } else if (cls == coreClasses.numClass ||
+               cls == helpers.jsNumberClass) {
+      addInterceptors(helpers.jsIntClass, enqueuer, registry);
+      addInterceptors(helpers.jsPositiveIntClass, enqueuer, registry);
+      addInterceptors(helpers.jsUInt32Class, enqueuer, registry);
+      addInterceptors(helpers.jsUInt31Class, enqueuer, registry);
+      addInterceptors(helpers.jsDoubleClass, enqueuer, registry);
+      addInterceptors(helpers.jsNumberClass, enqueuer, registry);
+    } else if (cls == helpers.jsJavaScriptObjectClass) {
+      addInterceptors(helpers.jsJavaScriptObjectClass, enqueuer, registry);
+    } else if (cls == helpers.jsPlainJavaScriptObjectClass) {
+      addInterceptors(helpers.jsPlainJavaScriptObjectClass, enqueuer, registry);
+    } else if (cls == helpers.jsUnknownJavaScriptObjectClass) {
+      addInterceptors(helpers.jsUnknownJavaScriptObjectClass, enqueuer, registry);
+    } else if (cls == helpers.jsJavaScriptFunctionClass) {
+      addInterceptors(helpers.jsJavaScriptFunctionClass, enqueuer, registry);
+    } else if (isNativeOrExtendsNative(cls)) {
       addInterceptorsForNativeClassMembers(cls, enqueuer);
-    } else if (cls == jsIndexingBehaviorInterface) {
+    } else if (cls == helpers.jsIndexingBehaviorInterface) {
       // These two helpers are used by the emitter and the codegen.
       // Because we cannot enqueue elements at the time of emission,
       // we make sure they are always generated.
-      enqueue(enqueuer, findHelper('isJsIndexable'), registry);
+      enqueue(enqueuer, helpers.isJsIndexable, registry);
     }
 
     customElementsAnalysis.registerInstantiatedClass(cls, enqueuer);
@@ -1209,10 +1266,10 @@
     assert(!enqueuer.isResolutionQueue);
     if (!enqueuer.nativeEnqueuer.hasInstantiatedNativeClasses()) return;
     Registry registry = compiler.globalDependencies;
-    enqueue(enqueuer, getNativeInterceptorMethod, registry);
-    enqueueClass(enqueuer, jsJavaScriptObjectClass, registry);
-    enqueueClass(enqueuer, jsPlainJavaScriptObjectClass, registry);
-    enqueueClass(enqueuer, jsJavaScriptFunctionClass, registry);
+    enqueue(enqueuer, helpers.getNativeInterceptorMethod, registry);
+    enqueueClass(enqueuer, helpers.jsJavaScriptObjectClass, registry);
+    enqueueClass(enqueuer, helpers.jsPlainJavaScriptObjectClass, registry);
+    enqueueClass(enqueuer, helpers.jsJavaScriptFunctionClass, registry);
     needToInitializeIsolateAffinityTag = true;
     needToInitializeDispatchProperty = true;
   }
@@ -1222,27 +1279,27 @@
   }
 
   void enqueueHelpers(ResolutionEnqueuer world, Registry registry) {
-    assert(interceptorsLibrary != null);
+    assert(helpers.interceptorsLibrary != null);
     // TODO(ngeoffray): Not enqueuing those two classes currently make
     // the compiler potentially crash. However, any reasonable program
     // will instantiate those two classes.
-    addInterceptors(jsBoolClass, world, registry);
-    addInterceptors(jsNullClass, world, registry);
+    addInterceptors(helpers.jsBoolClass, world, registry);
+    addInterceptors(helpers.jsNullClass, world, registry);
     if (compiler.enableTypeAssertions) {
       // Unconditionally register the helper that checks if the
       // expression in an if/while/for is a boolean.
       // TODO(ngeoffray): Should we have the resolver register those instead?
-      Element e = findHelper('boolConversionCheck');
+      Element e = helpers.boolConversionCheck;
       if (e != null) enqueue(world, e, registry);
     }
 
     if (TRACE_CALLS) {
-      traceHelper = findHelper(
-          TRACE_METHOD == 'console' ? 'consoleTraceHelper' : 'postTraceHelper');
+      traceHelper = TRACE_METHOD == 'console'
+          ? helpers.consoleTraceHelper : helpers.postTraceHelper;
       assert(traceHelper != null);
       enqueueInResolution(traceHelper, registry);
     }
-    enqueueInResolution(assertUnreachableMethod, registry);
+    enqueueInResolution(helpers.assertUnreachableMethod, registry);
     registerCheckedModeHelpers(registry);
   }
 
@@ -1283,27 +1340,19 @@
     super.registerClosureWithFreeTypeVariables(closure, enqueuer, registry);
   }
 
-  /// Call during codegen if an instance of [closure] is being created.
-  void registerInstantiatedClosure(LocalFunctionElement closure,
-                                   CodegenRegistry registry) {
-    if (methodNeedsRti(closure)) {
-      registerComputeSignature(compiler.enqueuer.codegen, registry);
-    }
-  }
-
   void registerBoundClosure(Enqueuer enqueuer) {
-    boundClosureClass.ensureResolved(resolution);
+    helpers.boundClosureClass.ensureResolved(resolution);
     registerInstantiatedType(
-        boundClosureClass.rawType,
+        helpers.boundClosureClass.rawType,
         enqueuer,
         // Precise dependency is not important here.
         compiler.globalDependencies);
   }
 
   void registerGetOfStaticFunction(Enqueuer enqueuer) {
-    closureClass.ensureResolved(resolution);
+    helpers.closureClass.ensureResolved(resolution);
     registerInstantiatedType(
-        closureClass.rawType,
+        helpers.closureClass.rawType,
         enqueuer,
         compiler.globalDependencies);
   }
@@ -1320,42 +1369,7 @@
     enqueueInResolution(helpers.setRuntimeTypeInfo, registry);
     registerGetRuntimeTypeArgument(registry);
     enqueueInResolution(helpers.getRuntimeTypeInfo, registry);
-    enqueueClass(enqueuer, compiler.listClass, registry);
-  }
-
-  void registerIsCheckForCodegen(DartType type,
-                                 Enqueuer world,
-                                 Registry registry) {
-    assert(!registry.isForResolution);
-    type = type.unaliased;
-    enqueueClass(world, compiler.boolClass, registry);
-    bool inCheckedMode = compiler.enableTypeAssertions;
-    // [registerIsCheck] is also called for checked mode checks, so we
-    // need to register checked mode helpers.
-    if (inCheckedMode) {
-      // All helpers are added to resolution queue in enqueueHelpers. These
-      // calls to enqueueInResolution serve as assertions that the helper was
-      // in fact added.
-      // TODO(13155): Find a way to enqueue helpers lazily.
-      CheckedModeHelper helper = getCheckedModeHelper(type, typeCast: false);
-      if (helper != null) {
-        enqueue(world, helper.getElement(compiler), registry);
-      }
-      // We also need the native variant of the check (for DOM types).
-      helper = getNativeCheckedModeHelper(type, typeCast: false);
-      if (helper != null) {
-        enqueue(world, helper.getElement(compiler), registry);
-      }
-    }
-    if (!type.treatAsRaw || type.containsTypeVariables) {
-      enqueueClass(world, compiler.listClass, registry);
-    }
-    if (type.element != null && type.element.isNative) {
-      // We will neeed to add the "$is" and "$as" properties on the
-      // JavaScript object prototype, so we make sure
-      // [:defineProperty:] is compiled.
-      enqueue(world, findHelper('defineProperty'), registry);
-    }
+    enqueueClass(enqueuer, coreClasses.listClass, registry);
   }
 
   void registerTypeVariableBoundsSubtypeCheck(DartType typeArgument,
@@ -1366,7 +1380,8 @@
   void registerCheckDeferredIsLoaded(Registry registry) {
     enqueueInResolution(helpers.checkDeferredIsLoaded, registry);
     // Also register the types of the arguments passed to this method.
-    enqueueClass(compiler.enqueuer.resolution, compiler.stringClass, registry);
+    enqueueClass(
+        compiler.enqueuer.resolution, coreClasses.stringClass, registry);
   }
 
   void registerNoSuchMethod(FunctionElement noSuchMethod) {
@@ -1409,8 +1424,8 @@
 
   void enableNoSuchMethod(Enqueuer world) {
     enqueue(world, helpers.createInvocationMirror, compiler.globalDependencies);
-    world.registerInvocation(
-        new UniverseSelector(Selectors.noSuchMethod_, null));
+    world.registerDynamicUse(
+        new DynamicUse(Selectors.noSuchMethod_, null));
   }
 
   void enableIsolateSupport(Enqueuer enqueuer) {
@@ -1424,31 +1439,22 @@
       // The JavaScript backend of [Isolate.spawnUri] uses the same internal
       // implementation as [Isolate.spawn], and fails if it cannot look main up
       // by name.
-      enqueuer.registerGetOfStaticFunction(compiler.mainFunction);
+      enqueuer.registerStaticUse(
+          new StaticUse.staticTearOff(compiler.mainFunction));
     }
     if (enqueuer.isResolutionQueue) {
-      for (String name in const [START_ROOT_ISOLATE,
-                                 '_currentIsolate',
-                                 '_callInIsolate']) {
-        Element element = find(isolateHelperLibrary, name);
+
+      void enqueue(Element element) {
         enqueuer.addToWorkList(element);
         compiler.globalDependencies.registerDependency(element);
         helpersUsed.add(element.declaration);
       }
-    } else {
-      enqueuer.addToWorkList(find(isolateHelperLibrary, START_ROOT_ISOLATE));
-    }
-  }
 
-  void registerRequiredType(DartType type) {
-    // If [argument] has type variables or is a type variable, this method
-    // registers a RTI dependency between the class where the type variable is
-    // defined (that is the enclosing class of the current element being
-    // resolved) and the class of [type]. If the class of [type] requires RTI,
-    // then the class of the type variable does too.
-    ClassElement contextClass = Types.getClassContext(type);
-    if (contextClass != null) {
-      rti.registerRtiDependency(type.element, contextClass);
+      enqueue(helpers.startRootIsolate);
+      enqueue(helpers.currentIsolate);
+      enqueue(helpers.callInIsolate);
+    } else {
+      enqueuer.addToWorkList(helpers.startRootIsolate);
     }
   }
 
@@ -1463,9 +1469,9 @@
   bool isDefaultEqualityImplementation(Element element) {
     assert(element.name == '==');
     ClassElement classElement = element.enclosingClass;
-    return classElement == compiler.objectClass
-        || classElement == jsInterceptorClass
-        || classElement == jsNullClass;
+    return classElement == coreClasses.objectClass
+        || classElement == helpers.jsInterceptorClass
+        || classElement == helpers.jsNullClass;
   }
 
   bool methodNeedsRti(FunctionElement function) {
@@ -1560,26 +1566,29 @@
     if (compiler.elementHasCompileTimeError(element)) {
       generatedCode[element] = jsAst.js(
           "function () { throw new Error('Compile time error in $element') }");
-      return const WorldImpact();
+      return const CodegenImpact();
     }
     var kind = element.kind;
     if (kind == ElementKind.TYPEDEF) {
       return const WorldImpact();
     }
-    if (element.isConstructor && element.enclosingClass == jsNullClass) {
+    if (element.isConstructor &&
+        element.enclosingClass == helpers.jsNullClass) {
       // Work around a problem compiling JSNull's constructor.
-      return const WorldImpact();
+      return const CodegenImpact();
     }
     if (kind.category == ElementCategory.VARIABLE) {
       ConstantValue initialValue =
           constants.getConstantValueForVariable(element);
       if (initialValue != null) {
         registerCompileTimeConstant(initialValue, work.registry);
+        addCompileTimeConstantForEmission(initialValue);
         // We don't need to generate code for static or top-level
         // variables. For instance variables, we may need to generate
         // the checked setter.
         if (Elements.isStaticOrTopLevel(element)) {
-          return const WorldImpact();
+          return impactTransformer.transformCodegenImpact(
+              work.registry.worldImpact);
         }
       } else {
         // If the constant-handler was not able to produce a result we have to
@@ -1587,12 +1596,13 @@
         // the static variable.
         // We also need to register the use of the cyclic-error helper.
         compiler.enqueuer.codegen.registerStaticUse(
-            helpers.cyclicThrowHelper);
+            new StaticUse.staticInvoke(
+                helpers.cyclicThrowHelper, CallStructure.ONE_ARG));
       }
     }
 
     generatedCode[element] = functionCompiler.compile(work);
-    return const WorldImpact();
+    return impactTransformer.transformCodegenImpact(work.registry.worldImpact);
   }
 
   native.NativeEnqueuer nativeResolutionEnqueuer(Enqueuer world) {
@@ -1604,9 +1614,12 @@
   }
 
   ClassElement defaultSuperclass(ClassElement element) {
-    if (element.isJsInterop) return jsJavaScriptObjectClass;
+    if (isJsInterop(element)) {
+      return helpers.jsJavaScriptObjectClass;
+    }
     // Native classes inherit from Interceptor.
-    return element.isNative ? jsInterceptorClass : compiler.objectClass;
+    return isNative(element)
+        ? helpers.jsInterceptorClass : coreClasses.objectClass;
   }
 
   /**
@@ -1719,29 +1732,35 @@
       assert(!typeCast); // Cannot cast to void.
       if (nativeCheckOnly) return null;
       return 'voidTypeCheck';
-    } else if (element == jsStringClass || element == compiler.stringClass) {
+    } else if (element == helpers.jsStringClass ||
+               element == coreClasses.stringClass) {
       if (nativeCheckOnly) return null;
       return typeCast
           ? 'stringTypeCast'
           : 'stringTypeCheck';
-    } else if (element == jsDoubleClass || element == compiler.doubleClass) {
+    } else if (element == helpers.jsDoubleClass ||
+               element == coreClasses.doubleClass) {
       if (nativeCheckOnly) return null;
       return typeCast
           ? 'doubleTypeCast'
           : 'doubleTypeCheck';
-    } else if (element == jsNumberClass || element == compiler.numClass) {
+    } else if (element == helpers.jsNumberClass ||
+               element == coreClasses.numClass) {
       if (nativeCheckOnly) return null;
       return typeCast
           ? 'numTypeCast'
           : 'numTypeCheck';
-    } else if (element == jsBoolClass || element == compiler.boolClass) {
+    } else if (element == helpers.jsBoolClass ||
+               element == coreClasses.boolClass) {
       if (nativeCheckOnly) return null;
       return typeCast
           ? 'boolTypeCast'
           : 'boolTypeCheck';
-    } else if (element == jsIntClass || element == compiler.intClass
-               || element == jsUInt32Class || element == jsUInt31Class
-               || element == jsPositiveIntClass) {
+    } else if (element == helpers.jsIntClass ||
+               element == coreClasses.intClass ||
+               element == helpers.jsUInt32Class ||
+               element == helpers.jsUInt31Class ||
+               element == helpers.jsPositiveIntClass) {
       if (nativeCheckOnly) return null;
       return typeCast
           ? 'intTypeCast'
@@ -1766,7 +1785,8 @@
             ? 'stringSuperTypeCast'
             : 'stringSuperTypeCheck';
       }
-    } else if ((element == compiler.listClass || element == jsArrayClass) &&
+    } else if ((element == coreClasses.listClass ||
+                element == helpers.jsArrayClass) &&
                type.treatAsRaw) {
       if (nativeCheckOnly) return null;
       return typeCast
@@ -1815,7 +1835,7 @@
     // We register all the helpers in the resolution queue.
     // TODO(13155): Find a way to register fewer helpers.
     for (CheckedModeHelper helper in checkedModeHelpers) {
-      enqueueInResolution(helper.getElement(compiler), registry);
+      enqueueInResolution(helper.getStaticUse(compiler).element, registry);
     }
   }
 
@@ -1825,16 +1845,16 @@
    */
   bool hasDirectCheckFor(DartType type) {
     Element element = type.element;
-    return element == compiler.stringClass ||
-        element == compiler.boolClass ||
-        element == compiler.numClass ||
-        element == compiler.intClass ||
-        element == compiler.doubleClass ||
-        element == jsArrayClass ||
-        element == jsMutableArrayClass ||
-        element == jsExtendableArrayClass ||
-        element == jsFixedArrayClass ||
-        element == jsUnmodifiableArrayClass;
+    return element == coreClasses.stringClass ||
+        element == coreClasses.boolClass ||
+        element == coreClasses.numClass ||
+        element == coreClasses.intClass ||
+        element == coreClasses.doubleClass ||
+        element == helpers.jsArrayClass ||
+        element == helpers.jsMutableArrayClass ||
+        element == helpers.jsExtendableArrayClass ||
+        element == helpers.jsFixedArrayClass ||
+        element == helpers.jsUnmodifiableArrayClass;
   }
 
   bool mayGenerateInstanceofCheck(DartType type) {
@@ -1848,49 +1868,51 @@
   }
 
   bool isNullImplementation(ClassElement cls) {
-    return cls == jsNullClass;
+    return cls == helpers.jsNullClass;
   }
 
-  ClassElement get intImplementation => jsIntClass;
-  ClassElement get uint32Implementation => jsUInt32Class;
-  ClassElement get uint31Implementation => jsUInt31Class;
-  ClassElement get positiveIntImplementation => jsPositiveIntClass;
-  ClassElement get doubleImplementation => jsDoubleClass;
-  ClassElement get numImplementation => jsNumberClass;
-  ClassElement get stringImplementation => jsStringClass;
-  ClassElement get listImplementation => jsArrayClass;
-  ClassElement get constListImplementation => jsUnmodifiableArrayClass;
-  ClassElement get fixedListImplementation => jsFixedArrayClass;
-  ClassElement get growableListImplementation => jsExtendableArrayClass;
-  ClassElement get mapImplementation => mapLiteralClass;
-  ClassElement get constMapImplementation => constMapLiteralClass;
-  ClassElement get typeImplementation => typeLiteralClass;
-  ClassElement get boolImplementation => jsBoolClass;
-  ClassElement get nullImplementation => jsNullClass;
+  ClassElement get intImplementation => helpers.jsIntClass;
+  ClassElement get uint32Implementation => helpers.jsUInt32Class;
+  ClassElement get uint31Implementation => helpers.jsUInt31Class;
+  ClassElement get positiveIntImplementation => helpers.jsPositiveIntClass;
+  ClassElement get doubleImplementation => helpers.jsDoubleClass;
+  ClassElement get numImplementation => helpers.jsNumberClass;
+  ClassElement get stringImplementation => helpers.jsStringClass;
+  ClassElement get listImplementation => helpers.jsArrayClass;
+  ClassElement get constListImplementation => helpers.jsUnmodifiableArrayClass;
+  ClassElement get fixedListImplementation => helpers.jsFixedArrayClass;
+  ClassElement get growableListImplementation => helpers.jsExtendableArrayClass;
+  ClassElement get mapImplementation => helpers.mapLiteralClass;
+  ClassElement get constMapImplementation => helpers.constMapLiteralClass;
+  ClassElement get typeImplementation => helpers.typeLiteralClass;
+  ClassElement get boolImplementation => helpers.jsBoolClass;
+  ClassElement get nullImplementation => helpers.jsNullClass;
+  ClassElement get syncStarIterableImplementation => helpers.syncStarIterable;
+  ClassElement get asyncFutureImplementation => helpers.futureImplementation;
+  ClassElement get asyncStarStreamImplementation => helpers.controllerStream;
 
   void registerStaticUse(Element element, Enqueuer enqueuer) {
-    if (element == disableTreeShakingMarker) {
+    if (element == helpers.disableTreeShakingMarker) {
       compiler.disableTypeInferenceForMirrors = true;
       isTreeShakingDisabled = true;
-    } else if (element == preserveNamesMarker) {
+    } else if (element == helpers.preserveNamesMarker) {
       mustPreserveNames = true;
-    } else if (element == preserveMetadataMarker) {
+    } else if (element == helpers.preserveMetadataMarker) {
       mustRetainMetadata = true;
-    } else if (element == preserveUrisMarker) {
+    } else if (element == helpers.preserveUrisMarker) {
       if (compiler.preserveUris) mustPreserveUris = true;
-    } else if (element == preserveLibraryNamesMarker) {
+    } else if (element == helpers.preserveLibraryNamesMarker) {
       mustRetainLibraryNames = true;
-    } else if (element == getIsolateAffinityTagMarker) {
+    } else if (element == helpers.getIsolateAffinityTagMarker) {
       needToInitializeIsolateAffinityTag = true;
     } else if (element.isDeferredLoaderGetter) {
       // TODO(sigurdm): Create a function registerLoadLibraryAccess.
       if (compiler.loadLibraryFunction == null) {
-        compiler.loadLibraryFunction =
-            findHelper("_loadLibraryWrapper");
+        compiler.loadLibraryFunction = helpers.loadLibraryWrapper;
         enqueueInResolution(compiler.loadLibraryFunction,
                             compiler.globalDependencies);
       }
-    } else if (element == requiresPreambleMarker) {
+    } else if (element == helpers.requiresPreambleMarker) {
       requiresPreamble = true;
     }
     customElementsAnalysis.registerStaticUse(element, enqueuer);
@@ -1942,39 +1964,7 @@
   }
 
   void onLibraryCreated(LibraryElement library) {
-    Uri uri = library.canonicalUri;
-    if (uri == DART_JS_HELPER) {
-      jsHelperLibrary = library;
-    } else if (uri == Uris.dart_async) {
-      asyncLibrary = library;
-    } else if (uri == Uris.dart__internal) {
-      internalLibrary = library;
-    } else if (uri ==  DART_INTERCEPTORS) {
-      interceptorsLibrary = library;
-    } else if (uri ==  DART_FOREIGN_HELPER) {
-      foreignLibrary = library;
-    } else if (uri == DART_ISOLATE_HELPER) {
-      isolateHelperLibrary = library;
-    }
-  }
-
-  void initializeHelperClasses() {
-    final List missingHelperClasses = [];
-    ClassElement lookupHelperClass(String name) {
-      ClassElement result = findHelper(name);
-      if (result == null) {
-        missingHelperClasses.add(name);
-      }
-      return result;
-    }
-    jsInvocationMirrorClass = lookupHelperClass('JSInvocationMirror');
-    boundClosureClass = lookupHelperClass('BoundClosure');
-    closureClass = lookupHelperClass('Closure');
-    if (!missingHelperClasses.isEmpty) {
-      reporter.internalError(jsHelperLibrary,
-          'dart:_js_helper library does not contain required classes: '
-          '$missingHelperClasses');
-    }
+    helpers.onLibraryCreated(library);
   }
 
   Future onLibraryScanned(LibraryElement library, LibraryLoader loader) {
@@ -1990,84 +1980,12 @@
         }
       }
     }).then((_) {
+      helpers.onLibraryScanned(library);
       Uri uri = library.canonicalUri;
-
-      FunctionElement findMethod(String name) {
-        return find(library, name);
-      }
-
-      ClassElement findClass(String name) {
-        return find(library, name);
-      }
-
-      if (uri == DART_INTERCEPTORS) {
-        getInterceptorMethod = findMethod('getInterceptor');
-        getNativeInterceptorMethod = findMethod('getNativeInterceptor');
-        jsInterceptorClass = findClass('Interceptor');
-        jsStringClass = findClass('JSString');
-        jsArrayClass = findClass('JSArray');
-        // The int class must be before the double class, because the
-        // emitter relies on this list for the order of type checks.
-        jsIntClass = findClass('JSInt');
-        jsPositiveIntClass = findClass('JSPositiveInt');
-        jsUInt32Class = findClass('JSUInt32');
-        jsUInt31Class = findClass('JSUInt31');
-        jsDoubleClass = findClass('JSDouble');
-        jsNumberClass = findClass('JSNumber');
-        jsNullClass = findClass('JSNull');
-        jsBoolClass = findClass('JSBool');
-        jsMutableArrayClass = findClass('JSMutableArray');
-        jsFixedArrayClass = findClass('JSFixedArray');
-        jsExtendableArrayClass = findClass('JSExtendableArray');
-        jsUnmodifiableArrayClass = findClass('JSUnmodifiableArray');
-        jsPlainJavaScriptObjectClass = findClass('PlainJavaScriptObject');
-        jsJavaScriptObjectClass = findClass('JavaScriptObject');
-        jsJavaScriptFunctionClass = findClass('JavaScriptFunction');
-        jsUnknownJavaScriptObjectClass = findClass('UnknownJavaScriptObject');
-        jsIndexableClass = findClass('JSIndexable');
-        jsMutableIndexableClass = findClass('JSMutableIndexable');
-      } else if (uri == DART_JS_HELPER) {
-        initializeHelperClasses();
-        helpers.assertTest = findHelper('assertTest');
-        helpers.assertThrow = findHelper('assertThrow');
-        helpers.assertHelper = findHelper('assertHelper');
-        assertUnreachableMethod = findHelper('assertUnreachable');
-
-        typeLiteralClass = findClass('TypeImpl');
-        constMapLiteralClass = findClass('ConstantMap');
-        typeVariableClass = findClass('TypeVariable');
-
-        jsIndexingBehaviorInterface = findClass('JavaScriptIndexingBehavior');
-
-        noSideEffectsClass = findClass('NoSideEffects');
-        noThrowsClass = findClass('NoThrows');
-        noInlineClass = findClass('NoInline');
-        forceInlineClass = findClass('ForceInline');
-        irRepresentationClass = findClass('IrRepresentation');
-
-        getIsolateAffinityTagMarker = findMethod('getIsolateAffinityTag');
-
-        requiresPreambleMarker = findMethod('requiresPreamble');
-      } else if (uri == DART_JS_MIRRORS) {
-        disableTreeShakingMarker = find(library, 'disableTreeShaking');
-        preserveMetadataMarker = find(library, 'preserveMetadata');
-        preserveUrisMarker = find(library, 'preserveUris');
-        preserveLibraryNamesMarker = find(library, 'preserveLibraryNames');
-      } else if (uri == DART_JS_NAMES) {
-        preserveNamesMarker = find(library, 'preserveNames');
-      } else if (uri == DART_EMBEDDED_NAMES) {
-        jsGetNameEnum = find(library, 'JsGetName');
-        jsBuiltinEnum = find(library, 'JsBuiltin');
-      } else if (uri == Uris.dart_html) {
+      if (uri == Uris.dart_html) {
         htmlLibraryIsLoaded = true;
-      } else if (uri == PACKAGE_LOOKUP_MAP) {
+      } else if (uri == LookupMapAnalysis.PACKAGE_LOOKUP_MAP) {
         lookupMapAnalysis.init(library);
-      } else if (uri == Uris.dart__native_typed_data) {
-        typedArrayClass = findClass('NativeTypedArray');
-        typedArrayOfIntClass = findClass('NativeTypedArrayOfInt');
-      } else if (uri == PACKAGE_JS) {
-        jsAnnotationClass = find(library, 'JS');
-        jsAnonymousClass = find(library, '_Anonymous');
       }
       annotations.onLibraryScanned(library);
     });
@@ -2078,74 +1996,29 @@
       return new Future.value();
     }
 
-    assert(loadedLibraries.containsLibrary(Uris.dart_core));
-    assert(loadedLibraries.containsLibrary(DART_INTERCEPTORS));
-    assert(loadedLibraries.containsLibrary(DART_JS_HELPER));
-
-    if (jsInvocationMirrorClass != null) {
-      jsInvocationMirrorClass.ensureResolved(resolution);
-      invokeOnMethod = jsInvocationMirrorClass.lookupLocalMember(INVOKE_ON);
-    }
-
-    // [LinkedHashMap] is reexported from dart:collection and can therefore not
-    // be loaded from dart:core in [onLibraryScanned].
-    mapLiteralClass = compiler.coreLibrary.find('LinkedHashMap');
-    assert(invariant(compiler.coreLibrary, mapLiteralClass != null,
-        message: "Element 'LinkedHashMap' not found in 'dart:core'."));
+    helpers.onLibrariesLoaded(loadedLibraries);
 
     implementationClasses = <ClassElement, ClassElement>{};
-    implementationClasses[compiler.intClass] = jsIntClass;
-    implementationClasses[compiler.boolClass] = jsBoolClass;
-    implementationClasses[compiler.numClass] = jsNumberClass;
-    implementationClasses[compiler.doubleClass] = jsDoubleClass;
-    implementationClasses[compiler.stringClass] = jsStringClass;
-    implementationClasses[compiler.listClass] = jsArrayClass;
-    implementationClasses[compiler.nullClass] = jsNullClass;
+    implementationClasses[coreClasses.intClass] = helpers.jsIntClass;
+    implementationClasses[coreClasses.boolClass] = helpers.jsBoolClass;
+    implementationClasses[coreClasses.numClass] = helpers.jsNumberClass;
+    implementationClasses[coreClasses.doubleClass] = helpers.jsDoubleClass;
+    implementationClasses[coreClasses.stringClass] = helpers.jsStringClass;
+    implementationClasses[coreClasses.listClass] = helpers.jsArrayClass;
+    implementationClasses[coreClasses.nullClass] = helpers.jsNullClass;
 
     // These methods are overwritten with generated versions.
-    inlineCache.markAsNonInlinable(getInterceptorMethod, insideLoop: true);
-
-    // TODO(kasperl): Some tests do not define the special JSArray
-    // subclasses, so we check to see if they are defined before
-    // trying to resolve them.
-    if (jsFixedArrayClass != null) {
-      jsFixedArrayClass.ensureResolved(resolution);
-    }
-    if (jsExtendableArrayClass != null) {
-      jsExtendableArrayClass.ensureResolved(resolution);
-    }
-    if (jsUnmodifiableArrayClass != null) {
-      jsUnmodifiableArrayClass.ensureResolved(resolution);
-    }
-
-    jsIndexableClass.ensureResolved(resolution);
-    jsIndexableLength = compiler.lookupElementIn(
-        jsIndexableClass, 'length');
-    if (jsIndexableLength != null && jsIndexableLength.isAbstractField) {
-      AbstractFieldElement element = jsIndexableLength;
-      jsIndexableLength = element.getter;
-    }
-
-    jsArrayClass.ensureResolved(resolution);
-    jsArrayTypedConstructor = compiler.lookupElementIn(jsArrayClass, 'typed');
-    jsArrayRemoveLast = compiler.lookupElementIn(jsArrayClass, 'removeLast');
-    jsArrayAdd = compiler.lookupElementIn(jsArrayClass, 'add');
-
-    jsStringClass.ensureResolved(resolution);
-    jsStringSplit = compiler.lookupElementIn(jsStringClass, 'split');
-    jsStringOperatorAdd = compiler.lookupElementIn(jsStringClass, '+');
-    jsStringToString = compiler.lookupElementIn(jsStringClass, 'toString');
-
-    objectEquals = compiler.lookupElementIn(compiler.objectClass, '==');
+    inlineCache.markAsNonInlinable(
+        helpers.getInterceptorMethod, insideLoop: true);
 
     specialOperatorEqClasses
-        ..add(compiler.objectClass)
-        ..add(jsInterceptorClass)
-        ..add(jsNullClass);
+        ..add(coreClasses.objectClass)
+        ..add(helpers.jsInterceptorClass)
+        ..add(helpers.jsNullClass);
 
-    validateInterceptorImplementsAllObjectMethods(jsInterceptorClass);
+    validateInterceptorImplementsAllObjectMethods(helpers.jsInterceptorClass);
     // The null-interceptor must also implement *all* methods.
-    validateInterceptorImplementsAllObjectMethods(jsNullClass);
+    validateInterceptorImplementsAllObjectMethods(helpers.jsNullClass);
 
     return new Future.value();
   }
@@ -2358,11 +2231,11 @@
     // As we do not think about closures as classes, yet, we have to make sure
     // their superclasses are available for reflection manually.
     if (foundClosure) {
-      reflectableMembers.add(closureClass);
+      reflectableMembers.add(helpers.closureClass);
     }
     Set<Element> closurizedMembers = compiler.resolverWorld.closurizedMembers;
     if (closurizedMembers.any(reflectableMembers.contains)) {
-      reflectableMembers.add(boundClosureClass);
+      reflectableMembers.add(helpers.boundClosureClass);
     }
     // Add typedefs.
     reflectableMembers
@@ -2398,7 +2271,7 @@
         new jsAst.PropertyAccess(use2, dispatchProperty);
 
     List<jsAst.Expression> arguments = <jsAst.Expression>[use1, record];
-    FunctionElement helper = findHelper('isJsIndexable');
+    FunctionElement helper = helpers.isJsIndexable;
     jsAst.Expression helperExpression = emitter.staticFunctionAccess(helper);
     return new jsAst.Call(helperExpression, arguments);
   }
@@ -2411,7 +2284,7 @@
         compiler.typedDataClass != null &&
         compiler.world.isInstantiated(compiler.typedDataClass) &&
         mask.satisfies(compiler.typedDataClass, compiler.world) &&
-        mask.satisfies(jsIndexingBehaviorInterface, compiler.world);
+        mask.satisfies(helpers.jsIndexingBehaviorInterface, compiler.world);
   }
 
   bool couldBeTypedArray(TypeMask mask) {
@@ -2425,7 +2298,7 @@
         intersects(mask,
             new TypeMask.subtype(compiler.typedDataClass, compiler.world)) &&
         intersects(mask,
-            new TypeMask.subtype(jsIndexingBehaviorInterface, compiler.world));
+            new TypeMask.subtype(helpers.jsIndexingBehaviorInterface, compiler.world));
   }
 
   /// Returns all static fields that are referenced through [targetsUsed].
@@ -2472,7 +2345,7 @@
 
     if (compiler.hasIncrementalSupport) {
       // Always enable tear-off closures during incremental compilation.
-      Element e = findHelper('closureFromTearOff');
+      Element e = helpers.closureFromTearOff;
       if (e != null && !enqueuer.isProcessed(e)) {
         registerBackendUse(e);
         enqueuer.addToWorkList(e);
@@ -2498,22 +2371,12 @@
       reporter.log('Retaining metadata.');
 
       compiler.libraryLoader.libraries.forEach(retainMetadataOf);
-      if (enqueuer.isResolutionQueue) {
-        for (Dependency dependency in metadataConstants) {
-          registerCompileTimeConstant(
-              dependency.constant,
-              new EagerRegistry(compiler,
-                  dependency.annotatedElement.analyzableElement.treeElements),
-              addForEmission: false);
-        }
-      } else {
-        for (Dependency dependency in metadataConstants) {
-          registerCompileTimeConstant(
-              dependency.constant,
-              new CodegenRegistry(compiler,
-                  dependency.annotatedElement.analyzableElement.treeElements),
-              addForEmission: false);
-        }
+      for (Dependency dependency in metadataConstants) {
+        registerCompileTimeConstant(
+            dependency.constant,
+            new EagerRegistry('EagerRegistry for ${dependency}', enqueuer));
+      }
+      if (!enqueuer.isResolutionQueue) {
         metadataConstants.clear();
       }
     }
@@ -2530,13 +2393,13 @@
   }
 
   void onElementResolved(Element element, TreeElements elements) {
-    if ((element.isFunction || element.isGenerativeConstructor) &&
+    if ((element.isFunction || element.isConstructor) &&
         annotations.noInline(element)) {
       inlineCache.markAsNonInlinable(element);
     }
 
     LibraryElement library = element.library;
-    if (!library.isPlatformLibrary && !library.canUseNative) return;
+    if (!library.isPlatformLibrary && !canLibraryUseNative(library)) return;
     bool hasNoInline = false;
     bool hasForceInline = false;
     bool hasNoThrows = false;
@@ -2548,7 +2411,7 @@
       if (!constantValue.isConstructedObject) continue;
       ObjectConstantValue value = constantValue;
       ClassElement cls = value.type.element;
-      if (cls == forceInlineClass) {
+      if (cls == helpers.forceInlineClass) {
         hasForceInline = true;
         if (VERBOSE_OPTIMIZER_HINTS) {
           reporter.reportHintMessage(
@@ -2557,7 +2420,7 @@
               {'text': "Must inline"});
         }
         inlineCache.markAsMustInline(element);
-      } else if (cls == noInlineClass) {
+      } else if (cls == helpers.noInlineClass) {
         hasNoInline = true;
         if (VERBOSE_OPTIMIZER_HINTS) {
           reporter.reportHintMessage(
@@ -2566,12 +2429,13 @@
               {'text': "Cannot inline"});
         }
         inlineCache.markAsNonInlinable(element);
-      } else if (cls == noThrowsClass) {
+      } else if (cls == helpers.noThrowsClass) {
         hasNoThrows = true;
-        if (!Elements.isStaticOrTopLevelFunction(element)) {
+        if (!Elements.isStaticOrTopLevelFunction(element) &&
+            !element.isFactoryConstructor) {
           reporter.internalError(element,
               "@NoThrows() is currently limited to top-level"
-              " or static functions");
+              " or static functions and factory constructors.");
         }
         if (VERBOSE_OPTIMIZER_HINTS) {
           reporter.reportHintMessage(
@@ -2580,7 +2444,7 @@
               {'text': "Cannot throw"});
         }
         compiler.world.registerCannotThrow(element);
-      } else if (cls == noSideEffectsClass) {
+      } else if (cls == helpers.noSideEffectsClass) {
         hasNoSideEffects = true;
         if (VERBOSE_OPTIMIZER_HINTS) {
           reporter.reportHintMessage(
@@ -2603,7 +2467,7 @@
       reporter.internalError(element,
           "@NoSideEffects() should always be combined with @NoInline.");
     }
-    if (element == invokeOnMethod) {
+    if (element == helpers.invokeOnMethod) {
       compiler.enabledInvokeOn = true;
     }
   }
@@ -2614,13 +2478,11 @@
         : null;
   }
 
-  FunctionElement helperForBadMain() => findHelper('badMain');
+  FunctionElement helperForBadMain() => helpers.badMain;
 
-  FunctionElement helperForMissingMain() => findHelper('missingMain');
+  FunctionElement helperForMissingMain() => helpers.missingMain;
 
-  FunctionElement helperForMainArity() {
-    return findHelper('mainHasTooManyParameters');
-  }
+  FunctionElement helperForMainArity() => helpers.mainHasTooManyParameters;
 
   void forgetElement(Element element) {
     constants.forgetElement(element);
@@ -2650,33 +2512,6 @@
     return "${outName}_$name$extension";
   }
 
-  void registerAsyncMarker(FunctionElement element,
-                           Enqueuer enqueuer,
-                           Registry registry) {
-    if (element.asyncMarker == AsyncMarker.ASYNC) {
-      _registerAsync(enqueuer, registry);
-    } else if (element.asyncMarker == AsyncMarker.SYNC_STAR) {
-      _registerSyncStar(enqueuer, registry);
-    } else if (element.asyncMarker == AsyncMarker.ASYNC_STAR) {
-      _registerAsyncStar(enqueuer, registry);
-    }
-  }
-
-  void _registerAsync(Enqueuer enqueuer,
-                      Registry registry) {
-    enqueueImpact(enqueuer, impacts.asyncBody, registry);
-  }
-
-  void _registerSyncStar(Enqueuer enqueuer,
-                         Registry registry) {
-    enqueueImpact(enqueuer, impacts.syncStarBody, registry);
-  }
-
-  void _registerAsyncStar(Enqueuer enqueuer,
-                          Registry registry) {
-    enqueueImpact(enqueuer, impacts.asyncStarBody, registry);
-  }
-
   @override
   bool enableDeferredLoadingIfSupported(Spannable node, Registry registry) {
     registerCheckDeferredIsLoaded(registry);
@@ -2754,6 +2589,28 @@
     }
     return rewriter.rewrite(code);
   }
+
+  /// The locations of js patch-files relative to the sdk-descriptors.
+  static const _patchLocations = const <String, String>{
+    "async": "_internal/js_runtime/lib/async_patch.dart",
+    "collection":  "_internal/js_runtime/lib/collection_patch.dart",
+    "convert": "_internal/js_runtime/lib/convert_patch.dart",
+    "core": "_internal/js_runtime/lib/core_patch.dart",
+    "developer": "_internal/js_runtime/lib/developer_patch.dart",
+    "io": "_internal/js_runtime/lib/io_patch.dart",
+    "isolate": "_internal/js_runtime/lib/isolate_patch.dart",
+    "math": "_internal/js_runtime/lib/math_patch.dart",
+    "mirrors": "_internal/js_runtime/lib/mirrors_patch.dart",
+    "typed_data": "_internal/js_runtime/lib/typed_data_patch.dart",
+    "_internal": "_internal/js_runtime/lib/internal_patch.dart"
+  };
+
+  @override
+  Uri resolvePatchUri(String libraryName, Uri platformConfigUri) {
+    String patchLocation = _patchLocations[libraryName];
+    if (patchLocation == null) return null;
+    return platformConfigUri.resolve(patchLocation);
+  }
 }
 
 /// Handling of special annotations for tests.
@@ -2795,7 +2652,7 @@
       // TODO(floitsch): restrict to elements from the test directory.
       return true;
     }
-    return _hasAnnotation(element, backend.noInlineClass);
+    return _hasAnnotation(element, backend.helpers.noInlineClass);
   }
 
   /// Returns `true` if parameter and returns types should be trusted for
@@ -2830,14 +2687,15 @@
   }
 }
 
-class JavaScriptResolutionCallbacks extends ResolutionCallbacks {
+class JavaScriptImpactTransformer extends ImpactTransformer {
   final JavaScriptBackend backend;
 
-  JavaScriptResolutionCallbacks(this.backend);
+  JavaScriptImpactTransformer(this.backend);
 
   BackendImpacts get impacts => backend.impacts;
 
-  WorldImpact transformImpact(ResolutionImpact worldImpact) {
+  @override
+  WorldImpact transformResolutionImpact(ResolutionImpact worldImpact) {
     TransformedWorldImpact transformed =
         new TransformedWorldImpact(worldImpact);
     for (Feature feature in worldImpact.features) {
@@ -2885,6 +2743,9 @@
         case Feature.STRING_INTERPOLATION:
           registerBackendImpact(transformed, impacts.stringInterpolation);
           break;
+        case Feature.STRING_JUXTAPOSITION:
+          registerBackendImpact(transformed, impacts.stringJuxtaposition);
+          break;
         case Feature.SUPER_NO_SUCH_METHOD:
           registerBackendImpact(transformed, impacts.superNoSuchMethod);
           break;
@@ -2911,25 +2772,53 @@
           break;
       }
     }
-    for (DartType type in worldImpact.isChecks) {
-      onIsCheck(type, transformed);
+
+    bool hasAsCast = false;
+    bool hasTypeLiteral = false;
+    for (TypeUse typeUse in worldImpact.typeUses) {
+      DartType type = typeUse.type;
+      switch (typeUse.kind) {
+        case TypeUseKind.INSTANTIATION:
+          registerRequiredType(type);
+          break;
+        case TypeUseKind.IS_CHECK:
+          onIsCheck(type, transformed);
+          break;
+        case TypeUseKind.AS_CAST:
+          onIsCheck(type, transformed);
+          hasAsCast = true;
+          break;
+        case TypeUseKind.CHECKED_MODE_CHECK:
+          if (backend.compiler.enableTypeAssertions) {
+            onIsCheck(type, transformed);
+          }
+          break;
+        case TypeUseKind.CATCH_TYPE:
+          onIsCheck(type, transformed);
+          break;
+        case TypeUseKind.TYPE_LITERAL:
+          backend.customElementsAnalysis.registerTypeLiteral(type);
+          if (type.isTypedef) {
+            backend.compiler.world.allTypedefs.add(type.element);
+          }
+          if (type.isTypeVariable) {
+            ClassElement cls = type.element.enclosingClass;
+            backend.rti.registerClassUsingTypeVariableExpression(cls);
+            registerBackendImpact(transformed, impacts.typeVariableExpression);
+          }
+          hasTypeLiteral = true;
+          break;
+      }
     }
 
-    if (worldImpact.asCasts.isNotEmpty) {
-      for (DartType type in worldImpact.asCasts) {
-        onIsCheck(type, transformed);
-      }
+    if (hasAsCast) {
       registerBackendImpact(transformed, impacts.asCheck);
     }
 
-    if (backend.compiler.enableTypeAssertions) {
-      for (DartType type in worldImpact.checkedModeChecks) {
-        onIsCheck(type, transformed);
-      }
-    }
-
-    for (DartType requiredType in worldImpact.requiredTypes) {
-      backend.registerRequiredType(requiredType);
+    if (hasTypeLiteral) {
+      transformed.registerTypeUse(new TypeUse.instantiation(
+          backend.compiler.coreTypes.typeType));
+      registerBackendImpact(transformed, impacts.typeLiteral);
     }
 
     for (MapLiteralUse mapLiteralUse in worldImpact.mapLiterals) {
@@ -2938,51 +2827,61 @@
       if (mapLiteralUse.isConstant) {
         registerBackendImpact(transformed, impacts.constantMapLiteral);
       } else {
-        transformed.registerInstantiatedType(mapLiteralUse.type);
+        transformed.registerTypeUse(
+            new TypeUse.instantiation(mapLiteralUse.type));
       }
+      registerRequiredType(mapLiteralUse.type);
     }
 
     for (ListLiteralUse listLiteralUse in worldImpact.listLiterals) {
       // TODO(johnniwinther): Use the [isConstant] and [isEmpty] property when
       // factory constructors are registered directly.
-      transformed.registerInstantiatedType(listLiteralUse.type);
+      transformed.registerTypeUse(
+          new TypeUse.instantiation(listLiteralUse.type));
+      registerRequiredType(listLiteralUse.type);
     }
 
-    if (worldImpact.typeLiterals.isNotEmpty) {
-      transformed.registerInstantiatedType(backend.compiler.coreTypes.typeType);
-      registerBackendImpact(transformed, impacts.typeLiteral);
-      for (DartType typeLiteral in worldImpact.typeLiterals) {
-        backend.customElementsAnalysis.registerTypeLiteral(typeLiteral);
-        if (typeLiteral.isTypedef) {
-          backend.compiler.world.allTypedefs.add(typeLiteral.element);
-        }
-        if (typeLiteral.isTypeVariable) {
-          ClassElement cls = typeLiteral.element.enclosingClass;
-          backend.rti.registerClassUsingTypeVariableExpression(cls);
-          registerBackendImpact(transformed, impacts.typeVariableExpression);
+    if (worldImpact.constSymbolNames.isNotEmpty) {
+      registerBackendImpact(transformed, impacts.constSymbol);
+      for (String constSymbolName in worldImpact.constSymbolNames) {
+        backend.registerConstSymbol(constSymbolName);
+      }
+    }
+
+    for (StaticUse staticUse in worldImpact.staticUses) {
+      if (staticUse.kind == StaticUseKind.CLOSURE) {
+        registerBackendImpact(transformed, impacts.closure);
+        LocalFunctionElement closure = staticUse.element;
+        if (closure.type.containsTypeVariables) {
+          backend.compiler.enqueuer.resolution.universe
+              .closuresWithFreeTypeVariables.add(closure);
+          registerBackendImpact(transformed, impacts.computeSignature);
         }
       }
     }
 
-    for (String constSymbolName in worldImpact.constSymbolNames) {
-      backend.registerConstSymbol(constSymbolName);
-    }
-
-    for (LocalFunctionElement closure in worldImpact.closures) {
-      if (closure.computeType(backend.resolution).containsTypeVariables) {
-        backend.compiler.enqueuer.resolution.universe
-            .closuresWithFreeTypeVariables.add(closure);
-        registerBackendImpact(transformed, impacts.computeSignature);
+    for (ConstantExpression constant in worldImpact.constantLiterals) {
+      switch (constant.kind) {
+        case ConstantExpressionKind.NULL:
+          registerBackendImpact(transformed, impacts.nullLiteral);
+          break;
+        case ConstantExpressionKind.BOOL:
+          registerBackendImpact(transformed, impacts.boolLiteral);
+          break;
+        case ConstantExpressionKind.INT:
+          registerBackendImpact(transformed, impacts.intLiteral);
+          break;
+        case ConstantExpressionKind.DOUBLE:
+          registerBackendImpact(transformed, impacts.doubleLiteral);
+          break;
+        case ConstantExpressionKind.STRING:
+          registerBackendImpact(transformed, impacts.stringLiteral);
+          break;
+        default:
+          assert(invariant(NO_LOCATION_SPANNABLE, false,
+              message: "Unexpected constant literal: ${constant.kind}."));
       }
     }
-    // TODO(johnniwinther): Remove this when dependency tracking is done on
-    // the world impact itself.
-    for (InterfaceType instantiatedType in worldImpact.instantiatedTypes) {
-      transformed.registerInstantiatedType(instantiatedType);
-    }
-    for (Element element in worldImpact.staticUses) {
-      transformed.registerStaticUse(element);
-    }
 
     return transformed;
   }
@@ -2992,24 +2891,42 @@
     for (Element staticUse in backendImpact.staticUses) {
       assert(staticUse != null);
       backend.registerBackendUse(staticUse);
-      worldImpact.registerStaticUse(staticUse);
+      worldImpact.registerStaticUse(
+          // TODO(johnniwinther): Store the correct use in impacts.
+          new StaticUse.foreignUse(staticUse));
     }
     for (InterfaceType instantiatedType in backendImpact.instantiatedTypes) {
       backend.registerBackendUse(instantiatedType.element);
-      worldImpact.registerInstantiatedType(instantiatedType);
+      worldImpact.registerTypeUse(
+          new TypeUse.instantiation(instantiatedType));
     }
     for (ClassElement cls in backendImpact.instantiatedClasses) {
       cls.ensureResolved(backend.resolution);
       backend.registerBackendUse(cls);
-      worldImpact.registerInstantiatedType(cls.rawType);
+      worldImpact.registerTypeUse(
+          new TypeUse.instantiation(cls.rawType));
     }
     for (BackendImpact otherImpact in backendImpact.otherImpacts) {
       registerBackendImpact(worldImpact, otherImpact);
     }
   }
 
+  /// Register [type] as required for the runtime type information system.
+  void registerRequiredType(DartType type) {
+    // If [argument] has type variables or is a type variable, this method
+    // registers a RTI dependency between the class where the type variable is
+    // defined (that is the enclosing class of the current element being
+    // resolved) and the class of [type]. If the class of [type] requires RTI,
+    // then the class of the type variable does too.
+    ClassElement contextClass = Types.getClassContext(type);
+    if (contextClass != null) {
+      backend.rti.registerRtiDependency(type.element, contextClass);
+    }
+  }
+
   // TODO(johnniwinther): Maybe split this into [onAssertType] and [onTestType].
   void onIsCheck(DartType type, TransformedWorldImpact transformed) {
+    registerRequiredType(type);
     type.computeUnaliased(backend.resolution);
     type = type.unaliased;
     registerBackendImpact(transformed, impacts.typeCheck);
@@ -3037,10 +2954,122 @@
     if (type is FunctionType) {
       registerBackendImpact(transformed, impacts.functionTypeCheck);
     }
-    if (type.element != null && type.element.isNative) {
+    if (type.element != null && backend.isNative(type.element)) {
       registerBackendImpact(transformed, impacts.nativeTypeCheck);
     }
   }
+
+  void onIsCheckForCodegen(DartType type, TransformedWorldImpact transformed) {
+    type = type.unaliased;
+    registerBackendImpact(transformed, impacts.typeCheck);
+
+    bool inCheckedMode = backend.compiler.enableTypeAssertions;
+    // [registerIsCheck] is also called for checked mode checks, so we
+    // need to register checked mode helpers.
+    if (inCheckedMode) {
+      // All helpers are added to resolution queue in enqueueHelpers. These
+      // calls to enqueueInResolution serve as assertions that the helper was
+      // in fact added.
+      // TODO(13155): Find a way to enqueue helpers lazily.
+      CheckedModeHelper helper =
+          backend.getCheckedModeHelper(type, typeCast: false);
+      if (helper != null) {
+        StaticUse staticUse = helper.getStaticUse(backend.compiler);
+        transformed.registerStaticUse(staticUse);
+        backend.registerBackendUse(staticUse.element);
+      }
+      // We also need the native variant of the check (for DOM types).
+      helper = backend.getNativeCheckedModeHelper(type, typeCast: false);
+      if (helper != null) {
+        StaticUse staticUse = helper.getStaticUse(backend.compiler);
+        transformed.registerStaticUse(staticUse);
+        backend.registerBackendUse(staticUse.element);
+      }
+    }
+    if (!type.treatAsRaw || type.containsTypeVariables) {
+      registerBackendImpact(transformed, impacts.genericIsCheck);
+    }
+    if (type.element != null && backend.isNative(type.element)) {
+      // We will neeed to add the "$is" and "$as" properties on the
+      // JavaScript object prototype, so we make sure
+      // [:defineProperty:] is compiled.
+      registerBackendImpact(transformed, impacts.nativeTypeCheck);
+    }
+  }
+
+  @override
+  WorldImpact transformCodegenImpact(CodegenImpact impact) {
+    TransformedWorldImpact transformed = new TransformedWorldImpact(impact);
+    EagerRegistry registry = impact.registry;
+    Enqueuer world = registry.world;
+
+    for (TypeUse typeUse in impact.typeUses) {
+      DartType type = typeUse.type;
+      switch (typeUse.kind) {
+        case TypeUseKind.INSTANTIATION:
+          backend.lookupMapAnalysis.registerInstantiatedType(type, registry);
+          break;
+        case TypeUseKind.IS_CHECK:
+          onIsCheckForCodegen(type, transformed);
+          break;
+        default:
+      }
+    }
+
+    for (ConstantValue constant in impact.compileTimeConstants) {
+      backend.registerCompileTimeConstant(constant, registry);
+      backend.addCompileTimeConstantForEmission(constant);
+    }
+
+    for (Pair<DartType, DartType> check in
+            impact.typeVariableBoundsSubtypeChecks) {
+      backend.registerTypeVariableBoundsSubtypeCheck(check.a, check.b);
+    }
+
+
+    for (StaticUse staticUse in impact.staticUses) {
+      if (staticUse.kind == StaticUseKind.CLOSURE) {
+        LocalFunctionElement closure = staticUse.element;
+        if (backend.methodNeedsRti(closure)) {
+           registerBackendImpact(transformed, impacts.computeSignature);
+         }
+      }
+    }
+
+    for (String name in impact.constSymbols) {
+      backend.registerConstSymbol(name);
+    }
+
+    for (Set<ClassElement> classes in impact.specializedGetInterceptors) {
+      backend.registerSpecializedGetInterceptor(classes);
+    }
+
+    if (impact.usesInterceptor) {
+      backend.registerUseInterceptor(world);
+    }
+
+    for (ClassElement element in impact.typeConstants) {
+      backend.customElementsAnalysis.registerTypeConstant(element);
+      backend.lookupMapAnalysis.registerTypeConstant(element);
+    }
+
+    for (FunctionElement element in impact.asyncMarkers) {
+      switch (element.asyncMarker) {
+        case AsyncMarker.ASYNC:
+          registerBackendImpact(transformed, impacts.asyncBody);
+          break;
+        case AsyncMarker.SYNC_STAR:
+          registerBackendImpact(transformed, impacts.syncStarBody);
+          break;
+        case AsyncMarker.ASYNC_STAR:
+          registerBackendImpact(transformed, impacts.asyncStarBody);
+          break;
+      }
+    }
+
+    // TODO(johnniwinther): Remove eager registration.
+    return transformed;
+  }
 }
 
 /// Records that [constant] is used by the element behind [registry].
@@ -3050,4 +3079,3 @@
 
   const Dependency(this.constant, this.annotatedElement);
 }
-
diff --git a/pkg/compiler/lib/src/js_backend/backend_helpers.dart b/pkg/compiler/lib/src/js_backend/backend_helpers.dart
index 3c59891..d0b2750 100644
--- a/pkg/compiler/lib/src/js_backend/backend_helpers.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_helpers.dart
@@ -4,20 +4,50 @@
 
 library dart2js.js_backend.helpers;
 
+import '../common.dart';
+import '../common/names.dart' show
+    Uris;
 import '../common/resolution.dart' show
     Resolution;
 import '../compiler.dart' show
     Compiler;
+import '../core_types.dart' show
+    CoreClasses;
 import '../elements/elements.dart' show
+    AbstractFieldElement,
     ClassElement,
+    ConstructorElement,
     Element,
+    EnumClassElement,
+    FunctionElement,
     LibraryElement,
     MethodElement;
+import '../library_loader.dart' show
+    LoadedLibraries;
 
 import 'js_backend.dart';
 
 /// Helper classes and functions for the JavaScript backend.
 class BackendHelpers {
+  static final Uri DART_JS_HELPER = new Uri(scheme: 'dart', path: '_js_helper');
+  static final Uri DART_INTERCEPTORS =
+      new Uri(scheme: 'dart', path: '_interceptors');
+  static final Uri DART_FOREIGN_HELPER =
+      new Uri(scheme: 'dart', path: '_foreign_helper');
+  static final Uri DART_JS_MIRRORS =
+      new Uri(scheme: 'dart', path: '_js_mirrors');
+  static final Uri DART_JS_NAMES =
+      new Uri(scheme: 'dart', path: '_js_names');
+  static final Uri DART_EMBEDDED_NAMES =
+      new Uri(scheme: 'dart', path: '_js_embedded_names');
+  static final Uri DART_ISOLATE_HELPER =
+      new Uri(scheme: 'dart', path: '_isolate_helper');
+  static final Uri PACKAGE_JS =
+         new Uri(scheme: 'package', path: 'js/js.dart');
+
+  static const String INVOKE_ON = '_getCachedInvocation';
+  static const String START_ROOT_ISOLATE = 'startRootIsolate';
+
   final Compiler compiler;
 
   Element cachedCheckConcurrentModificationError;
@@ -28,16 +58,350 @@
 
   Resolution get resolution => backend.resolution;
 
+  CoreClasses get coreClasses => compiler.coreClasses;
+
+  DiagnosticReporter get reporter => compiler.reporter;
+
   MethodElement assertTest;
   MethodElement assertThrow;
   MethodElement assertHelper;
 
-  Element findHelper(String name) => backend.findHelper(name);
-  Element findAsyncHelper(String name) => backend.findAsyncHelper(name);
-  Element findInterceptor(String name) => backend.findInterceptor(name);
 
+  LibraryElement jsHelperLibrary;
+  LibraryElement asyncLibrary;
+  LibraryElement interceptorsLibrary;
+  LibraryElement foreignLibrary;
+  LibraryElement isolateHelperLibrary;
+
+  /// Reference to the internal library to lookup functions to always inline.
+  LibraryElement internalLibrary;
+
+  ClassElement closureClass;
+  ClassElement boundClosureClass;
+  Element assertUnreachableMethod;
+  Element invokeOnMethod;
+
+  ClassElement jsInterceptorClass;
+  ClassElement jsStringClass;
+  ClassElement jsArrayClass;
+  ClassElement jsNumberClass;
+  ClassElement jsIntClass;
+  ClassElement jsDoubleClass;
+  ClassElement jsNullClass;
+  ClassElement jsBoolClass;
+  ClassElement jsPlainJavaScriptObjectClass;
+  ClassElement jsUnknownJavaScriptObjectClass;
+  ClassElement jsJavaScriptFunctionClass;
+  ClassElement jsJavaScriptObjectClass;
+
+  ClassElement jsIndexableClass;
+  ClassElement jsMutableIndexableClass;
+
+  ClassElement jsMutableArrayClass;
+  ClassElement jsFixedArrayClass;
+  ClassElement jsExtendableArrayClass;
+  ClassElement jsUnmodifiableArrayClass;
+  ClassElement jsPositiveIntClass;
+  ClassElement jsUInt32Class;
+  ClassElement jsUInt31Class;
+
+  Element jsIndexableLength;
+  Element jsArrayTypedConstructor;
+  Element jsArrayRemoveLast;
+  Element jsArrayAdd;
+  Element jsStringSplit;
+  Element jsStringToString;
+  Element jsStringOperatorAdd;
+  Element objectEquals;
+
+  ClassElement typeLiteralClass;
+  ClassElement mapLiteralClass;
+  ClassElement constMapLiteralClass;
+  ClassElement typeVariableClass;
+  ConstructorElement mapLiteralConstructor;
+  ConstructorElement mapLiteralConstructorEmpty;
+  Element mapLiteralUntypedMaker;
+  Element mapLiteralUntypedEmptyMaker;
+
+  ClassElement noSideEffectsClass;
+  ClassElement noThrowsClass;
+  ClassElement noInlineClass;
+  ClassElement forceInlineClass;
+  ClassElement irRepresentationClass;
+
+  ClassElement jsAnnotationClass;
+  ClassElement jsAnonymousClass;
+
+  Element getInterceptorMethod;
+
+  ClassElement jsInvocationMirrorClass;
+
+  ClassElement typedArrayClass;
+  ClassElement typedArrayOfIntClass;
+
+  /**
+   * Interface used to determine if an object has the JavaScript
+   * indexing behavior. The interface is only visible to specific
+   * libraries.
+   */
+  ClassElement jsIndexingBehaviorInterface;
+
+  Element getNativeInterceptorMethod;
+
+  /// Holds the method "getIsolateAffinityTag" when dart:_js_helper has been
+  /// loaded.
+  FunctionElement getIsolateAffinityTagMarker;
+
+  /// Holds the method "disableTreeShaking" in js_mirrors when
+  /// dart:mirrors has been loaded.
+  FunctionElement disableTreeShakingMarker;
+
+  /// Holds the method "preserveNames" in js_mirrors when
+  /// dart:mirrors has been loaded.
+  FunctionElement preserveNamesMarker;
+
+  /// Holds the method "preserveMetadata" in js_mirrors when
+  /// dart:mirrors has been loaded.
+  FunctionElement preserveMetadataMarker;
+
+  /// Holds the method "preserveUris" in js_mirrors when
+  /// dart:mirrors has been loaded.
+  FunctionElement preserveUrisMarker;
+
+  /// Holds the method "preserveLibraryNames" in js_mirrors when
+  /// dart:mirrors has been loaded.
+  FunctionElement preserveLibraryNamesMarker;
+
+  /// Holds the method "requiresPreamble" in _js_helper.
+  FunctionElement requiresPreambleMarker;
+
+  /// Holds the class for the [JsGetName] enum.
+  EnumClassElement jsGetNameEnum;
+
+  /// Holds the class for the [JsBuiltins] enum.
+  EnumClassElement jsBuiltinEnum;
+
+  // TODO(johnniwinther): Make these private.
+  // TODO(johnniwinther): Split into findHelperFunction and findHelperClass and
+  // add a check that the element has the expected kind.
+  Element findHelper(String name) => find(jsHelperLibrary, name);
+  Element findAsyncHelper(String name) => find(asyncLibrary, name);
+  Element findInterceptor(String name) => find(interceptorsLibrary, name);
   Element find(LibraryElement library, String name) {
-    return backend.find(library, name);
+    Element element = library.implementation.findLocal(name);
+    assert(invariant(library, element != null,
+        message: "Element '$name' not found in '${library.canonicalUri}'."));
+    return element;
+  }
+
+  void onLibraryCreated(LibraryElement library) {
+    Uri uri = library.canonicalUri;
+    if (uri == DART_JS_HELPER) {
+      jsHelperLibrary = library;
+    } else if (uri == Uris.dart_async) {
+      asyncLibrary = library;
+    } else if (uri == Uris.dart__internal) {
+      internalLibrary = library;
+    } else if (uri ==  DART_INTERCEPTORS) {
+      interceptorsLibrary = library;
+    } else if (uri ==  DART_FOREIGN_HELPER) {
+      foreignLibrary = library;
+    } else if (uri == DART_ISOLATE_HELPER) {
+      isolateHelperLibrary = library;
+    }
+  }
+
+  void initializeHelperClasses(DiagnosticReporter reporter) {
+    final List missingHelperClasses = [];
+    ClassElement lookupHelperClass(String name) {
+      ClassElement result = findHelper(name);
+      if (result == null) {
+        missingHelperClasses.add(name);
+      }
+      return result;
+    }
+    jsInvocationMirrorClass = lookupHelperClass('JSInvocationMirror');
+    boundClosureClass = lookupHelperClass('BoundClosure');
+    closureClass = lookupHelperClass('Closure');
+    if (!missingHelperClasses.isEmpty) {
+      reporter.internalError(jsHelperLibrary,
+          'dart:_js_helper library does not contain required classes: '
+          '$missingHelperClasses');
+    }
+  }
+
+  void onLibraryScanned(LibraryElement library) {
+    Uri uri = library.canonicalUri;
+
+    FunctionElement findMethod(String name) {
+      return find(library, name);
+    }
+
+    ClassElement findClass(String name) {
+      return find(library, name);
+    }
+
+    if (uri == DART_INTERCEPTORS) {
+      getInterceptorMethod = findMethod('getInterceptor');
+      getNativeInterceptorMethod = findMethod('getNativeInterceptor');
+      jsInterceptorClass = findClass('Interceptor');
+      jsStringClass = findClass('JSString');
+      jsArrayClass = findClass('JSArray');
+      // The int class must be before the double class, because the
+      // emitter relies on this list for the order of type checks.
+      jsIntClass = findClass('JSInt');
+      jsPositiveIntClass = findClass('JSPositiveInt');
+      jsUInt32Class = findClass('JSUInt32');
+      jsUInt31Class = findClass('JSUInt31');
+      jsDoubleClass = findClass('JSDouble');
+      jsNumberClass = findClass('JSNumber');
+      jsNullClass = findClass('JSNull');
+      jsBoolClass = findClass('JSBool');
+      jsMutableArrayClass = findClass('JSMutableArray');
+      jsFixedArrayClass = findClass('JSFixedArray');
+      jsExtendableArrayClass = findClass('JSExtendableArray');
+      jsUnmodifiableArrayClass = findClass('JSUnmodifiableArray');
+      jsPlainJavaScriptObjectClass = findClass('PlainJavaScriptObject');
+      jsJavaScriptObjectClass = findClass('JavaScriptObject');
+      jsJavaScriptFunctionClass = findClass('JavaScriptFunction');
+      jsUnknownJavaScriptObjectClass = findClass('UnknownJavaScriptObject');
+      jsIndexableClass = findClass('JSIndexable');
+      jsMutableIndexableClass = findClass('JSMutableIndexable');
+    } else if (uri == DART_JS_HELPER) {
+      initializeHelperClasses(reporter);
+      assertTest = findHelper('assertTest');
+      assertThrow = findHelper('assertThrow');
+      assertHelper = findHelper('assertHelper');
+      assertUnreachableMethod = findHelper('assertUnreachable');
+
+      typeLiteralClass = findClass('TypeImpl');
+      constMapLiteralClass = findClass('ConstantMap');
+      typeVariableClass = findClass('TypeVariable');
+
+      jsIndexingBehaviorInterface = findClass('JavaScriptIndexingBehavior');
+
+      noSideEffectsClass = findClass('NoSideEffects');
+      noThrowsClass = findClass('NoThrows');
+      noInlineClass = findClass('NoInline');
+      forceInlineClass = findClass('ForceInline');
+      irRepresentationClass = findClass('IrRepresentation');
+
+      getIsolateAffinityTagMarker = findMethod('getIsolateAffinityTag');
+
+      requiresPreambleMarker = findMethod('requiresPreamble');
+    } else if (uri == DART_JS_MIRRORS) {
+      disableTreeShakingMarker = find(library, 'disableTreeShaking');
+      preserveMetadataMarker = find(library, 'preserveMetadata');
+      preserveUrisMarker = find(library, 'preserveUris');
+      preserveLibraryNamesMarker = find(library, 'preserveLibraryNames');
+    } else if (uri == DART_JS_NAMES) {
+      preserveNamesMarker = find(library, 'preserveNames');
+    } else if (uri == DART_EMBEDDED_NAMES) {
+      jsGetNameEnum = find(library, 'JsGetName');
+      jsBuiltinEnum = find(library, 'JsBuiltin');
+    } else if (uri == Uris.dart__native_typed_data) {
+      typedArrayClass = findClass('NativeTypedArray');
+      typedArrayOfIntClass = findClass('NativeTypedArrayOfInt');
+    } else if (uri == PACKAGE_JS) {
+      jsAnnotationClass = find(library, 'JS');
+      jsAnonymousClass = find(library, '_Anonymous');
+    }
+  }
+
+
+  void onLibrariesLoaded(LoadedLibraries loadedLibraries) {
+    assert(loadedLibraries.containsLibrary(Uris.dart_core));
+    assert(loadedLibraries.containsLibrary(DART_INTERCEPTORS));
+    assert(loadedLibraries.containsLibrary(DART_JS_HELPER));
+
+    if (jsInvocationMirrorClass != null) {
+      jsInvocationMirrorClass.ensureResolved(resolution);
+      invokeOnMethod = jsInvocationMirrorClass.lookupLocalMember(INVOKE_ON);
+    }
+
+    // [LinkedHashMap] is reexported from dart:collection and can therefore not
+    // be loaded from dart:core in [onLibraryScanned].
+    mapLiteralClass = compiler.coreLibrary.find('LinkedHashMap');
+    assert(invariant(compiler.coreLibrary, mapLiteralClass != null,
+        message: "Element 'LinkedHashMap' not found in 'dart:core'."));
+
+    // TODO(kasperl): Some tests do not define the special JSArray
+    // subclasses, so we check to see if they are defined before
+    // trying to resolve them.
+    if (jsFixedArrayClass != null) {
+      jsFixedArrayClass.ensureResolved(resolution);
+    }
+    if (jsExtendableArrayClass != null) {
+      jsExtendableArrayClass.ensureResolved(resolution);
+    }
+    if (jsUnmodifiableArrayClass != null) {
+      jsUnmodifiableArrayClass.ensureResolved(resolution);
+    }
+
+    jsIndexableClass.ensureResolved(resolution);
+    jsIndexableLength = compiler.lookupElementIn(
+        jsIndexableClass, 'length');
+    if (jsIndexableLength != null && jsIndexableLength.isAbstractField) {
+      AbstractFieldElement element = jsIndexableLength;
+      jsIndexableLength = element.getter;
+    }
+
+    jsArrayClass.ensureResolved(resolution);
+    jsArrayTypedConstructor = compiler.lookupElementIn(jsArrayClass, 'typed');
+    jsArrayRemoveLast = compiler.lookupElementIn(jsArrayClass, 'removeLast');
+    jsArrayAdd = compiler.lookupElementIn(jsArrayClass, 'add');
+
+    jsStringClass.ensureResolved(resolution);
+    jsStringSplit = compiler.lookupElementIn(jsStringClass, 'split');
+    jsStringOperatorAdd = compiler.lookupElementIn(jsStringClass, '+');
+    jsStringToString = compiler.lookupElementIn(jsStringClass, 'toString');
+
+    objectEquals = compiler.lookupElementIn(coreClasses.objectClass, '==');
+  }
+
+  Element get badMain {
+    return findHelper('badMain');
+  }
+
+  Element get missingMain {
+    return findHelper('missingMain');
+  }
+
+  Element get mainHasTooManyParameters {
+    return findHelper('mainHasTooManyParameters');
+  }
+
+  Element get loadLibraryWrapper {
+    return findHelper("_loadLibraryWrapper");
+  }
+
+  Element get boolConversionCheck {
+    return findHelper('boolConversionCheck');
+  }
+
+  Element get consoleTraceHelper {
+    return findHelper('consoleTraceHelper');
+  }
+
+  Element get postTraceHelper {
+    return findHelper('postTraceHelper');
+  }
+
+  FunctionElement get closureFromTearOff {
+    return findHelper('closureFromTearOff');
+  }
+
+  Element get isJsIndexable {
+    return findHelper('isJsIndexable');
+  }
+
+
+  Element get throwIllegalArgumentException {
+    return findHelper('iae');
+  }
+
+  Element get throwIndexOutOfRangeException {
+    return findHelper('ioore');
   }
 
   Element get exceptionUnwrapper {
@@ -222,6 +586,18 @@
     return classElement;
   }
 
+  Element get futureImplementation {
+    ClassElement classElement = findAsyncHelper('_Future');
+    classElement.ensureResolved(resolution);
+    return classElement;
+  }
+
+  Element get controllerStream {
+    ClassElement classElement = findAsyncHelper("_ControllerStream");
+    classElement.ensureResolved(resolution);
+    return classElement;
+  }
+
   Element get syncStarIterableConstructor {
     ClassElement classElement = syncStarIterable;
     classElement.ensureResolved(resolution);
@@ -252,6 +628,30 @@
     return classElement.lookupConstructor("");
   }
 
+  ClassElement get VoidRuntimeType {
+    return findHelper('VoidRuntimeType');
+  }
+
+  ClassElement get RuntimeType {
+    return findHelper('RuntimeType');
+  }
+
+  ClassElement get RuntimeFunctionType {
+    return findHelper('RuntimeFunctionType');
+  }
+
+  ClassElement get RuntimeTypePlain {
+    return findHelper('RuntimeTypePlain');
+  }
+
+  ClassElement get RuntimeTypeGeneric {
+    return findHelper('RuntimeTypeGeneric');
+  }
+
+  ClassElement get DynamicRuntimeType {
+    return findHelper('DynamicRuntimeType');
+  }
+
   MethodElement get functionTypeTestMetaHelper {
     return findHelper('functionTypeTestMetaHelper');
   }
@@ -259,4 +659,24 @@
   MethodElement get defineProperty {
     return findHelper('defineProperty');
   }
-}
\ No newline at end of file
+
+  Element get startRootIsolate {
+    return find(isolateHelperLibrary, START_ROOT_ISOLATE);
+  }
+
+  Element get currentIsolate {
+    return find(isolateHelperLibrary, '_currentIsolate');
+  }
+
+  Element get callInIsolate {
+    return find(isolateHelperLibrary, '_callInIsolate');
+  }
+
+  Element get findIndexForNativeSubclassType {
+    return findInterceptor('findIndexForNativeSubclassType');
+  }
+
+  Element get convertRtiToRuntimeType {
+    return findHelper('convertRtiToRuntimeType');
+  }
+}
diff --git a/pkg/compiler/lib/src/js_backend/backend_impact.dart b/pkg/compiler/lib/src/js_backend/backend_impact.dart
index 90dba81..3320c2f 100644
--- a/pkg/compiler/lib/src/js_backend/backend_impact.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_impact.dart
@@ -8,6 +8,8 @@
     Identifiers;
 import '../compiler.dart' show
     Compiler;
+import '../core_types.dart' show
+    CoreClasses;
 import '../dart_types.dart' show
     InterfaceType;
 import '../elements/elements.dart' show
@@ -41,249 +43,599 @@
 
   BackendHelpers get helpers => backend.helpers;
 
-  BackendImpact get getRuntimeTypeArgument => new BackendImpact(
-      staticUses: [
-        helpers.getRuntimeTypeArgument,
-        helpers.getTypeArgumentByIndex,
-        helpers.copyTypeArguments]);
+  CoreClasses get coreClasses => compiler.coreClasses;
 
-  BackendImpact get computeSignature => new BackendImpact(
-      staticUses: [
-        helpers.setRuntimeTypeInfo,
-        helpers.getRuntimeTypeInfo,
-        helpers.computeSignature,
-        helpers.getRuntimeTypeArguments],
-      instantiatedClasses: [
-        compiler.listClass]);
+  BackendImpact _getRuntimeTypeArgument;
 
-  BackendImpact get asyncBody => new BackendImpact(
-      staticUses: [
-        helpers.asyncHelper,
-        helpers.syncCompleterConstructor,
-        helpers.streamIteratorConstructor,
-        helpers.wrapBody]);
-
-  BackendImpact get syncStarBody => new BackendImpact(
-      staticUses: [
-        helpers.syncStarIterableConstructor,
-        helpers.endOfIteration,
-        helpers.yieldStar,
-        helpers.syncStarUncaughtError],
-      instantiatedClasses: [
-        helpers.syncStarIterable]);
-
-  BackendImpact get asyncStarBody => new BackendImpact(
-      staticUses: [
-        helpers.asyncStarHelper,
-        helpers.streamOfController,
-        helpers.yieldSingle,
-        helpers.yieldStar,
-        helpers.asyncStarControllerConstructor,
-        helpers.streamIteratorConstructor,
-        helpers.wrapBody],
-      instantiatedClasses: [
-        helpers.asyncStarController]);
-
-  BackendImpact get typeVariableBoundCheck => new BackendImpact(
-      staticUses: [
-        helpers.throwTypeError,
-        helpers.assertIsSubtype]);
-
-  BackendImpact get abstractClassInstantiation => new BackendImpact(
-      staticUses: [
-        helpers.throwAbstractClassInstantiationError],
-      otherImpacts: [
-        needsString('Needed to encode the message.')]);
-
-  BackendImpact get fallThroughError => new BackendImpact(
-      staticUses: [
-        helpers.fallThroughError]);
-
-  BackendImpact get asCheck => new BackendImpact(
-      staticUses: [
-        helpers.throwRuntimeError]);
-
-  BackendImpact get throwNoSuchMethod => new BackendImpact(
-      staticUses: [
-        helpers.throwNoSuchMethod],
-      otherImpacts: [
-        // Also register the types of the arguments passed to this method.
-        needsList(
-            'Needed to encode the arguments for throw NoSuchMethodError.'),
-        needsString(
-            'Needed to encode the name for throw NoSuchMethodError.')]);
-
-  BackendImpact get throwRuntimeError => new BackendImpact(
-      staticUses: [
-        helpers.throwRuntimeError],
-      // Also register the types of the arguments passed to this method.
-      instantiatedClasses: [
-        helpers.compiler.stringClass]);
-
-  BackendImpact get superNoSuchMethod => new BackendImpact(
-      staticUses: [
-        helpers.createInvocationMirror,
-        helpers.compiler.objectClass.lookupLocalMember(
-            Identifiers.noSuchMethod_)],
-      otherImpacts: [
-        needsInt(
-            'Needed to encode the invocation kind of super.noSuchMethod.'),
-        needsList(
-            'Needed to encode the arguments of super.noSuchMethod.'),
-        needsString(
-            'Needed to encode the name of super.noSuchMethod.')]);
-
-  BackendImpact get constantMapLiteral {
-
-    ClassElement find(String name) {
-      return helpers.find(backend.jsHelperLibrary, name);
+  BackendImpact get getRuntimeTypeArgument {
+    if (_getRuntimeTypeArgument == null) {
+      _getRuntimeTypeArgument = new BackendImpact(
+          staticUses: [
+            helpers.getRuntimeTypeArgument,
+            helpers.getTypeArgumentByIndex,
+            helpers.copyTypeArguments]);
     }
-
-    return new BackendImpact(
-      instantiatedClasses: [
-        find(JavaScriptMapConstant.DART_CLASS),
-        find(JavaScriptMapConstant.DART_PROTO_CLASS),
-        find(JavaScriptMapConstant.DART_STRING_CLASS),
-        find(JavaScriptMapConstant.DART_GENERAL_CLASS)]);
+    return _getRuntimeTypeArgument;
   }
 
-  BackendImpact get symbolConstructor => new BackendImpact(
-      staticUses: [
-        helpers.compiler.symbolValidatedConstructor]);
+  BackendImpact _computeSignature;
 
+  BackendImpact get computeSignature {
+    if (_computeSignature == null) {
+      _computeSignature = new BackendImpact(
+          staticUses: [
+            helpers.setRuntimeTypeInfo,
+            helpers.getRuntimeTypeInfo,
+            helpers.computeSignature,
+            helpers.getRuntimeTypeArguments],
+          instantiatedClasses: [
+            coreClasses.listClass]);
+    }
+    return _computeSignature;
+  }
 
-  BackendImpact get incDecOperation =>
-      needsInt('Needed for the `+ 1` or `- 1` operation of ++/--.');
+  BackendImpact _asyncBody;
+
+  BackendImpact get asyncBody {
+    if (_asyncBody == null) {
+      _asyncBody = new BackendImpact(
+          staticUses: [
+            helpers.asyncHelper,
+            helpers.syncCompleterConstructor,
+            helpers.streamIteratorConstructor,
+            helpers.wrapBody]);
+    }
+    return _asyncBody;
+  }
+
+  BackendImpact _syncStarBody;
+
+  BackendImpact get syncStarBody {
+    if (_syncStarBody == null) {
+      _syncStarBody = new BackendImpact(
+          staticUses: [
+            helpers.syncStarIterableConstructor,
+            helpers.endOfIteration,
+            helpers.yieldStar,
+            helpers.syncStarUncaughtError],
+          instantiatedClasses: [
+            helpers.syncStarIterable]);
+    }
+    return _syncStarBody;
+  }
+
+  BackendImpact _asyncStarBody;
+
+  BackendImpact get asyncStarBody {
+    if (_asyncStarBody == null) {
+      _asyncStarBody = new BackendImpact(
+          staticUses: [
+            helpers.asyncStarHelper,
+            helpers.streamOfController,
+            helpers.yieldSingle,
+            helpers.yieldStar,
+            helpers.asyncStarControllerConstructor,
+            helpers.streamIteratorConstructor,
+            helpers.wrapBody],
+          instantiatedClasses: [
+            helpers.asyncStarController]);
+    }
+    return _asyncStarBody;
+  }
+
+  BackendImpact _typeVariableBoundCheck;
+
+  BackendImpact get typeVariableBoundCheck {
+    if (_typeVariableBoundCheck == null) {
+      _typeVariableBoundCheck = new BackendImpact(
+          staticUses: [
+            helpers.throwTypeError,
+            helpers.assertIsSubtype]);
+    }
+    return _typeVariableBoundCheck;
+  }
+
+  BackendImpact _abstractClassInstantiation;
+
+  BackendImpact get abstractClassInstantiation {
+    if (_abstractClassInstantiation == null) {
+      _abstractClassInstantiation = new BackendImpact(
+          staticUses: [
+            helpers.throwAbstractClassInstantiationError],
+          otherImpacts: [
+            _needsString('Needed to encode the message.')]);
+    }
+    return _abstractClassInstantiation;
+  }
+
+  BackendImpact _fallThroughError;
+
+  BackendImpact get fallThroughError {
+    if (_fallThroughError == null) {
+      _fallThroughError = new BackendImpact(
+          staticUses: [
+            helpers.fallThroughError]);
+    }
+    return _fallThroughError;
+  }
+
+  BackendImpact _asCheck;
+
+  BackendImpact get asCheck {
+    if (_asCheck == null) {
+      _asCheck = new BackendImpact(
+          staticUses: [
+            helpers.throwRuntimeError]);
+    }
+    return _asCheck;
+  }
+
+  BackendImpact _throwNoSuchMethod;
+
+  BackendImpact get throwNoSuchMethod {
+    if (_throwNoSuchMethod == null) {
+      _throwNoSuchMethod = new BackendImpact(
+          staticUses: [
+            helpers.throwNoSuchMethod],
+          otherImpacts: [
+            // Also register the types of the arguments passed to this method.
+            _needsList(
+                'Needed to encode the arguments for throw NoSuchMethodError.'),
+            _needsString(
+                'Needed to encode the name for throw NoSuchMethodError.')]);
+    }
+    return _throwNoSuchMethod;
+  }
+
+  BackendImpact _throwRuntimeError;
+
+  BackendImpact get throwRuntimeError {
+    if (_throwRuntimeError == null) {
+      _throwRuntimeError = new BackendImpact(
+          staticUses: [
+            helpers.throwRuntimeError],
+          // Also register the types of the arguments passed to this method.
+          instantiatedClasses: [
+            coreClasses.stringClass]);
+    }
+    return _throwRuntimeError;
+  }
+
+  BackendImpact _superNoSuchMethod;
+
+  BackendImpact get superNoSuchMethod {
+    if (_superNoSuchMethod == null) {
+      _superNoSuchMethod = new BackendImpact(
+          staticUses: [
+            helpers.createInvocationMirror,
+            coreClasses.objectClass.lookupLocalMember(
+                Identifiers.noSuchMethod_)],
+          otherImpacts: [
+            _needsInt(
+                'Needed to encode the invocation kind of super.noSuchMethod.'),
+            _needsList(
+                'Needed to encode the arguments of super.noSuchMethod.'),
+            _needsString(
+                'Needed to encode the name of super.noSuchMethod.')]);
+    }
+    return _superNoSuchMethod;
+  }
+
+  BackendImpact _constantMapLiteral;
+
+  BackendImpact get constantMapLiteral {
+    if (_constantMapLiteral == null) {
+
+      ClassElement find(String name) {
+        return helpers.find(helpers.jsHelperLibrary, name);
+      }
+
+      _constantMapLiteral = new BackendImpact(
+          instantiatedClasses: [
+            find(JavaScriptMapConstant.DART_CLASS),
+            find(JavaScriptMapConstant.DART_PROTO_CLASS),
+            find(JavaScriptMapConstant.DART_STRING_CLASS),
+            find(JavaScriptMapConstant.DART_GENERAL_CLASS)]);
+    }
+    return _constantMapLiteral;
+  }
+
+  BackendImpact _symbolConstructor;
+
+  BackendImpact get symbolConstructor {
+    if (_symbolConstructor == null) {
+      _symbolConstructor = new BackendImpact(
+        staticUses: [
+          helpers.compiler.symbolValidatedConstructor]);
+    }
+    return _symbolConstructor;
+  }
+
+  BackendImpact _constSymbol;
+
+  BackendImpact get constSymbol {
+    if (_constSymbol == null) {
+      _constSymbol = new BackendImpact(
+        instantiatedClasses: [
+          coreClasses.symbolClass],
+        staticUses: [
+          compiler.symbolConstructor.declaration]);
+    }
+    return _constSymbol;
+  }
+
+  BackendImpact _incDecOperation;
+
+  BackendImpact get incDecOperation {
+    if (_incDecOperation == null) {
+      _incDecOperation =
+          _needsInt('Needed for the `+ 1` or `- 1` operation of ++/--.');
+    }
+    return _incDecOperation;
+  }
 
   /// Helper for registering that `int` is needed.
-  BackendImpact needsInt(String reason) {
+  BackendImpact _needsInt(String reason) {
     // TODO(johnniwinther): Register [reason] for use in dump-info.
     return new BackendImpact(
-        instantiatedClasses: [helpers.compiler.intClass]);
+        instantiatedClasses: [coreClasses.intClass]);
   }
 
   /// Helper for registering that `List` is needed.
-  BackendImpact needsList(String reason) {
+  BackendImpact _needsList(String reason) {
     // TODO(johnniwinther): Register [reason] for use in dump-info.
     return new BackendImpact(
-        instantiatedClasses: [helpers.compiler.listClass]);
+        instantiatedClasses: [coreClasses.listClass]);
   }
 
   /// Helper for registering that `String` is needed.
-  BackendImpact needsString(String reason) {
+  BackendImpact _needsString(String reason) {
     // TODO(johnniwinther): Register [reason] for use in dump-info.
     return new BackendImpact(
         instantiatedClasses: [
-          helpers.compiler.stringClass]);
+          coreClasses.stringClass]);
   }
 
-  BackendImpact get assertWithoutMessage => new BackendImpact(
-      staticUses: [
-        helpers.assertHelper]);
+  BackendImpact _assertWithoutMessage;
 
-  BackendImpact get assertWithMessage => new BackendImpact(
-      staticUses: [
-        helpers.assertTest,
-        helpers.assertThrow]);
+  BackendImpact get assertWithoutMessage {
+    if (_assertWithoutMessage == null) {
+      _assertWithoutMessage = new BackendImpact(
+          staticUses: [
+            helpers.assertHelper]);
+    }
+    return _assertWithoutMessage;
+  }
 
-  BackendImpact get asyncForIn => new BackendImpact(
-      staticUses: [
-        helpers.streamIteratorConstructor]);
+  BackendImpact _assertWithMessage;
 
-  BackendImpact get stringInterpolation => new BackendImpact(
-      staticUses: [
-        helpers.stringInterpolationHelper]);
+  BackendImpact get assertWithMessage {
+    if (_assertWithMessage == null) {
+      _assertWithMessage = new BackendImpact(
+          staticUses: [
+            helpers.assertTest,
+            helpers.assertThrow]);
+    }
+    return _assertWithMessage;
+  }
 
-  BackendImpact get catchStatement => new BackendImpact(
-      staticUses: [
-        helpers.exceptionUnwrapper],
-      instantiatedClasses: [
-        backend.jsPlainJavaScriptObjectClass,
-        backend.jsUnknownJavaScriptObjectClass]);
+  BackendImpact _asyncForIn;
 
-  BackendImpact get throwExpression => new BackendImpact(
-      // We don't know ahead of time whether we will need the throw in a
-      // statement context or an expression context, so we register both
-      // here, even though we may not need the throwExpression helper.
-      staticUses: [
-        helpers.wrapExceptionHelper,
-        helpers.throwExpressionHelper]);
+  BackendImpact get asyncForIn {
+    if (_asyncForIn == null) {
+      _asyncForIn = new BackendImpact(
+          staticUses: [
+            helpers.streamIteratorConstructor]);
+    }
+    return _asyncForIn;
+  }
 
-  BackendImpact get lazyField => new BackendImpact(
-      staticUses: [
-        helpers.cyclicThrowHelper]);
+  BackendImpact _stringInterpolation;
 
-  BackendImpact get typeLiteral => new BackendImpact(
-      instantiatedClasses: [
-        backend.typeImplementation],
-      staticUses: [
-        helpers.createRuntimeType]);
+  BackendImpact get stringInterpolation {
+    if (_stringInterpolation == null) {
+      _stringInterpolation = new BackendImpact(
+          staticUses: [
+            helpers.stringInterpolationHelper],
+          otherImpacts: [
+            _needsString('Strings are created.')]);
+    }
+    return _stringInterpolation;
+  }
 
-  BackendImpact get stackTraceInCatch => new BackendImpact(
-      staticUses: [
-        helpers.traceFromException]);
+  BackendImpact _stringJuxtaposition;
 
-  BackendImpact get syncForIn => new BackendImpact(
-      // The SSA builder recognizes certain for-in loops and can generate calls
-      // to throwConcurrentModificationError.
-      staticUses: [
-        helpers.checkConcurrentModificationError]);
+  BackendImpact get stringJuxtaposition {
+    if (_stringJuxtaposition == null) {
+      _stringJuxtaposition = _needsString('String.concat is used.');
+    }
+    return _stringJuxtaposition;
+  }
 
-  BackendImpact get typeVariableExpression => new BackendImpact(
-      staticUses: [
-        helpers.setRuntimeTypeInfo,
-        helpers.getRuntimeTypeInfo,
-        helpers.runtimeTypeToString,
-        helpers.createRuntimeType],
-      instantiatedClasses: [
-        helpers.compiler.listClass],
-      otherImpacts: [
-        getRuntimeTypeArgument,
-        needsInt('Needed for accessing a type variable literal on this.')]);
+  // TODO(johnniwinther): Point to to the JavaScript classes instead of the Dart
+  // classes in these impacts.
+  BackendImpact _nullLiteral;
 
-  BackendImpact get typeCheck => new BackendImpact(
-      instantiatedClasses: [
-        helpers.compiler.boolClass]);
+  BackendImpact get nullLiteral {
+    if (_nullLiteral == null) {
+      _nullLiteral = new BackendImpact(
+          instantiatedClasses: [
+            coreClasses.nullClass]);
+    }
+    return _nullLiteral;
+  }
 
-  BackendImpact get checkedModeTypeCheck => new BackendImpact(
-      staticUses: [
-        helpers.throwRuntimeError]);
+  BackendImpact _boolLiteral;
 
-  BackendImpact get malformedTypeCheck => new BackendImpact(
-      staticUses: [
-        helpers.throwTypeError]);
+  BackendImpact get boolLiteral {
+    if (_boolLiteral == null) {
+      _boolLiteral = new BackendImpact(
+          instantiatedClasses: [
+            coreClasses.boolClass]);
+    }
+    return _boolLiteral;
+  }
 
-  BackendImpact get genericTypeCheck => new BackendImpact(
-      staticUses: [
-        helpers.checkSubtype,
-        // TODO(johnniwinther): Investigate why this is needed.
-        helpers.setRuntimeTypeInfo,
-        helpers.getRuntimeTypeInfo],
-      instantiatedClasses: [
-        helpers.compiler.listClass],
-      otherImpacts: [
-        getRuntimeTypeArgument]);
+  BackendImpact _intLiteral;
 
-  BackendImpact get genericCheckedModeTypeCheck => new BackendImpact(
-      staticUses: [
-        helpers.assertSubtype]);
+  BackendImpact get intLiteral {
+    if (_intLiteral == null) {
+      _intLiteral = new BackendImpact(
+          instantiatedClasses: [
+            coreClasses.intClass]);
+    }
+    return _intLiteral;
+  }
 
-  BackendImpact get typeVariableTypeCheck => new BackendImpact(
-      staticUses: [
-        helpers.checkSubtypeOfRuntimeType]);
+  BackendImpact _doubleLiteral;
 
-  BackendImpact get typeVariableCheckedModeTypeCheck => new BackendImpact(
-      staticUses: [
-        helpers.assertSubtypeOfRuntimeType]);
+  BackendImpact get doubleLiteral {
+    if (_doubleLiteral == null) {
+      _doubleLiteral = new BackendImpact(
+          instantiatedClasses: [
+            coreClasses.doubleClass]);
+    }
+    return _doubleLiteral;
+  }
 
-  BackendImpact get functionTypeCheck => new BackendImpact(
-      staticUses: [
-        helpers.functionTypeTestMetaHelper]);
+  BackendImpact _stringLiteral;
 
-  BackendImpact get nativeTypeCheck => new BackendImpact(
-      staticUses: [
-        // We will neeed to add the "$is" and "$as" properties on the
-        // JavaScript object prototype, so we make sure
-        // [:defineProperty:] is compiled.
-        helpers.defineProperty]);
+  BackendImpact get stringLiteral {
+    if (_stringLiteral == null) {
+      _stringLiteral = new BackendImpact(
+          instantiatedClasses: [
+            coreClasses.stringClass]);
+    }
+    return _stringLiteral;
+  }
+
+  BackendImpact _catchStatement;
+
+  BackendImpact get catchStatement {
+    if (_catchStatement == null) {
+      _catchStatement = new BackendImpact(
+          staticUses: [
+            helpers.exceptionUnwrapper],
+          instantiatedClasses: [
+            helpers.jsPlainJavaScriptObjectClass,
+            helpers.jsUnknownJavaScriptObjectClass]);
+    }
+    return _catchStatement;
+  }
+
+  BackendImpact _throwExpression;
+
+  BackendImpact get throwExpression {
+    if (_throwExpression == null) {
+      _throwExpression = new BackendImpact(
+          // We don't know ahead of time whether we will need the throw in a
+          // statement context or an expression context, so we register both
+          // here, even though we may not need the throwExpression helper.
+          staticUses: [
+            helpers.wrapExceptionHelper,
+            helpers.throwExpressionHelper]);
+    }
+    return _throwExpression;
+  }
+
+  BackendImpact _lazyField;
+
+  BackendImpact get lazyField {
+    if (_lazyField == null) {
+      _lazyField = new BackendImpact(
+          staticUses: [
+            helpers.cyclicThrowHelper]);
+    }
+    return _lazyField;
+  }
+
+  BackendImpact _typeLiteral;
+
+  BackendImpact get typeLiteral {
+    if (_typeLiteral == null) {
+      _typeLiteral = new BackendImpact(
+          instantiatedClasses: [
+            backend.typeImplementation],
+          staticUses: [
+            helpers.createRuntimeType]);
+    }
+    return _typeLiteral;
+  }
+
+  BackendImpact _stackTraceInCatch;
+
+  BackendImpact get stackTraceInCatch {
+    if (_stackTraceInCatch == null) {
+      _stackTraceInCatch = new BackendImpact(
+          instantiatedClasses: [
+            coreClasses.stackTraceClass],
+          staticUses: [
+            helpers.traceFromException]);
+    }
+    return _stackTraceInCatch;
+  }
+
+  BackendImpact _syncForIn;
+
+  BackendImpact get syncForIn {
+    if (_syncForIn == null) {
+      _syncForIn = new BackendImpact(
+          // The SSA builder recognizes certain for-in loops and can generate
+          // calls to throwConcurrentModificationError.
+          staticUses: [
+            helpers.checkConcurrentModificationError]);
+    }
+    return _syncForIn;
+  }
+
+  BackendImpact _typeVariableExpression;
+
+  BackendImpact get typeVariableExpression {
+    if (_typeVariableExpression == null) {
+      _typeVariableExpression = new BackendImpact(
+          staticUses: [
+            helpers.setRuntimeTypeInfo,
+            helpers.getRuntimeTypeInfo,
+            helpers.runtimeTypeToString,
+            helpers.createRuntimeType],
+          instantiatedClasses: [
+            coreClasses.listClass],
+          otherImpacts: [
+            getRuntimeTypeArgument,
+            _needsInt('Needed for accessing a type variable literal on this.')
+          ]);
+    }
+    return _typeVariableExpression;
+  }
+
+  BackendImpact _typeCheck;
+
+  BackendImpact get typeCheck {
+    if (_typeCheck == null) {
+      _typeCheck = new BackendImpact(
+          instantiatedClasses: [
+            coreClasses.boolClass]);
+    }
+    return _typeCheck;
+  }
+
+  BackendImpact _checkedModeTypeCheck;
+
+  BackendImpact get checkedModeTypeCheck {
+    if (_checkedModeTypeCheck == null) {
+      _checkedModeTypeCheck = new BackendImpact(
+          staticUses: [
+            helpers.throwRuntimeError]);
+    }
+    return _checkedModeTypeCheck;
+  }
+
+  BackendImpact _malformedTypeCheck;
+
+  BackendImpact get malformedTypeCheck {
+    if (_malformedTypeCheck == null) {
+      _malformedTypeCheck = new BackendImpact(
+          staticUses: [
+            helpers.throwTypeError]);
+    }
+    return _malformedTypeCheck;
+  }
+
+  BackendImpact _genericTypeCheck;
+
+  BackendImpact get genericTypeCheck {
+    if (_genericTypeCheck == null) {
+      _genericTypeCheck = new BackendImpact(
+          staticUses: [
+            helpers.checkSubtype,
+            // TODO(johnniwinther): Investigate why this is needed.
+            helpers.setRuntimeTypeInfo,
+            helpers.getRuntimeTypeInfo],
+          instantiatedClasses: [
+            coreClasses.listClass],
+          otherImpacts: [
+            getRuntimeTypeArgument]);
+    }
+    return _genericTypeCheck;
+  }
+
+  BackendImpact _genericIsCheck;
+
+  BackendImpact get genericIsCheck {
+    if (_genericIsCheck == null) {
+      _genericIsCheck = new BackendImpact(
+          instantiatedClasses: [
+            coreClasses.listClass]);
+    }
+    return _genericIsCheck;
+  }
+
+  BackendImpact _genericCheckedModeTypeCheck;
+
+  BackendImpact get genericCheckedModeTypeCheck {
+    if (_genericCheckedModeTypeCheck == null) {
+      _genericCheckedModeTypeCheck = new BackendImpact(
+          staticUses: [
+            helpers.assertSubtype]);
+    }
+    return _genericCheckedModeTypeCheck;
+  }
+
+  BackendImpact _typeVariableTypeCheck;
+
+  BackendImpact get typeVariableTypeCheck {
+    if (_typeVariableTypeCheck == null) {
+      _typeVariableTypeCheck = new BackendImpact(
+          staticUses: [
+            helpers.checkSubtypeOfRuntimeType]);
+    }
+    return _typeVariableTypeCheck;
+  }
+
+  BackendImpact _typeVariableCheckedModeTypeCheck;
+
+  BackendImpact get typeVariableCheckedModeTypeCheck {
+    if (_typeVariableCheckedModeTypeCheck == null) {
+      _typeVariableCheckedModeTypeCheck = new BackendImpact(
+        staticUses: [
+          helpers.assertSubtypeOfRuntimeType]);
+    }
+    return _typeVariableCheckedModeTypeCheck;
+  }
+
+  BackendImpact _functionTypeCheck;
+
+  BackendImpact get functionTypeCheck {
+    if (_functionTypeCheck == null) {
+      _functionTypeCheck = new BackendImpact(
+          staticUses: [
+            helpers.functionTypeTestMetaHelper]);
+    }
+    return _functionTypeCheck;
+  }
+
+  BackendImpact _nativeTypeCheck;
+
+  BackendImpact get nativeTypeCheck {
+    if (_nativeTypeCheck == null) {
+      _nativeTypeCheck = new BackendImpact(
+          staticUses: [
+            // We will neeed to add the "$is" and "$as" properties on the
+            // JavaScript object prototype, so we make sure
+            // [:defineProperty:] is compiled.
+            helpers.defineProperty]);
+    }
+    return _nativeTypeCheck;
+  }
+
+  BackendImpact _closure;
+
+  BackendImpact get closure {
+    if (_closure == null) {
+      _closure = new BackendImpact(
+          instantiatedClasses: [
+            coreClasses.functionClass]);
+    }
+    return _closure;
+  }
 }
\ No newline at end of file
diff --git a/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart b/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart
index 003ab69..a40caad 100644
--- a/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart
+++ b/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart
@@ -9,21 +9,24 @@
 
   const CheckedModeHelper(String this.name);
 
-  Element getElement(Compiler compiler) {
+  StaticUse getStaticUse(Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
-    return backend.findHelper(name);
+    return new StaticUse.staticInvoke(
+        backend.helpers.findHelper(name), callStructure);
   }
 
+  CallStructure get callStructure => CallStructure.ONE_ARG;
+
   jsAst.Expression generateCall(SsaCodeGenerator codegen,
                                 HTypeConversion node) {
-    Element helperElement = getElement(codegen.compiler);
-    codegen.registry.registerStaticUse(helperElement);
+    StaticUse staticUse = getStaticUse(codegen.compiler);
+    codegen.registry.registerStaticUse(staticUse);
     List<jsAst.Expression> arguments = <jsAst.Expression>[];
     codegen.use(node.checkedInput);
     arguments.add(codegen.pop());
     generateAdditionalArguments(codegen, node, arguments);
     jsAst.Expression helper =
-        codegen.backend.emitter.staticFunctionAccess(helperElement);
+        codegen.backend.emitter.staticFunctionAccess(staticUse.element);
     return new jsAst.Call(helper, arguments);
   }
 
@@ -73,6 +76,8 @@
 class MalformedCheckedModeHelper extends CheckedModeHelper {
   const MalformedCheckedModeHelper(String name) : super(name);
 
+  CallStructure get callStructure => CallStructure.TWO_ARGS;
+
   void generateAdditionalArguments(SsaCodeGenerator codegen,
                                    HTypeConversion node,
                                    List<jsAst.Expression> arguments) {
@@ -84,6 +89,8 @@
 class PropertyCheckedModeHelper extends CheckedModeHelper {
   const PropertyCheckedModeHelper(String name) : super(name);
 
+  CallStructure get callStructure => CallStructure.TWO_ARGS;
+
   void generateAdditionalArguments(SsaCodeGenerator codegen,
                                    HTypeConversion node,
                                    List<jsAst.Expression> arguments) {
@@ -96,6 +103,8 @@
 class TypeVariableCheckedModeHelper extends CheckedModeHelper {
   const TypeVariableCheckedModeHelper(String name) : super(name);
 
+  CallStructure get callStructure => CallStructure.TWO_ARGS;
+
   void generateAdditionalArguments(SsaCodeGenerator codegen,
                                    HTypeConversion node,
                                    List<jsAst.Expression> arguments) {
@@ -108,6 +117,8 @@
 class SubtypeCheckedModeHelper extends CheckedModeHelper {
   const SubtypeCheckedModeHelper(String name) : super(name);
 
+  CallStructure get callStructure => const CallStructure.unnamed(4);
+
   void generateAdditionalArguments(SsaCodeGenerator codegen,
                                    HTypeConversion node,
                                    List<jsAst.Expression> arguments) {
diff --git a/pkg/compiler/lib/src/js_backend/codegen/codegen.dart b/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
index 92852b7..bcf0968 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
@@ -23,10 +23,14 @@
     BuiltinOperator;
 import '../../types/types.dart' show
     TypeMask;
+import '../../universe/call_structure.dart' show
+    CallStructure;
 import '../../universe/selector.dart' show
     Selector;
-import '../../universe/universe.dart' show
-    UniverseSelector;
+import '../../universe/use.dart' show
+    DynamicUse,
+    StaticUse,
+    TypeUse;
 import '../../util/maplet.dart';
 
 class CodegenBailout {
@@ -72,6 +76,7 @@
 
   /// Generates JavaScript code for the body of [function].
   js.Fun buildFunction(tree_ir.FunctionDefinition function) {
+    registerDefaultParameterValues(function.element);
     currentFunction = function.element;
     visitStatement(function.body);
 
@@ -235,7 +240,17 @@
   js.Expression buildStaticInvoke(Element target,
                                   List<js.Expression> arguments,
                                   {SourceInformation sourceInformation}) {
-    registry.registerStaticInvocation(target.declaration);
+    if (target.isConstructor) {
+      // TODO(johnniwinther): Avoid dependency on [isGenerativeConstructor] by
+      // using backend-specific [StatisUse] classes.
+      registry.registerStaticUse(
+          new StaticUse.constructorInvoke(target.declaration,
+              new CallStructure.unnamed(arguments.length)));
+    } else {
+      registry.registerStaticUse(
+          new StaticUse.staticInvoke(target.declaration,
+              new CallStructure.unnamed(arguments.length)));
+    }
     js.Expression elementAccess = glue.staticFunctionAccess(target);
     return new js.Call(elementAccess, arguments,
         sourceInformation: sourceInformation);
@@ -245,20 +260,22 @@
   js.Expression visitInvokeConstructor(tree_ir.InvokeConstructor node) {
     if (node.constant != null) return giveup(node);
 
-    registry.registerInstantiatedType(node.type);
+    registry.registerInstantiation(node.type);
     FunctionElement target = node.target;
     List<js.Expression> arguments = visitExpressionList(node.arguments);
     return buildStaticInvoke(
-        target, arguments, sourceInformation: node.sourceInformation);
+        target,
+        arguments,
+        sourceInformation: node.sourceInformation);
   }
 
   void registerMethodInvoke(tree_ir.InvokeMethod node) {
     Selector selector = node.selector;
     TypeMask mask = node.mask;
     if (selector.isGetter) {
-      registry.registerDynamicGetter(new UniverseSelector(selector, mask));
+      registry.registerDynamicUse(new DynamicUse(selector, mask));
     } else if (selector.isSetter) {
-      registry.registerDynamicSetter(new UniverseSelector(selector, mask));
+      registry.registerDynamicUse(new DynamicUse(selector, mask));
     } else {
       assert(invariant(CURRENT_ELEMENT_SPANNABLE,
           selector.isCall || selector.isOperator ||
@@ -266,8 +283,8 @@
           message: 'unexpected kind ${selector.kind}'));
       // TODO(sigurdm): We should find a better place to register the call.
       Selector call = new Selector.callClosureFrom(selector);
-      registry.registerDynamicInvocation(new UniverseSelector(call, null));
-      registry.registerDynamicInvocation(new UniverseSelector(selector, mask));
+      registry.registerDynamicUse(new DynamicUse(call, null));
+      registry.registerDynamicUse(new DynamicUse(selector, mask));
     }
   }
 
@@ -290,8 +307,20 @@
 
   @override
   js.Expression visitInvokeMethodDirectly(tree_ir.InvokeMethodDirectly node) {
-    registry.registerDirectInvocation(node.target.declaration);
+    if (node.isTearOff) {
+      // If this is a tear-off, register the fact that a tear-off closure
+      // will be created, and that this tear-off must bypass ordinary
+      // dispatch to ensure the super method is invoked.
+      registry.registerStaticUse(new StaticUse.staticInvoke(
+          glue.closureFromTearOff, new CallStructure.unnamed(
+            glue.closureFromTearOff.parameters.length)));
+      registry.registerStaticUse(new StaticUse.superTearOff(node.target));
+    }
     if (node.target is ConstructorBodyElement) {
+      registry.registerStaticUse(
+          new StaticUse.constructorBodyInvoke(
+              node.target.declaration,
+              new CallStructure.unnamed(node.arguments.length)));
       // A constructor body cannot be overriden or intercepted, so we can
       // use the short form for this invocation.
       return js.js('#.#(#)',
@@ -300,6 +329,10 @@
            visitExpressionList(node.arguments)])
           .withSourceInformation(node.sourceInformation);
     }
+    registry.registerStaticUse(
+        new StaticUse.superInvoke(
+            node.target.declaration,
+            new CallStructure.unnamed(node.arguments.length)));
     return js.js('#.#.call(#, #)',
         [glue.prototypeAccess(node.target.enclosingClass),
          glue.invocationName(node.selector),
@@ -359,7 +392,8 @@
     List<js.Expression> typeArguments = visitExpressionList(node.typeArguments);
     DartType type = node.type;
     if (type is InterfaceType) {
-      glue.registerIsCheck(type, registry);
+      registry.registerTypeUse(new TypeUse.isCheck(type));
+      //glue.registerIsCheck(type, registry);
       ClassElement clazz = type.element;
 
       if (glue.isStringClass(clazz)) {
@@ -404,7 +438,7 @@
           function,
           <js.Expression>[value, isT, typeArgumentArray, asT]);
     } else if (type is TypeVariableType || type is FunctionType) {
-      glue.registerIsCheck(type, registry);
+      registry.registerTypeUse(new TypeUse.isCheck(type));
 
       Element function = node.isTypeTest
           ? glue.getCheckSubtypeOfRuntimeType()
@@ -425,7 +459,8 @@
     js.Expression object = visitExpression(node.object);
     DartType dartType = node.dartType;
     assert(dartType.isInterfaceType);
-    glue.registerIsCheck(dartType, registry);
+    registry.registerTypeUse(new TypeUse.isCheck(dartType));
+    //glue.registerIsCheck(dartType, registry);
     js.Expression property = glue.getTypeTestTag(dartType);
     return js.js(r'#.#', [object, property]);
   }
@@ -470,6 +505,13 @@
            other is tree_ir.Break && node.target == other.target;
   }
 
+  /// True if the given break is equivalent to an unlabeled continue.
+  bool isShortContinue(tree_ir.Break node) {
+    tree_ir.Statement next = node.target.binding.next;
+    return next is tree_ir.Continue &&
+           next.target.binding == shortContinue.target;
+  }
+
   @override
   void visitBreak(tree_ir.Break node) {
     if (isEffectiveBreakTarget(node, fallthrough.target)) {
@@ -479,6 +521,10 @@
       // Unlabeled break to the break target or to an equivalent break.
       shortBreak.use();
       accumulator.add(new js.Break(null));
+    } else if (isShortContinue(node)) {
+      // An unlabeled continue is better than a labeled break.
+      shortContinue.use();
+      accumulator.add(new js.Continue(null));
     } else {
       usedLabels.add(node.target);
       accumulator.add(new js.Break(node.target.name));
@@ -663,7 +709,7 @@
     //               carry a DartType so we can register the instantiated type
     //               with its type arguments. Otherwise dataflow analysis is
     //               needed to reconstruct the instantiated type.
-    registry.registerInstantiatedClass(classElement);
+    registry.registerInstantiation(classElement.rawType);
     if (classElement is ClosureClassElement) {
       registry.registerInstantiatedClosure(classElement.methodElement);
     }
@@ -704,7 +750,7 @@
 
   @override
   js.Expression visitInterceptor(tree_ir.Interceptor node) {
-    glue.registerUseInterceptorInCodegen();
+    registry.registerUseInterceptor();
     registry.registerSpecializedGetInterceptor(node.interceptedClasses);
     js.Name helperName = glue.getInterceptorName(node.interceptedClasses);
     js.Expression globalHolder = glue.getInterceptorLibrary();
@@ -715,7 +761,7 @@
 
   @override
   js.Expression visitGetField(tree_ir.GetField node) {
-    registry.registerFieldGetter(node.field);
+    registry.registerStaticUse(new StaticUse.fieldGet(node.field));
     return new js.PropertyAccess(
         visitExpression(node.object),
         glue.instanceFieldPropertyName(node.field));
@@ -723,7 +769,7 @@
 
   @override
   js.Assignment visitSetField(tree_ir.SetField node) {
-    registry.registerFieldSetter(node.field);
+    registry.registerStaticUse(new StaticUse.fieldSet(node.field));
     js.PropertyAccess field =
         new js.PropertyAccess(
             visitExpression(node.object),
@@ -736,25 +782,29 @@
     assert(node.element is FieldElement || node.element is FunctionElement);
     if (node.element is FunctionElement) {
       // Tear off a method.
-      registry.registerGetOfStaticFunction(node.element.declaration);
+      registry.registerStaticUse(
+          new StaticUse.staticTearOff(node.element.declaration));
       return glue.isolateStaticClosureAccess(node.element);
     }
     if (glue.isLazilyInitialized(node.element)) {
       // Read a lazily initialized field.
-      registry.registerStaticUse(node.element.declaration);
+      registry.registerStaticUse(
+          new StaticUse.staticInit(node.element.declaration));
       js.Expression getter = glue.isolateLazyInitializerAccess(node.element);
       return new js.Call(getter, <js.Expression>[],
           sourceInformation: node.sourceInformation);
     }
     // Read an eagerly initialized field.
-    registry.registerStaticUse(node.element.declaration);
+    registry.registerStaticUse(
+        new StaticUse.staticGet(node.element.declaration));
     return glue.staticFieldAccess(node.element);
   }
 
   @override
   js.Expression visitSetStatic(tree_ir.SetStatic node) {
     assert(node.element is FieldElement);
-    registry.registerStaticUse(node.element.declaration);
+    registry.registerStaticUse(
+        new StaticUse.staticSet(node.element.declaration));
     js.Expression field = glue.staticFieldAccess(node.element);
     js.Expression value = visitExpression(node.value);
     return new js.Assignment(field, value);
@@ -784,7 +834,8 @@
       FunctionElement helper,
       List<js.Expression> arguments,
       {SourceInformation sourceInformation}) {
-    registry.registerStaticUse(helper);
+    registry.registerStaticUse(new StaticUse.staticInvoke(
+        helper, new CallStructure.unnamed(arguments.length)));
     return buildStaticInvoke(
         helper, arguments, sourceInformation: sourceInformation);
   }
@@ -826,8 +877,15 @@
   }
 
   js.Node handleForeignCode(tree_ir.ForeignCode node) {
-    registry.registerStaticUse(node.dependency);
-    // TODO(sra): Should this be in CodegenRegistry?
+    if (node.dependency != null) {
+      // Dependency is only used if [node] calls a Dart function. Currently only
+      // through foreign function `RAW_DART_FUNCTION_REF`.
+      registry.registerStaticUse(
+          new StaticUse.staticInvoke(
+              node.dependency,
+              new CallStructure.unnamed(node.arguments.length)));
+    }
+    // TODO(sra,johnniwinther): Should this be in CodegenRegistry?
     glue.registerNativeBehavior(node.nativeBehavior, node);
     return node.codeTemplate.instantiate(visitExpressionList(node.arguments));
   }
@@ -846,6 +904,7 @@
   void visitYield(tree_ir.Yield node) {
     js.Expression value = visitExpression(node.input);
     accumulator.add(new js.DartYield(value, node.hasStar));
+    visitStatement(node.next);
   }
 
   @override
@@ -883,11 +942,16 @@
       case BuiltinOperator.NumShr:
         // No normalization required since output is always uint32.
         return js.js('# >>> #', args);
+      case BuiltinOperator.NumBitNot:
+        return js.js('(~#) >>> 0', args);
+      case BuiltinOperator.NumNegate:
+        return js.js('-#', args);
       case BuiltinOperator.StringConcatenate:
         if (args.isEmpty) return js.string('');
         return args.reduce((e1,e2) => new js.Binary('+', e1, e2));
       case BuiltinOperator.Identical:
-        registry.registerStaticInvocation(glue.identicalFunction);
+        registry.registerStaticUse(new StaticUse.staticInvoke(
+            glue.identicalFunction, new CallStructure.unnamed(args.length)));
         return buildStaticHelperInvocation(glue.identicalFunction, args);
       case BuiltinOperator.StrictEq:
         return new js.Binary('===', args[0], args[1]);
@@ -1013,4 +1077,22 @@
     // We might need them if we want to emit raw JS nested functions.
     throw 'FunctionExpressions should not be used';
   }
+
+  /// Ensures that parameter defaults will be emitted.
+  ///
+  /// Ideally, this should be done when generating the relevant stub methods,
+  /// since those are the ones that actually reference the constants, but those
+  /// are created by the emitter when it is too late to register new constants.
+  ///
+  /// For non-static methods, we have no way of knowing if the defaults are
+  /// actually used, so we conservatively register them all.
+  void registerDefaultParameterValues(ExecutableElement element) {
+    if (element is! FunctionElement) return;
+    FunctionElement function = element;
+    if (function.isStatic) return; // Defaults are inlined at call sites.
+    function.functionSignature.forEachOptionalParameter((param) {
+      ConstantValue constant = glue.getDefaultParameterValue(param);
+      registry.registerCompileTimeConstant(constant);
+    });
+  }
 }
diff --git a/pkg/compiler/lib/src/js_backend/codegen/glue.dart b/pkg/compiler/lib/src/js_backend/codegen/glue.dart
index e6f5909..b441960 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/glue.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/glue.dart
@@ -4,6 +4,8 @@
 
 library code_generator_dependencies;
 
+import '../backend_helpers.dart' show
+    BackendHelpers;
 import '../js_backend.dart';
 
 import '../../common.dart';
@@ -39,10 +41,12 @@
 
   CodegenEnqueuer get _enqueuer => _compiler.enqueuer.codegen;
 
-  FunctionElement get getInterceptorMethod => _backend.getInterceptorMethod;
+  FunctionElement get getInterceptorMethod => _helpers.getInterceptorMethod;
 
   JavaScriptBackend get _backend => _compiler.backend;
 
+  BackendHelpers get _helpers => _backend.helpers;
+
   CodeEmitterTask get _emitter => _backend.emitter;
 
   Namer get _namer => _backend.namer;
@@ -65,10 +69,6 @@
     return classWorld.isUsedAsMixin(classElement);
   }
 
-  ConstantValue getConstantValueForVariable(VariableElement variable) {
-    return _backend.constants.getConstantValueForVariable(variable);
-  }
-
   js.Expression staticFunctionAccess(FunctionElement element) {
     return _backend.emitter.staticFunctionAccess(element);
   }
@@ -93,14 +93,14 @@
     return _namer.safeVariableName(name);
   }
 
-  ClassElement get listClass => _compiler.listClass;
+  ClassElement get listClass => _compiler.coreClasses.listClass;
 
   ConstructorElement get mapLiteralConstructor {
-    return _backend.mapLiteralConstructor;
+    return _helpers.mapLiteralConstructor;
   }
 
   ConstructorElement get mapLiteralConstructorEmpty {
-    return _backend.mapLiteralConstructorEmpty;
+    return _helpers.mapLiteralConstructorEmpty;
   }
 
   FunctionElement get identicalFunction => _compiler.identicalFunction;
@@ -110,11 +110,7 @@
   }
 
   FunctionElement get createInvocationMirrorMethod {
-    return _backend.helpers.createInvocationMirror;
-  }
-
-  void registerUseInterceptorInCodegen() {
-    _backend.registerUseInterceptor(_enqueuer);
+    return _helpers.createInvocationMirror;
   }
 
   bool isInterceptedSelector(Selector selector) {
@@ -126,7 +122,7 @@
   }
 
   bool isInterceptorClass(ClassElement element) {
-    return element.isSubclassOf(_backend.jsInterceptorClass);
+    return element.isSubclassOf(_helpers.jsInterceptorClass);
   }
 
   Set<ClassElement> getInterceptedClassesOn(Selector selector) {
@@ -165,59 +161,59 @@
 
   js.Expression getInterceptorLibrary() {
     return new js.VariableUse(
-        _backend.namer.globalObjectFor(_backend.interceptorsLibrary));
+        _backend.namer.globalObjectFor(_helpers.interceptorsLibrary));
   }
 
   FunctionElement getWrapExceptionHelper() {
-    return _backend.helpers.wrapExceptionHelper;
+    return _helpers.wrapExceptionHelper;
   }
 
   FunctionElement getExceptionUnwrapper() {
-    return _backend.helpers.exceptionUnwrapper;
+    return _helpers.exceptionUnwrapper;
   }
 
   FunctionElement getTraceFromException() {
-    return _backend.helpers.traceFromException;
+    return _helpers.traceFromException;
   }
 
   FunctionElement getCreateRuntimeType() {
-    return _backend.helpers.createRuntimeType;
+    return _helpers.createRuntimeType;
   }
 
   FunctionElement getRuntimeTypeToString() {
-    return _backend.helpers.runtimeTypeToString;
+    return _helpers.runtimeTypeToString;
   }
 
   FunctionElement getRuntimeTypeArgument() {
-    return _backend.helpers.getRuntimeTypeArgument;
+    return _helpers.getRuntimeTypeArgument;
   }
 
   FunctionElement getTypeArgumentByIndex() {
-    return _backend.helpers.getTypeArgumentByIndex;
+    return _helpers.getTypeArgumentByIndex;
   }
 
   FunctionElement getAddRuntimeTypeInformation() {
-    return _backend.helpers.setRuntimeTypeInfo;
+    return _helpers.setRuntimeTypeInfo;
   }
 
   /// checkSubtype(value, $isT, typeArgs, $asT)
   FunctionElement getCheckSubtype() {
-    return _backend.helpers.checkSubtype;
+    return _helpers.checkSubtype;
   }
 
   /// subtypeCast(value, $isT, typeArgs, $asT)
   FunctionElement getSubtypeCast() {
-    return _backend.helpers.subtypeCast;
+    return _helpers.subtypeCast;
   }
 
   /// checkSubtypeOfRuntime(value, runtimeType)
   FunctionElement getCheckSubtypeOfRuntimeType() {
-    return _backend.helpers.checkSubtypeOfRuntimeType;
+    return _helpers.checkSubtypeOfRuntimeType;
   }
 
   /// subtypeOfRuntimeTypeCast(value, runtimeType)
   FunctionElement getSubtypeOfRuntimeTypeCast() {
-    return _backend.helpers.subtypeOfRuntimeTypeCast;
+    return _helpers.subtypeOfRuntimeTypeCast;
   }
 
   js.Expression getRuntimeTypeName(ClassElement cls) {
@@ -247,15 +243,10 @@
         (_) => arguments[variableIndex++]);
     assert(variableIndex == arguments.length);
     // Representation contains JavaScript Arrays.
-    registry.registerInstantiatedClass(_backend.jsArrayClass);
+    registry.registerInstantiatedClass(_helpers.jsArrayClass);
     return representation;
   }
 
-  void registerIsCheck(DartType type, Registry registry) {
-    _enqueuer.registerIsCheck(type);
-    _backend.registerIsCheckForCodegen(type, _enqueuer, registry);
-  }
-
   js.Name getTypeTestTag(DartType type) {
     return _backend.namer.operatorIsType(type);
   }
@@ -272,23 +263,29 @@
     return _compiler.world.hasAnyStrictSubtype(element);
   }
 
-  ClassElement get jsFixedArrayClass => _backend.jsFixedArrayClass;
-  ClassElement get jsExtendableArrayClass => _backend.jsExtendableArrayClass;
+  ClassElement get jsFixedArrayClass => _helpers.jsFixedArrayClass;
+  ClassElement get jsExtendableArrayClass => _helpers.jsExtendableArrayClass;
   ClassElement get jsUnmodifiableArrayClass =>
-      _backend.jsUnmodifiableArrayClass;
-  ClassElement get jsMutableArrayClass => _backend.jsMutableArrayClass;
+      _helpers.jsUnmodifiableArrayClass;
+  ClassElement get jsMutableArrayClass => _helpers.jsMutableArrayClass;
 
   bool isStringClass(ClassElement classElement) =>
-      classElement == _backend.jsStringClass ||
-      classElement == _compiler.stringClass;
+      classElement == _helpers.jsStringClass ||
+      classElement == _compiler.coreClasses.stringClass;
 
   bool isBoolClass(ClassElement classElement) =>
-      classElement == _backend.jsBoolClass ||
-      classElement == _compiler.boolClass;
+      classElement == _helpers.jsBoolClass ||
+      classElement == _compiler.coreClasses.boolClass;
 
-  // TODO(sra): Should this be part of CodegenRegistry?
+  // TODO(sra,johnniwinther): Should this be part of CodegenRegistry?
   void registerNativeBehavior(NativeBehavior nativeBehavior, node) {
     if (nativeBehavior == null) return;
     _enqueuer.nativeEnqueuer.registerNativeBehavior(nativeBehavior, node);
   }
+
+  ConstantValue getDefaultParameterValue(ParameterElement elem) {
+    return _backend.constants.getConstantValueForVariable(elem);
+  }
+
+  FunctionElement get closureFromTearOff => _backend.helpers.closureFromTearOff;
 }
diff --git a/pkg/compiler/lib/src/js_backend/codegen/task.dart b/pkg/compiler/lib/src/js_backend/codegen/task.dart
index 28beb1c..d9881b2 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/task.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/task.dart
@@ -102,6 +102,7 @@
         }
         cps.FunctionDefinition cpsFunction = compileToCpsIr(element);
         cpsFunction = optimizeCpsIr(cpsFunction);
+        cpsIntegrityChecker = null;
         tree_ir.FunctionDefinition treeFunction = compileToTreeIr(cpsFunction);
         treeFunction = optimizeTreeIr(treeFunction);
         return compileToJavaScript(work, treeFunction);
@@ -133,7 +134,8 @@
   }
 
   cps.FunctionDefinition compileToCpsIr(AstElement element) {
-    cps.FunctionDefinition cpsFunction = cpsBuilderTask.buildNode(element);
+    cps.FunctionDefinition cpsFunction =
+        cpsBuilderTask.buildNode(element, typeSystem);
     if (cpsFunction == null) {
       if (cpsBuilderTask.bailoutMessage == null) {
         giveUp('unable to build cps definition of $element');
@@ -185,29 +187,38 @@
     }
   }
 
-  static bool checkCpsIntegrity(cps.FunctionDefinition node, String pass) {
-    new CheckCpsIntegrity().check(node, pass);
+  CheckCpsIntegrity cpsIntegrityChecker;
+
+  bool checkCpsIntegrity(cps.FunctionDefinition node, String previousPass) {
+    cpsOptimizationTask.measureSubtask('Check integrity', () {
+      if (cpsIntegrityChecker == null) {
+        cpsIntegrityChecker = new CheckCpsIntegrity();
+      }
+      cpsIntegrityChecker.check(node, previousPass);
+    });
     return true; // So this can be used from assert().
   }
 
   cps.FunctionDefinition optimizeCpsIr(cps.FunctionDefinition cpsFunction) {
-    TypeMaskSystem typeSystem = new TypeMaskSystem(compiler);
+    cpsOptimizationTask.measure(() {
+      TypeMaskSystem typeSystem = new TypeMaskSystem(compiler);
 
-    applyCpsPass(new RedundantJoinEliminator(), cpsFunction);
-    applyCpsPass(new RedundantPhiEliminator(), cpsFunction);
-    applyCpsPass(new InsertRefinements(typeSystem), cpsFunction);
-    applyCpsPass(new TypePropagator(compiler, typeSystem, this), cpsFunction);
-    applyCpsPass(new RemoveRefinements(), cpsFunction);
-    applyCpsPass(new ShrinkingReducer(), cpsFunction);
-    applyCpsPass(new ScalarReplacer(compiler), cpsFunction);
-    applyCpsPass(new MutableVariableEliminator(), cpsFunction);
-    applyCpsPass(new RedundantJoinEliminator(), cpsFunction);
-    applyCpsPass(new RedundantPhiEliminator(), cpsFunction);
-    applyCpsPass(new BoundsChecker(typeSystem, compiler.world), cpsFunction);
-    applyCpsPass(new ShrinkingReducer(), cpsFunction);
-    applyCpsPass(new ShareInterceptors(), cpsFunction);
-    applyCpsPass(new ShrinkingReducer(), cpsFunction);
-
+      applyCpsPass(new RedundantJoinEliminator(), cpsFunction);
+      applyCpsPass(new RedundantPhiEliminator(), cpsFunction);
+      applyCpsPass(new InsertRefinements(typeSystem), cpsFunction);
+      applyCpsPass(new TypePropagator(compiler, typeSystem, this), cpsFunction);
+      applyCpsPass(new ShareFinalFields(backend), cpsFunction);
+      applyCpsPass(new RemoveRefinements(), cpsFunction);
+      applyCpsPass(new ShrinkingReducer(), cpsFunction);
+      applyCpsPass(new ScalarReplacer(compiler), cpsFunction);
+      applyCpsPass(new MutableVariableEliminator(), cpsFunction);
+      applyCpsPass(new RedundantJoinEliminator(), cpsFunction);
+      applyCpsPass(new RedundantPhiEliminator(), cpsFunction);
+      applyCpsPass(new BoundsChecker(typeSystem, compiler.world), cpsFunction);
+      applyCpsPass(new ShrinkingReducer(), cpsFunction);
+      applyCpsPass(new ShareInterceptors(backend), cpsFunction);
+      applyCpsPass(new ShrinkingReducer(), cpsFunction);
+    });
     return cpsFunction;
   }
 
@@ -222,8 +233,10 @@
     return treeNode;
   }
 
-  static bool checkTreeIntegrity(tree_ir.FunctionDefinition node) {
-    new CheckTreeIntegrity().check(node);
+  bool checkTreeIntegrity(tree_ir.FunctionDefinition node) {
+    treeOptimizationTask.measureSubtask('Check integrity', () {
+      new CheckTreeIntegrity().check(node);
+    });
     return true; // So this can be used from assert().
   }
 
@@ -236,11 +249,13 @@
       assert(checkTreeIntegrity(node));
     }
 
-    applyTreePass(new StatementRewriter());
-    applyTreePass(new VariableMerger());
-    applyTreePass(new LoopRewriter());
-    applyTreePass(new LogicalRewriter());
-    applyTreePass(new PullIntoInitializers());
+    treeOptimizationTask.measure(() {
+      applyTreePass(new StatementRewriter());
+      applyTreePass(new VariableMerger());
+      applyTreePass(new LoopRewriter());
+      applyTreePass(new LogicalRewriter());
+      applyTreePass(new PullIntoInitializers());
+    });
 
     return node;
   }
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 3dca32b..57b54fd 100644
--- a/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
@@ -4,13 +4,19 @@
 
 library dart2js.constant_system.js;
 
-import '../compiler.dart' show Compiler;
+import '../compiler.dart' show
+    Compiler;
 import '../constants/constant_system.dart';
 import '../constants/values.dart';
 import '../constant_system_dart.dart';
+import '../core_types.dart' show
+    CoreTypes;
 import '../dart_types.dart';
-import '../elements/elements.dart' show ClassElement;
-import '../tree/tree.dart' show DartString, LiteralDartString;
+import '../elements/elements.dart' show
+    ClassElement;
+import '../tree/tree.dart' show
+    DartString,
+    LiteralDartString;
 import 'js_backend.dart';
 
 const JAVA_SCRIPT_CONSTANT_SYSTEM = const JavaScriptConstantSystem();
@@ -291,6 +297,7 @@
                              List<ConstantValue> keys,
                              List<ConstantValue> values) {
     JavaScriptBackend backend = compiler.backend;
+    CoreTypes coreTypes = compiler.coreTypes;
 
     bool onlyStringKeys = true;
     ConstantValue protoValue = null;
@@ -311,17 +318,16 @@
     bool hasProtoKey = (protoValue != null);
     DartType keysType;
     if (sourceType.treatAsRaw) {
-      keysType = compiler.listClass.rawType;
+      keysType = coreTypes.listType();
     } else {
-      List<DartType> arguments = <DartType>[sourceType.typeArguments.first];
-      keysType = new InterfaceType(compiler.listClass, arguments);
+      keysType = coreTypes.listType(sourceType.typeArguments.first);
     }
     ListConstantValue keysList = new ListConstantValue(keysType, keys);
     String className = onlyStringKeys
         ? (hasProtoKey ? JavaScriptMapConstant.DART_PROTO_CLASS
                        : JavaScriptMapConstant.DART_STRING_CLASS)
         : JavaScriptMapConstant.DART_GENERAL_CLASS;
-    ClassElement classElement = backend.jsHelperLibrary.find(className);
+    ClassElement classElement = backend.helpers.jsHelperLibrary.find(className);
     classElement.ensureResolved(compiler.resolution);
     List<DartType> typeArgument = sourceType.typeArguments;
     InterfaceType type;
diff --git a/pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart b/pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart
index 8ddbb43..1a5e287 100644
--- a/pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart
@@ -68,12 +68,12 @@
 
   void registerInstantiatedClass(ClassElement classElement, Enqueuer enqueuer) {
     classElement.ensureResolved(compiler.resolution);
-    if (!Elements.isNativeOrExtendsNative(classElement)) return;
+    if (!backend.isNativeOrExtendsNative(classElement)) return;
     if (classElement.isMixinApplication) return;
     if (classElement.isAbstract) return;
     // JsInterop classes are opaque interfaces without a concrete
     // implementation.
-    if (classElement.isJsInterop) return;
+    if (backend.isJsInterop(classElement)) return;
     joinFor(enqueuer).instantiatedClasses.add(classElement);
   }
 
@@ -91,9 +91,8 @@
     }
   }
 
-  void registerTypeConstant(Element element, Enqueuer enqueuer) {
+  void registerTypeConstant(Element element) {
     assert(element.isClass);
-    assert(!enqueuer.isResolutionQueue);
     codegenJoin.selectedClasses.add(element);
   }
 
@@ -101,8 +100,7 @@
     assert(element != null);
     if (!fetchedTableAccessorMethod) {
       fetchedTableAccessorMethod = true;
-      tableAccessorMethod = backend.findInterceptor(
-          'findIndexForNativeSubclassType');
+      tableAccessorMethod = backend.helpers.findIndexForNativeSubclassType;
     }
     if (element == tableAccessorMethod) {
       joinFor(enqueuer).demanded = true;
@@ -149,18 +147,20 @@
     if (!demanded) return;
     var newActiveClasses = new Set<ClassElement>();
     for (ClassElement classElement in instantiatedClasses) {
-      bool isNative = classElement.isNative;
+      bool isNative = backend.isNative(classElement);
       bool isExtension =
-          !isNative && Elements.isNativeOrExtendsNative(classElement);
+          !isNative && backend.isNativeOrExtendsNative(classElement);
       // Generate table entries for native classes that are explicitly named and
       // extensions that fix our criteria.
       if ((isNative && selectedClasses.contains(classElement)) ||
           (isExtension &&
               (allClassesSelected || selectedClasses.contains(classElement)))) {
         newActiveClasses.add(classElement);
-        Iterable<Element> escapingConstructors =
+        Iterable<ConstructorElement> escapingConstructors =
             computeEscapingConstructors(classElement);
-        escapingConstructors.forEach(enqueuer.registerStaticUse);
+        for (ConstructorElement constructor in escapingConstructors) {
+          enqueuer.registerStaticUse(new StaticUse.foreignUse(constructor));
+        }
         escapingConstructors
             .forEach(compiler.globalDependencies.registerDependency);
         // Force the generaton of the type constant that is the key to an entry
@@ -168,6 +168,7 @@
         ConstantValue constant = makeTypeConstant(classElement);
         backend.registerCompileTimeConstant(
             constant, compiler.globalDependencies);
+        backend.addCompileTimeConstantForEmission(constant);
       }
     }
     activeClasses.addAll(newActiveClasses);
@@ -179,17 +180,18 @@
     return backend.constantSystem.createType(compiler, elementType);
   }
 
-  List<Element> computeEscapingConstructors(ClassElement classElement) {
-    List<Element> result = <Element>[];
+  List<ConstructorElement> computeEscapingConstructors(
+      ClassElement classElement) {
+    List<ConstructorElement> result = <ConstructorElement>[];
     // Only classes that extend native classes have constructors in the table.
     // We could refine this to classes that extend Element, but that would break
     // the tests and there is no sane reason to subclass other native classes.
-    if (classElement.isNative) return result;
+    if (backend.isNative(classElement)) return result;
 
-    selectGenerativeConstructors(ClassElement enclosing, Element member) {
+    void selectGenerativeConstructors(ClassElement enclosing, Element member) {
       if (member.isGenerativeConstructor) {
         // Ignore constructors that cannot be called with zero arguments.
-        FunctionElement constructor = member;
+        ConstructorElement constructor = member;
         constructor.computeType(compiler.resolution);
         FunctionSignature parameters = constructor.functionSignature;
         if (parameters.requiredParameterCount == 0) {
diff --git a/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart b/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
index 707e7e76..0a89b42 100644
--- a/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
+++ b/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
@@ -14,17 +14,15 @@
   // this could be because the field belongs to a mixin. In such a case this
   // will return `null` and a normal field name has to be used.
   jsAst.Name _minifiedInstanceFieldPropertyName(Element element) {
-    if (element.hasFixedBackendName) {
-      return new StringBackedName(element.fixedBackendName);
+    if (backend.hasFixedBackendName(element)) {
+      return new StringBackedName(backend.getFixedBackendName(element));
     }
 
     _FieldNamingScope names;
     if (element is BoxFieldElement) {
       names = new _FieldNamingScope.forBox(element.box, fieldRegistry);
     } else {
-      ClassElement cls = element is ClosureFieldElement
-          ? element.closureClass
-          : element.enclosingClass;
+      ClassElement cls = element.enclosingClass;
       names =
           new _FieldNamingScope.forClass(cls, compiler.world, fieldRegistry);
     }
@@ -77,7 +75,7 @@
         nameStore.add(
             new StringBackedName(MinifyNamer._reservedNativeProperties[index]));
       } else {
-        nameStore.add(namer.getFreshName(NamingScope.instance, "field$index"));
+        nameStore.add(namer.getFreshName(namer.instanceScope, "field$index"));
       }
     }
 
diff --git a/pkg/compiler/lib/src/js_backend/frequency_namer.dart b/pkg/compiler/lib/src/js_backend/frequency_namer.dart
index 0aaf8f6..6fa2ccf 100644
--- a/pkg/compiler/lib/src/js_backend/frequency_namer.dart
+++ b/pkg/compiler/lib/src/js_backend/frequency_namer.dart
@@ -26,7 +26,7 @@
   }
 
   TokenScope newScopeFor(NamingScope scope) {
-    if (scope == NamingScope.instance) {
+    if (scope == instanceScope) {
       Set<String> illegalNames = new Set<String>.from(jsReserved);
       for (String illegal in MinifyNamer._reservedNativeProperties) {
         illegalNames.add(illegal);
@@ -50,8 +50,7 @@
 
     // Get the name the normal namer would use as a key.
     String proposed = _generateFreshStringForName(proposedName,
-                                                  getUsedNames(scope),
-                                                  getSuggestedNames(scope),
+                                                  scope,
                                                   sanitizeForNatives:
                                                   sanitizeForNatives,
                                                   sanitizeForAnnotations:
diff --git a/pkg/compiler/lib/src/js_backend/js_backend.dart b/pkg/compiler/lib/src/js_backend/js_backend.dart
index 3da429f..9c69c45 100644
--- a/pkg/compiler/lib/src/js_backend/js_backend.dart
+++ b/pkg/compiler/lib/src/js_backend/js_backend.dart
@@ -14,8 +14,10 @@
 import '../common.dart';
 import '../common/backend_api.dart' show
     Backend,
+    ImpactTransformer,
     ForeignResolver;
 import '../common/codegen.dart' show
+    CodegenImpact,
     CodegenRegistry,
     CodegenWorkItem;
 import '../common/names.dart' show
@@ -23,6 +25,7 @@
     Selectors,
     Uris;
 import '../common/registry.dart' show
+    EagerRegistry,
     Registry;
 import '../common/tasks.dart' show
     CompilerTask;
@@ -31,9 +34,7 @@
     ListLiteralUse,
     MapLiteralUse,
     Resolution,
-    ResolutionCallbacks,
-    ResolutionImpact,
-    TransformedWorldImpact;
+    ResolutionImpact;
 import '../common/work.dart' show
     ItemCompilationContext;
 import '../compiler.dart' show
@@ -42,15 +43,16 @@
 import '../constants/constant_system.dart';
 import '../constants/expressions.dart';
 import '../constants/values.dart';
+import '../core_types.dart' show
+    CoreClasses,
+    CoreTypes;
 import '../dart_types.dart';
 import '../elements/elements.dart';
 import '../elements/visitor.dart' show
     BaseElementVisitor;
 import '../enqueue.dart' show
     Enqueuer,
-    ResolutionEnqueuer,
-    WorldImpact;
-import '../helpers/helpers.dart';
+    ResolutionEnqueuer;
 import '../io/code_output.dart';
 import '../io/source_information.dart' show
     SourceInformationStrategy,
@@ -72,10 +74,6 @@
     USE_LAZY_EMITTER;
 import '../library_loader.dart' show LibraryLoader, LoadedLibraries;
 import '../native/native.dart' as native;
-import '../patch_parser.dart' show
-    checkJsInteropAnnotation;
-import '../resolution/registry.dart' show
-    EagerRegistry;
 import '../resolution/tree_elements.dart' show
     TreeElements;
 import '../ssa/ssa.dart';
@@ -87,6 +85,15 @@
     Selector,
     SelectorKind;
 import '../universe/universe.dart';
+import '../universe/use.dart' show
+    DynamicUse,
+    StaticUse,
+    StaticUseKind,
+    TypeUse,
+    TypeUseKind;
+import '../universe/world_impact.dart' show
+    TransformedWorldImpact,
+    WorldImpact;
 import '../util/characters.dart';
 import '../util/util.dart';
 import '../world.dart' show
diff --git a/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart b/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
index e6cce5b..65a49c8 100644
--- a/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
@@ -31,6 +31,7 @@
 import '../universe/selector.dart' show Selector;
 import '../universe/universe.dart' show SelectorConstraints;
 
+import 'backend_helpers.dart' show BackendHelpers;
 import 'js_backend.dart' show JavaScriptBackend;
 
 class JsInteropAnalysis {
@@ -45,11 +46,13 @@
 
   JsInteropAnalysis(this.backend);
 
+  BackendHelpers get helpers => backend.helpers;
+
   void onQueueClosed() {
     if (_inCodegen) return;
 
-    if (backend.jsAnnotationClass != null) {
-      nameField = backend.jsAnnotationClass.lookupMember('name');
+    if (helpers.jsAnnotationClass != null) {
+      nameField = helpers.jsAnnotationClass.lookupMember('name');
       backend.compiler.libraryLoader.libraries
           .forEach(processJsInteropAnnotationsInLibrary);
     }
@@ -65,14 +68,15 @@
           annotation.constant);
       if (constant == null || constant is! ConstructedConstantValue) continue;
       ConstructedConstantValue constructedConstant = constant;
-      if (constructedConstant.type.element == backend.jsAnnotationClass) {
+      if (constructedConstant.type.element == helpers.jsAnnotationClass) {
         ConstantValue value = constructedConstant.fields[nameField];
         if (value.isString) {
           StringConstantValue stringValue = value;
-          e.setJsInteropName(stringValue.primitiveValue.slowToString());
+          backend.setJsInteropName(
+              e, stringValue.primitiveValue.slowToString());
         } else {
           // TODO(jacobr): report a warning if the value is not a String.
-          e.setJsInteropName('');
+          backend.setJsInteropName(e, '');
         }
         enabledJsInterop = true;
         return;
@@ -81,7 +85,7 @@
   }
 
   bool hasAnonymousAnnotation(Element element) {
-    if (backend.jsAnonymousClass == null) return false;
+    if (backend.helpers.jsAnonymousClass == null) return false;
     return element.metadata.any((MetadataAnnotation annotation) {
       ConstantValue constant = backend.compiler.constants.getConstantValue(
           annotation.constant);
@@ -89,7 +93,7 @@
           constant is! ConstructedConstantValue) return false;
       ConstructedConstantValue constructedConstant = constant;
       return constructedConstant.type.element ==
-          backend.jsAnonymousClass;
+          backend.helpers.jsAnonymousClass;
     });
   }
 
@@ -107,7 +111,7 @@
     processJsInteropAnnotation(library);
     library.implementation.forEachLocalMember((Element element) {
       processJsInteropAnnotation(element);
-      if (!element.isJsInterop) return;
+      if (!backend.isJsInterop(element)) return;
       if (element is FunctionElement) {
         _checkFunctionParameters(element);
       }
@@ -117,7 +121,7 @@
       ClassElement classElement = element;
 
       if (!classElement
-          .implementsInterface(backend.jsJavaScriptObjectClass)) {
+          .implementsInterface(helpers.jsJavaScriptObjectClass)) {
         backend.reporter.reportErrorMessage(classElement,
             MessageKind.JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS, {
           'cls': classElement.name,
@@ -130,7 +134,7 @@
         processJsInteropAnnotation(member);
 
         if (!member.isSynthesized &&
-            classElement.isJsInterop &&
+            backend.isJsInterop(classElement) &&
             member is FunctionElement) {
           FunctionElement fn = member;
           if (!fn.isExternal && !fn.isAbstract && !fn.isConstructor &&
diff --git a/pkg/compiler/lib/src/js_backend/lookup_map_analysis.dart b/pkg/compiler/lib/src/js_backend/lookup_map_analysis.dart
index a6c1990..111eb22 100644
--- a/pkg/compiler/lib/src/js_backend/lookup_map_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/lookup_map_analysis.dart
@@ -68,6 +68,9 @@
 // ClassElement of a type to refer to keys we need to discover).
 // TODO(sigmund): detect uses of mirrors
 class LookupMapAnalysis {
+  static final Uri PACKAGE_LOOKUP_MAP =
+      new Uri(scheme: 'package', path: 'lookup_map/lookup_map.dart');
+
   /// Reference to [JavaScriptBackend] to be able to enqueue work when we
   /// discover that a key in a map is potentially used.
   final JavaScriptBackend backend;
@@ -205,8 +208,7 @@
     if (key is ConstructedConstantValue) {
       ClassElement element = key.type.element;
       return _typesWithEquals.putIfAbsent(element, () =>
-          element.lookupMember('==').enclosingClass !=
-          backend.compiler.objectClass);
+          !element.lookupMember('==').enclosingClass.isObject);
     }
     return false;
   }
@@ -411,8 +413,7 @@
     ConstantValue constant = unusedEntries.remove(key);
     usedEntries[key] = constant;
     analysis.backend.registerCompileTimeConstant(constant,
-        analysis.backend.compiler.globalDependencies,
-        addForEmission: false);
+        analysis.backend.compiler.globalDependencies);
   }
 
   /// Restores [original] to contain all of the entries marked as possibly used.
diff --git a/pkg/compiler/lib/src/js_backend/minify_namer.dart b/pkg/compiler/lib/src/js_backend/minify_namer.dart
index b781bc0..0ba2e4e 100644
--- a/pkg/compiler/lib/src/js_backend/minify_namer.dart
+++ b/pkg/compiler/lib/src/js_backend/minify_namer.dart
@@ -34,19 +34,17 @@
   /// minified names will always avoid clashing with annotated names or natives.
   @override
   String _generateFreshStringForName(String proposedName,
-      Set<String> usedNames,
-      Map<String, String> suggestedNames,
+      NamingScope scope,
       {bool sanitizeForNatives: false,
        bool sanitizeForAnnotations: false}) {
     String freshName;
-    String suggestion = suggestedNames[proposedName];
-    if (suggestion != null && !usedNames.contains(suggestion)) {
+    String suggestion = scope.suggestName(proposedName);
+    if (suggestion != null && scope.isUnused(suggestion)) {
       freshName = suggestion;
     } else {
-      freshName = _getUnusedName(proposedName, usedNames,
-          suggestedNames.values);
+      freshName = _getUnusedName(proposedName, scope);
     }
-    usedNames.add(freshName);
+    scope.registerUse(freshName);
     return freshName;
   }
 
@@ -85,12 +83,14 @@
         String disambiguatedName = name;
         reservePublicMemberName(name, disambiguatedName);
       }
-      usedInstanceNames.add(name);
+      instanceScope.registerUse(name);
       // Getter and setter names are autogenerated by prepending 'g' and 's' to
       // field names.  Therefore there are some field names we don't want to
       // use.  It is implicit in the next line that the banned prefix is
       // only one character.
-      if (_hasBannedPrefix(name)) usedInstanceNames.add(name.substring(1));
+      if (_hasBannedPrefix(name)) {
+        instanceScope.registerUse(name.substring(1));
+      }
     }
 
     // These popular names are present in most programs and deserve
@@ -99,8 +99,7 @@
     // minifier was less stable from version to version of the program being
     // minified.
     _populateSuggestedNames(
-        suggestedInstanceNames,
-        usedInstanceNames,
+        instanceScope,
         const <String>[
             r'$add', r'add$1', r'$and',
             r'$or',
@@ -115,8 +114,7 @@
             r'$tdiv', r'toString$0']);
 
     _populateSuggestedNames(
-        suggestedGlobalNames,
-        usedGlobalNames,
+        globalScope,
         const <String>[
             r'Object', 'wrapException', r'$eq', r'S', r'ioore',
             r'UnsupportedError$', r'length', r'$sub',
@@ -135,8 +133,7 @@
             ]);
   }
 
-  void _populateSuggestedNames(Map<String, String> suggestionMap,
-                               Set<String> used,
+  void _populateSuggestedNames(NamingScope scope,
                                List<String> suggestions) {
     int c = $a - 1;
     String letter;
@@ -145,9 +142,9 @@
         assert(c != $Z);
         c = (c == $z) ? $A : c + 1;
         letter = new String.fromCharCodes([c]);
-      } while (_hasBannedPrefix(letter) || used.contains(letter));
-      assert(suggestionMap[name] == null);
-      suggestionMap[name] = letter;
+      } while (_hasBannedPrefix(letter) || scope.isUsed(letter));
+      assert(!scope.hasSuggestion(name));
+      scope.addSuggestion(name, letter);
     }
   }
 
@@ -156,8 +153,7 @@
   // is slightly less efficient than just getting the next name in a series,
   // but it means that small changes in the input program will give smallish
   // changes in the output, which can be useful for diffing etc.
-  String _getUnusedName(String proposedName, Set<String> usedNames,
-                        Iterable<String> suggestions) {
+  String _getUnusedName(String proposedName, NamingScope scope) {
     int hash = _calculateHash(proposedName);
     // Avoid very small hashes that won't try many names.
     hash = hash < 1000 ? hash * 314159 : hash;  // Yes, it's prime.
@@ -177,10 +173,10 @@
           h2 ~/= ALPHANUMERIC_CHARACTERS;
         }
         final candidate = new String.fromCharCodes(codes);
-        if (!usedNames.contains(candidate) &&
+        if (scope.isUnused(candidate) &&
             !jsReserved.contains(candidate) &&
             !_hasBannedPrefix(candidate) &&
-            (n != 1 || !suggestions.contains(candidate))) {
+            (n != 1 || scope.isSuggestion(candidate))) {
           return candidate;
         }
         // Try again with a slightly different hash.  After around 10 turns
@@ -188,7 +184,7 @@
         h ~/= 7;
       }
     }
-    return _badName(hash, usedNames);
+    return _badName(hash, scope);
   }
 
   /// Instance members starting with g and s are reserved for getters and
@@ -217,7 +213,7 @@
 
   /// If we can't find a hash based name in the three-letter space, then base
   /// the name on a letter and a counter.
-  String _badName(int hash, Set<String> usedNames) {
+  String _badName(int hash, NamingScope scope) {
     int count = _badNames.putIfAbsent(hash, () => 0);
     String startLetter =
         new String.fromCharCodes([_letterNumber(hash + count)]);
@@ -226,7 +222,7 @@
     int i = 0;
     do {
       name = "$startLetter${i++}";
-    } while (usedNames.contains(name));
+    } while (scope.isUsed(name));
     // We don't need to check for banned prefix because the name is in the form
     // xnnn, where nnn is a number.  There can be no getter or setter called
     // gnnn since that would imply a numeric field name.
diff --git a/pkg/compiler/lib/src/js_backend/namer.dart b/pkg/compiler/lib/src/js_backend/namer.dart
index 783b518..768a072 100644
--- a/pkg/compiler/lib/src/js_backend/namer.dart
+++ b/pkg/compiler/lib/src/js_backend/namer.dart
@@ -370,7 +370,7 @@
   /// Although global names are distributed across a number of global objects,
   /// (see [globalObjectFor]), we currently use a single namespace for all these
   /// names.
-  final Set<String> usedGlobalNames = new Set<String>();
+  final NamingScope globalScope = new NamingScope();
   final Map<Element, jsAst.Name> userGlobals =
       new HashMap<Element, jsAst.Name>();
   final Map<String, jsAst.Name> internalGlobals =
@@ -379,7 +379,7 @@
   /// Used disambiguated names in the instance namespace, issued by
   /// [_disambiguateMember], [_disambiguateInternalMember],
   /// [_disambiguateOperator], and [reservePublicMemberName].
-  final Set<String> usedInstanceNames = new Set<String>();
+  final NamingScope instanceScope = new NamingScope();
   final Map<String, jsAst.Name> userInstanceMembers =
       new HashMap<String, jsAst.Name>();
   final Map<Element, jsAst.Name> internalInstanceMembers =
@@ -388,18 +388,11 @@
       new HashMap<String, jsAst.Name>();
 
   /// Used to disambiguate names for constants in [constantName].
-  final Set<String> usedConstantNames = new Set<String>();
+  final NamingScope constantScope = new NamingScope();
 
-  Set<String> getUsedNames(NamingScope scope) {
-    if (scope == NamingScope.global) {
-      return usedGlobalNames;
-    } else if (scope == NamingScope.instance){
-      return usedInstanceNames;
-    } else {
-      assert(scope == NamingScope.constant);
-      return usedConstantNames;
-    }
-  }
+  /// Used to store scopes for instances of [PrivatelyNamedJsEntity]
+  final Map<Entity, NamingScope> _privateNamingScopes =
+      new Map<Entity, NamingScope>();
 
   final Map<String, int> popularNameCounters = <String, int>{};
 
@@ -417,28 +410,9 @@
   final Map<String, LibraryElement> shortPrivateNameOwners =
       <String, LibraryElement>{};
 
-  /// Maps proposed names to *suggested* disambiguated names.
-  ///
-  /// Suggested names are hints to the [MinifyNamer], suggesting that a specific
-  /// names be given to the first item with the given proposed name.
-  ///
-  /// This is currently used in [MinifyNamer] to assign very short minified
-  /// names to things that tend to be used very often.
   final Map<String, String> suggestedGlobalNames = <String, String>{};
   final Map<String, String> suggestedInstanceNames = <String, String>{};
 
-  Map<String, String> getSuggestedNames(NamingScope scope) {
-    if (scope == NamingScope.global) {
-      return suggestedGlobalNames;
-    } else if (scope == NamingScope.instance) {
-      return suggestedInstanceNames;
-    } else {
-      assert(scope == NamingScope.constant);
-      return const {};
-    }
-  }
-
-
   /// Used to store unique keys for library names. Keys are not used as names,
   /// nor are they visible in the output. The only serve as an internal
   /// key into maps.
@@ -457,8 +431,12 @@
 
   JavaScriptBackend get backend => compiler.backend;
 
+  BackendHelpers get helpers => backend.helpers;
+
   DiagnosticReporter get reporter => compiler.reporter;
 
+  CoreClasses get coreClasses => compiler.coreClasses;
+
   String get deferredTypesName => 'deferredTypes';
   String get isolateName => 'Isolate';
   String get isolatePropertiesName => r'$isolateProperties';
@@ -472,6 +450,11 @@
   String get closureInvocationSelectorName => Identifiers.call;
   bool get shouldMinify => false;
 
+  NamingScope _getPrivateScopeFor(PrivatelyNamedJSEntity entity) {
+    return _privateNamingScopes.putIfAbsent(entity.rootOfScope,
+                                            () => new NamingScope());
+  }
+
   /// Returns the string that is to be used as the result of a call to
   /// [JS_GET_NAME] at [node] with argument [name].
   jsAst.Name getNameForJsGetName(Node node, JsGetName name) {
@@ -506,14 +489,13 @@
       case JsGetName.FUNCTION_TYPE_NAMED_PARAMETERS_TAG:
         return asName(functionTypeNamedParametersTag);
       case JsGetName.IS_INDEXABLE_FIELD_NAME:
-        Element cls = backend.findHelper('JavaScriptIndexingBehavior');
-        return operatorIs(cls);
+        return operatorIs(helpers.jsIndexingBehaviorInterface);
       case JsGetName.NULL_CLASS_TYPE_NAME:
-        return runtimeTypeName(compiler.nullClass);
+        return runtimeTypeName(coreClasses.nullClass);
       case JsGetName.OBJECT_CLASS_TYPE_NAME:
-        return runtimeTypeName(compiler.objectClass);
+        return runtimeTypeName(coreClasses.objectClass);
       case JsGetName.FUNCTION_CLASS_TYPE_NAME:
-        return runtimeTypeName(compiler.functionClass);
+        return runtimeTypeName(coreClasses.functionClass);
       default:
         reporter.reportErrorMessage(
           node,
@@ -542,7 +524,7 @@
     jsAst.Name result = constantNames[constant];
     if (result == null) {
       String longName = constantLongName(constant);
-      result = getFreshName(NamingScope.constant, longName);
+      result = getFreshName(constantScope, longName);
       constantNames[constant] = result;
     }
     return _newReference(result);
@@ -637,8 +619,9 @@
   }
 
   String _jsNameHelper(Element e) {
-    if (e.jsInteropName != null && e.jsInteropName.isNotEmpty)
-      return e.jsInteropName;
+    String jsInteropName = backend.getJsInteropName(e);
+    if (jsInteropName != null && jsInteropName.isNotEmpty)
+      return jsInteropName;
     return e.isLibrary ? 'self' : e.name;
   }
 
@@ -649,7 +632,7 @@
   /// Map class of the goog.map JavaScript library would have path
   /// "goog.maps.Map".
   String fixedBackendPath(Element element) {
-    if (!element.isJsInterop) return null;
+    if (!backend.isJsInterop(element)) return null;
     if (element.isInstanceMember) return 'this';
     if (element.isConstructor) return fixedBackendPath(element.enclosingClass);
     if (element.isLibrary) return 'self';
@@ -791,18 +774,21 @@
   jsAst.Name instanceFieldPropertyName(FieldElement element) {
     ClassElement enclosingClass = element.enclosingClass;
 
-    if (element.hasFixedBackendName) {
-      return new StringBackedName(element.fixedBackendName);
+    if (backend.hasFixedBackendName(element)) {
+      return new StringBackedName(backend.getFixedBackendName(element));
     }
 
-    // Instances of BoxFieldElement are special. They are already created with
-    // a unique and safe name. However, as boxes are not really instances of
-    // classes, the usual naming scheme that tries to avoid name clashes with
-    // super classes does not apply. We still do not mark the name as a
-    // fixedBackendName, as we want to allow other namers to do something more
-    // clever with them.
-    if (element is BoxFieldElement) {
-      return new StringBackedName(element.name);
+    // Some elements, like e.g. instances of BoxFieldElement are special.
+    // They are created with a unique and safe name for the element model.
+    // While their name is unique, it is not very readable. So we try to
+    // preserve the original, proposed name.
+    // However, as boxes are not really instances of classes, the usual naming
+    // scheme that tries to avoid name clashes with super classes does not
+    // apply. So we can directly grab a name.
+    Entity asEntity = element;
+    if (asEntity is JSEntity) {
+      return _disambiguateInternalMember(element,
+                                         () => asEntity.declaredEntity.name);
     }
 
     // If the name of the field might clash with another field,
@@ -832,8 +818,8 @@
 
   /// True if [class_] is a non-native class that inherits from a native class.
   bool _isUserClassExtendingNative(ClassElement class_) {
-    return !class_.isNative &&
-           Elements.isNativeOrExtendsNative(class_.superclass);
+    return !backend.isNative(class_) &&
+           backend.isNativeOrExtendsNative(class_.superclass);
   }
 
   /// Annotated name for the setter of [element].
@@ -878,7 +864,7 @@
   jsAst.Name _disambiguateInternalGlobal(String name) {
     jsAst.Name newName = internalGlobals[name];
     if (newName == null) {
-      newName = getFreshName(NamingScope.global, name);
+      newName = getFreshName(globalScope, name);
       internalGlobals[name] = newName;
     }
     return _newReference(newName);
@@ -925,7 +911,7 @@
     jsAst.Name newName = userGlobals[element];
     if (newName == null) {
       String proposedName = _proposeNameForGlobal(element);
-      newName = getFreshName(NamingScope.global, proposedName);
+      newName = getFreshName(globalScope, proposedName);
       userGlobals[element] = newName;
     }
     return _newReference(newName);
@@ -965,7 +951,7 @@
         // proposed name must be a valid identifier, but not necessarily unique.
         proposedName += r'$' + suffixes.join(r'$');
       }
-      newName = getFreshName(NamingScope.instance, proposedName,
+      newName = getFreshName(instanceScope, proposedName,
                              sanitizeForAnnotations: true);
       userInstanceMembers[key] = newName;
     }
@@ -988,7 +974,7 @@
     jsAst.Name newName = userInstanceMembers[key];
     if (newName == null) {
       String name = proposeName();
-      newName = getFreshName(NamingScope.instance, name,
+      newName = getFreshName(instanceScope, name,
                              sanitizeForAnnotations: true);
       userInstanceMembers[key] = newName;
     }
@@ -1010,9 +996,9 @@
     String suffix = ''; // We don't need any suffixes.
     String key = '$libraryPrefix@$originalName@$suffix';
     assert(!userInstanceMembers.containsKey(key));
-    assert(!usedInstanceNames.contains(disambiguatedName));
+    assert(!instanceScope.isUsed(disambiguatedName));
     userInstanceMembers[key] = new StringBackedName(disambiguatedName);
-    usedInstanceNames.add(disambiguatedName);
+    instanceScope.registerUse(disambiguatedName);
   }
 
   /// Disambiguated name unique to [element].
@@ -1026,11 +1012,22 @@
     jsAst.Name newName = internalInstanceMembers[element];
     if (newName == null) {
       String name = proposeName();
-      bool mayClashNative = _isUserClassExtendingNative(element.enclosingClass);
-      newName = getFreshName(NamingScope.instance, name,
-                             sanitizeForAnnotations: true,
-                             sanitizeForNatives: mayClashNative);
-      internalInstanceMembers[element] = newName;
+
+      Entity asEntity = element;
+      if (asEntity is PrivatelyNamedJSEntity) {
+        NamingScope scope = _getPrivateScopeFor(asEntity);
+        newName = getFreshName(scope, name,
+                               sanitizeForAnnotations: true,
+                               sanitizeForNatives: false);
+        internalInstanceMembers[element] = newName;
+      } else {
+        bool mayClashNative =
+            _isUserClassExtendingNative(element.enclosingClass);
+        newName = getFreshName(instanceScope, name,
+                               sanitizeForAnnotations: true,
+                               sanitizeForNatives: mayClashNative);
+        internalInstanceMembers[element] = newName;
+      }
     }
     return _newReference(newName);
   }
@@ -1044,15 +1041,14 @@
   jsAst.Name _disambiguateOperator(String operatorIdentifier) {
     jsAst.Name newName = userInstanceOperators[operatorIdentifier];
     if (newName == null) {
-      newName = getFreshName(NamingScope.instance, operatorIdentifier);
+      newName = getFreshName(instanceScope, operatorIdentifier);
       userInstanceOperators[operatorIdentifier] = newName;
     }
     return _newReference(newName);
   }
 
   String _generateFreshStringForName(String proposedName,
-      Set<String> usedNames,
-      Map<String, String> suggestedNames,
+      NamingScope scope,
       {bool sanitizeForAnnotations: false,
        bool sanitizeForNatives: false}) {
     if (sanitizeForAnnotations) {
@@ -1063,18 +1059,18 @@
     }
     proposedName = _sanitizeForKeywords(proposedName);
     String candidate;
-    if (!usedNames.contains(proposedName)) {
+    if (scope.isUnused(proposedName)) {
       candidate = proposedName;
     } else {
       int counter = popularNameCounters[proposedName];
       int i = (counter == null) ? 0 : counter;
-      while (usedNames.contains("$proposedName$i")) {
+      while (scope.isUsed("$proposedName$i")) {
         i++;
       }
       popularNameCounters[proposedName] = i + 1;
       candidate = "$proposedName$i";
     }
-    usedNames.add(candidate);
+    scope.registerUse(candidate);
     return candidate;
   }
 
@@ -1096,8 +1092,7 @@
                            bool sanitizeForNatives: false}) {
     String candidate =
         _generateFreshStringForName(proposedName,
-                                    getUsedNames(scope),
-                                    getSuggestedNames(scope),
+                                    scope,
                                     sanitizeForAnnotations:
                                         sanitizeForAnnotations,
                                     sanitizeForNatives: sanitizeForNatives);
@@ -1204,23 +1199,23 @@
 
   String suffixForGetInterceptor(Iterable<ClassElement> classes) {
     String abbreviate(ClassElement cls) {
-      if (cls == compiler.objectClass) return "o";
-      if (cls == backend.jsStringClass) return "s";
-      if (cls == backend.jsArrayClass) return "a";
-      if (cls == backend.jsDoubleClass) return "d";
-      if (cls == backend.jsIntClass) return "i";
-      if (cls == backend.jsNumberClass) return "n";
-      if (cls == backend.jsNullClass) return "u";
-      if (cls == backend.jsBoolClass) return "b";
-      if (cls == backend.jsInterceptorClass) return "I";
+      if (cls == coreClasses.objectClass) return "o";
+      if (cls == helpers.jsStringClass) return "s";
+      if (cls == helpers.jsArrayClass) return "a";
+      if (cls == helpers.jsDoubleClass) return "d";
+      if (cls == helpers.jsIntClass) return "i";
+      if (cls == helpers.jsNumberClass) return "n";
+      if (cls == helpers.jsNullClass) return "u";
+      if (cls == helpers.jsBoolClass) return "b";
+      if (cls == helpers.jsInterceptorClass) return "I";
       return cls.name;
     }
     List<String> names = classes
-        .where((cls) => !Elements.isNativeOrExtendsNative(cls))
+        .where((cls) => !backend.isNativeOrExtendsNative(cls))
         .map(abbreviate)
         .toList();
     // There is one dispatch mechanism for all native classes.
-    if (classes.any((cls) => Elements.isNativeOrExtendsNative(cls))) {
+    if (classes.any((cls) => backend.isNativeOrExtendsNative(cls))) {
       names.add("x");
     }
     // Sort the names of the classes after abbreviating them to ensure
@@ -1231,8 +1226,8 @@
 
   /// Property name used for `getInterceptor` or one of its specializations.
   jsAst.Name nameForGetInterceptor(Iterable<ClassElement> classes) {
-    FunctionElement getInterceptor = backend.getInterceptorMethod;
-    if (classes.contains(backend.jsInterceptorClass)) {
+    FunctionElement getInterceptor = helpers.getInterceptorMethod;
+    if (classes.contains(helpers.jsInterceptorClass)) {
       // If the base Interceptor class is in the set of intercepted classes, we
       // need to go through the generic getInterceptorMethod, since any subclass
       // of the base Interceptor could match.
@@ -1254,7 +1249,7 @@
     // other global names.
     jsAst.Name root = invocationName(selector);
 
-    if (classes.contains(backend.jsInterceptorClass)) {
+    if (classes.contains(helpers.jsInterceptorClass)) {
       // If the base Interceptor class is in the set of intercepted classes,
       // this is the most general specialization which uses the generic
       // getInterceptor method.
@@ -1364,7 +1359,7 @@
   String globalObjectFor(Element element) {
     if (_isPropertyOfStaticStateHolder(element)) return staticStateHolder;
     LibraryElement library = element.library;
-    if (library == backend.interceptorsLibrary) return 'J';
+    if (library == helpers.interceptorsLibrary) return 'J';
     if (library.isInternalLibrary) return 'H';
     if (library.isPlatformLibrary) {
       if ('${library.canonicalUri}' == 'dart:html') return 'W';
@@ -1432,7 +1427,7 @@
   jsAst.Name getFunctionTypeName(FunctionType functionType) {
     return functionTypeNameMap.putIfAbsent(functionType, () {
       String proposedName = functionTypeNamer.computeName(functionType);
-      return getFreshName(NamingScope.instance, proposedName);
+      return getFreshName(instanceScope, proposedName);
     });
   }
 
@@ -1568,7 +1563,6 @@
   void forgetElement(Element element) {
     jsAst.Name globalName = userGlobals[element];
     invariant(element, globalName != null, message: 'No global name.');
-    usedGlobalNames.remove(globalName);
     userGlobals.remove(element);
   }
 }
@@ -2024,8 +2018,29 @@
   }
 }
 
-enum NamingScope {
-  global,
-  instance,
-  constant
+
+class NamingScope {
+  /// Maps proposed names to *suggested* disambiguated names.
+  ///
+  /// Suggested names are hints to the [MinifyNamer], suggesting that a specific
+  /// names be given to the first item with the given proposed name.
+  ///
+  /// This is currently used in [MinifyNamer] to assign very short minified
+  /// names to things that tend to be used very often.
+  final Map<String, String> _suggestedNames = new Map<String, String>();
+  final Set<String> _usedNames = new Set<String>();
+
+  bool isUsed(String name) => _usedNames.contains(name);
+  bool isUnused(String name) => !_usedNames.contains(name);
+  bool registerUse(String name) => _usedNames.add(name);
+
+  String suggestName(String original) => _suggestedNames[original];
+  void addSuggestion(String original, String suggestion) {
+    assert(!_suggestedNames.containsKey(original));
+    _suggestedNames[original] = suggestion;
+  }
+  bool hasSuggestion(String original) => _suggestedNames.containsKey(original);
+  bool isSuggestion(String candidate) {
+    return _suggestedNames.containsValue(candidate);
+  }
 }
diff --git a/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart b/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart
index 3bb7e45..ee09ed3 100644
--- a/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart
+++ b/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart
@@ -167,9 +167,9 @@
 
   bool _isDefaultNoSuchMethodImplementation(FunctionElement element) {
     ClassElement classElement = element.enclosingClass;
-    return classElement == _compiler.objectClass
-        || classElement == _backend.jsInterceptorClass
-        || classElement == _backend.jsNullClass;
+    return classElement == _compiler.coreClasses.objectClass
+        || classElement == _backend.helpers.jsInterceptorClass
+        || classElement == _backend.helpers.jsNullClass;
   }
 
   bool _hasForwardingSyntax(FunctionElement element) {
diff --git a/pkg/compiler/lib/src/js_backend/patch_resolver.dart b/pkg/compiler/lib/src/js_backend/patch_resolver.dart
index c8e609d..60573ed 100644
--- a/pkg/compiler/lib/src/js_backend/patch_resolver.dart
+++ b/pkg/compiler/lib/src/js_backend/patch_resolver.dart
@@ -31,7 +31,7 @@
       });
       checkMatchingPatchSignatures(element, patch);
       element = patch;
-    } else if (!element.isJsInterop) {
+    } else if (!compiler.backend.isJsInterop(element)) {
       reporter.reportErrorMessage(
          element, MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION);
     }
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index a5136ad..849fae3 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -264,8 +264,9 @@
     // the calls of the list constructor whenever we determine that
     // JSArray needs type arguments.
     // TODO(karlklose): make this dependency visible from code.
-    if (backend.jsArrayClass != null) {
-      registerRtiDependency(backend.jsArrayClass, compiler.listClass);
+    if (backend.helpers.jsArrayClass != null) {
+      registerRtiDependency(
+          backend.helpers.jsArrayClass, compiler.coreClasses.listClass);
     }
     // Compute the set of all classes and methods that need runtime type
     // information.
diff --git a/pkg/compiler/lib/src/js_backend/type_variable_handler.dart b/pkg/compiler/lib/src/js_backend/type_variable_handler.dart
index 2ebda27..3fb220a 100644
--- a/pkg/compiler/lib/src/js_backend/type_variable_handler.dart
+++ b/pkg/compiler/lib/src/js_backend/type_variable_handler.dart
@@ -32,7 +32,7 @@
 
   TypeVariableHandler(this._compiler);
 
-  ClassElement get _typeVariableClass => _backend.typeVariableClass;
+  ClassElement get _typeVariableClass => _backend.helpers.typeVariableClass;
   CodeEmitterTask get _task => _backend.emitter;
   MetadataCollector get _metadataCollector => _task.metadataCollector;
   JavaScriptBackend get _backend => _compiler.backend;
@@ -56,7 +56,9 @@
         _backend.registerInstantiatedType(
             _typeVariableClass.rawType, enqueuer, registry);
         enqueuer.registerStaticUse(
-            _backend.registerBackendUse(_backend.helpers.createRuntimeType));
+            new StaticUse.staticInvoke(
+                _backend.registerBackendUse(_backend.helpers.createRuntimeType),
+                CallStructure.ONE_ARG));
         _seenClassesWithTypeVariables = true;
       }
     } else {
@@ -119,6 +121,7 @@
               arguments);
       ConstantValue value = constant.value;
       _backend.registerCompileTimeConstant(value, _compiler.globalDependencies);
+      _backend.addCompileTimeConstantForEmission(value);
       _backend.constants.addCompileTimeConstantForEmission(value);
       constants.add(
           _reifyTypeVariableConstant(value, currentTypeVariable.element));
diff --git a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
index cdd676b..87f9d41 100644
--- a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
@@ -206,7 +206,7 @@
   Namer namer = backend.namer;
   Compiler compiler = backend.compiler;
 
-  Element closureFromTearOff = backend.findHelper('closureFromTearOff');
+  Element closureFromTearOff = backend.helpers.closureFromTearOff;
   jsAst.Expression tearOffAccessExpression;
   jsAst.Expression tearOffGlobalObjectString;
   jsAst.Expression tearOffGlobalObject;
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart
index cb03c3e..f625c8a 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart
@@ -45,7 +45,7 @@
     emitRuntimeTypeInformation(cls, builder);
     emitNativeInfo(cls, builder);
 
-    if (classElement == backend.closureClass) {
+    if (classElement == backend.helpers.closureClass) {
       // We add a special getter here to allow for tearing off a closure from
       // itself.
       jsAst.Fun function = js('function() { return this; }');
@@ -253,8 +253,7 @@
       emitter.containerBuilder.addMemberMethod(method, builder);
     }
 
-    if (identical(classElement, compiler.objectClass)
-        && backend.enabledNoSuchMethod) {
+    if (classElement.isObject && backend.enabledNoSuchMethod) {
       // Emit the noSuchMethod handlers on the Object prototype now,
       // so that the code in the dynamicFunction helper can find
       // them. Note that this helper is invoked before analyzing the
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/code_emitter_helper.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/code_emitter_helper.dart
index 78c963d..6c7ee56 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/code_emitter_helper.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/code_emitter_helper.dart
@@ -11,6 +11,8 @@
 
   JavaScriptBackend get backend => emitter.backend;
 
+  BackendHelpers get helpers => backend.helpers;
+
   CodeEmitterTask get task => emitter.task;
 
   Compiler get compiler => emitter.compiler;
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
index 473766a..07ba88b 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
@@ -24,6 +24,8 @@
 import '../../compiler.dart' show
     Compiler;
 import '../../constants/values.dart';
+import '../../core_types.dart' show
+    CoreClasses;
 import '../../dart_types.dart' show
     DartType;
 import '../../deferred_load.dart' show OutputUnit;
@@ -54,6 +56,8 @@
     SourceMapBuilder;
 import '../../js/js.dart' as jsAst;
 import '../../js/js.dart' show js;
+import '../../js_backend/backend_helpers.dart' show
+    BackendHelpers;
 import '../../js_backend/js_backend.dart' show
     CheckedModeHelper,
     CompoundName,
@@ -131,6 +135,7 @@
   ConstantEmitter constantEmitter;
   NativeEmitter get nativeEmitter => task.nativeEmitter;
   TypeTestRegistry get typeTestRegistry => task.typeTestRegistry;
+  CoreClasses get coreClasses => compiler.coreClasses;
 
   // The full code that is written to each hunk part-file.
   Map<OutputUnit, CodeOutput> outputBuffers = new Map<OutputUnit, CodeOutput>();
@@ -370,7 +375,7 @@
     switch (builtin) {
       case JsBuiltin.dartObjectConstructor:
         return jsAst.js.expressionTemplateYielding(
-            typeAccess(compiler.objectClass));
+            typeAccess(coreClasses.objectClass));
 
       case JsBuiltin.isCheckPropertyToJsConstructorName:
         int isPrefixLength = namer.operatorIsPrefix.length;
@@ -445,13 +450,13 @@
   /// In minified mode we want to keep the name for the most common core types.
   bool _isNativeTypeNeedingReflectionName(Element element) {
     if (!element.isClass) return false;
-    return (element == compiler.intClass ||
-            element == compiler.doubleClass ||
-            element == compiler.numClass ||
-            element == compiler.stringClass ||
-            element == compiler.boolClass ||
-            element == compiler.nullClass ||
-            element == compiler.listClass);
+    return (element == coreClasses.intClass ||
+            element == coreClasses.doubleClass ||
+            element == coreClasses.numClass ||
+            element == coreClasses.stringClass ||
+            element == coreClasses.boolClass ||
+            element == coreClasses.nullClass ||
+            element == coreClasses.listClass);
   }
 
   /// Returns the "reflection name" of an [Element] or [Selector].
@@ -1187,8 +1192,8 @@
       // 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.className(compiler.objectClass);
+      assert(coreClasses.objectClass != null);
+      builder.superName = namer.className(coreClasses.objectClass);
       jsAst.Node declaration = builder.toObjectInitializer();
       jsAst.Name mangledName = namer.globalPropertyName(typedef);
       String reflectionName = getReflectionName(typedef, mangledName);
@@ -1833,14 +1838,16 @@
 
   ClassBuilder getElementDescriptor(Element element, Fragment fragment) {
     Element owner = element.library;
-    if (!element.isLibrary && !element.isTopLevel && !element.isNative) {
+    if (!element.isLibrary &&
+        !element.isTopLevel &&
+        !backend.isNative(element)) {
       // For static (not top level) elements, record their code in a buffer
       // specific to the class. For now, not supported for native classes and
       // native elements.
       ClassElement cls =
           element.enclosingClassOrCompilationUnit.declaration;
       if (compiler.codegenWorld.directlyInstantiatedClasses.contains(cls) &&
-          !cls.isNative &&
+          !backend.isNative(cls) &&
           compiler.deferredLoadTask.outputUnitForElement(element) ==
               compiler.deferredLoadTask.outputUnitForElement(cls)) {
         owner = cls;
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/interceptor_emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/interceptor_emitter.dart
index c9132ed..573dc34 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/interceptor_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/interceptor_emitter.dart
@@ -41,9 +41,9 @@
       Set<ClassElement> classes = specializedGetInterceptors[name];
       parts.add(
           js.statement('#.# = #',
-                       [namer.globalObjectFor(backend.interceptorsLibrary),
-                        name,
-                        buildGetInterceptorMethod(name, classes)]));
+              [namer.globalObjectFor(backend.helpers.interceptorsLibrary),
+               name,
+               buildGetInterceptorMethod(name, classes)]));
     }
 
     return new jsAst.Block(parts);
@@ -56,7 +56,8 @@
 
     InterceptorStubGenerator stubGenerator =
         new InterceptorStubGenerator(compiler, namer, backend);
-    String globalObject = namer.globalObjectFor(backend.interceptorsLibrary);
+    String globalObject =
+        namer.globalObjectFor(backend.helpers.interceptorsLibrary);
     for (jsAst.Name name in names) {
       jsAst.Expression function =
           stubGenerator.generateOneShotInterceptor(name);
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart
index f14b9a3..f8911bd 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart
@@ -160,7 +160,7 @@
     }
     // Startup code that loops over the method names and puts handlers on the
     // Object class to catch noSuchMethod invocations.
-    ClassElement objectClass = compiler.objectClass;
+    ClassElement objectClass = compiler.coreClasses.objectClass;
     jsAst.Expression createInvocationMirror = backend.emitter
         .staticFunctionAccess(backend.helpers.createInvocationMirror);
     if (useDiffEncoding) {
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart
index e256e7b..9ad63ab 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart
@@ -129,14 +129,14 @@
      'needsNativeSupport': program.needsNativeSupport,
      'enabledJsInterop': backend.jsInteropAnalysis.enabledJsInterop,
      'jsInteropBoostrap':backend.jsInteropAnalysis.buildJsInteropBootstrap(),
-     'isInterceptorClass': namer.operatorIs(backend.jsInterceptorClass),
-     'isObject' : namer.operatorIs(compiler.objectClass),
+     'isInterceptorClass': namer.operatorIs(backend.helpers.jsInterceptorClass),
+     'isObject' : namer.operatorIs(compiler.coreClasses.objectClass),
      'specProperty': js.string(namer.nativeSpecProperty),
      'trivialNsmHandlers': emitter.buildTrivialNsmHandlers(),
      'hasRetainedMetadata': backend.hasRetainedMetadata,
      'types': typesAccess,
      'objectClassName': js.quoteName(
-         namer.runtimeTypeName(compiler.objectClass)),
+         namer.runtimeTypeName(compiler.coreClasses.objectClass)),
      'needsStructuredMemberInfo': emitter.needsStructuredMemberInfo,
      'usesMangledNames':
           compiler.mirrorsLibrary != null || compiler.enabledFunctionApply,
diff --git a/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
index 886d3ed..2eabee0 100644
--- a/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
@@ -13,6 +13,8 @@
 
   Emitter get emitter => backend.emitter.emitter;
 
+  BackendHelpers get helpers => backend.helpers;
+
   jsAst.Expression generateGetInterceptorMethod(Set<ClassElement> classes) {
     jsAst.Expression interceptorFor(ClassElement cls) {
       return backend.emitter.interceptorPrototypeAccess(cls);
@@ -25,20 +27,20 @@
     jsAst.Statement buildInterceptorCheck(ClassElement cls) {
       jsAst.Expression condition;
       assert(backend.isInterceptorClass(cls));
-      if (cls == backend.jsBoolClass) {
+      if (cls == helpers.jsBoolClass) {
         condition = js('(typeof receiver) == "boolean"');
-      } else if (cls == backend.jsIntClass ||
-                 cls == backend.jsDoubleClass ||
-                 cls == backend.jsNumberClass) {
+      } else if (cls == helpers.jsIntClass ||
+                 cls == helpers.jsDoubleClass ||
+                 cls == helpers.jsNumberClass) {
         throw 'internal error';
-      } else if (cls == backend.jsArrayClass ||
-                 cls == backend.jsMutableArrayClass ||
-                 cls == backend.jsFixedArrayClass ||
-                 cls == backend.jsExtendableArrayClass) {
+      } else if (cls == helpers.jsArrayClass ||
+                 cls == helpers.jsMutableArrayClass ||
+                 cls == helpers.jsFixedArrayClass ||
+                 cls == helpers.jsExtendableArrayClass) {
         condition = js('receiver.constructor == Array');
-      } else if (cls == backend.jsStringClass) {
+      } else if (cls == helpers.jsStringClass) {
         condition = js('(typeof receiver) == "string"');
-      } else if (cls == backend.jsNullClass) {
+      } else if (cls == helpers.jsNullClass) {
         condition = js('receiver == null');
       } else {
         throw 'internal error';
@@ -58,16 +60,16 @@
           .hasInstantiatedNativeClasses();
 
     for (ClassElement cls in classes) {
-      if (cls == backend.jsArrayClass ||
-          cls == backend.jsMutableArrayClass ||
-          cls == backend.jsFixedArrayClass ||
-          cls == backend.jsExtendableArrayClass) hasArray = true;
-      else if (cls == backend.jsBoolClass) hasBool = true;
-      else if (cls == backend.jsDoubleClass) hasDouble = true;
-      else if (cls == backend.jsIntClass) hasInt = true;
-      else if (cls == backend.jsNullClass) hasNull = true;
-      else if (cls == backend.jsNumberClass) hasNumber = true;
-      else if (cls == backend.jsStringClass) hasString = true;
+      if (cls == helpers.jsArrayClass ||
+          cls == helpers.jsMutableArrayClass ||
+          cls == helpers.jsFixedArrayClass ||
+          cls == helpers.jsExtendableArrayClass) hasArray = true;
+      else if (cls == helpers.jsBoolClass) hasBool = true;
+      else if (cls == helpers.jsDoubleClass) hasDouble = true;
+      else if (cls == helpers.jsIntClass) hasInt = true;
+      else if (cls == helpers.jsNullClass) hasNull = true;
+      else if (cls == helpers.jsNumberClass) hasNumber = true;
+      else if (cls == helpers.jsStringClass) hasString = true;
       else {
         // The set of classes includes classes mixed-in to interceptor classes
         // and user extensions of native classes.
@@ -79,7 +81,7 @@
         // unresolved PlainJavaScriptObject by testing for anyNativeClasses.
 
         if (anyNativeClasses) {
-          if (Elements.isNativeOrExtendsNative(cls)) hasNative = true;
+          if (backend.isNativeOrExtendsNative(cls)) hasNative = true;
         }
       }
     }
@@ -103,13 +105,13 @@
       /// is the fallback used when we have determined that receiver
       /// is a JavaScript Number.
       jsAst.Expression interceptorForNumber = interceptorFor(
-          hasDouble ? backend.jsDoubleClass : backend.jsNumberClass);
+          hasDouble ? helpers.jsDoubleClass : helpers.jsNumberClass);
 
       if (hasInt) {
         whenNumber = js.statement('''{
             if (Math.floor(receiver) == receiver) return #;
             return #;
-        }''', [interceptorFor(backend.jsIntClass), interceptorForNumber]);
+        }''', [interceptorFor(helpers.jsIntClass), interceptorForNumber]);
       } else {
         whenNumber = js.statement('return #', interceptorForNumber);
       }
@@ -118,10 +120,10 @@
     }
 
     if (hasString) {
-      statements.add(buildInterceptorCheck(backend.jsStringClass));
+      statements.add(buildInterceptorCheck(helpers.jsStringClass));
     }
     if (hasNull) {
-      statements.add(buildInterceptorCheck(backend.jsNullClass));
+      statements.add(buildInterceptorCheck(helpers.jsNullClass));
     } else {
       // Returning "undefined" or "null" here will provoke a JavaScript
       // TypeError which is later identified as a null-error by
@@ -130,12 +132,12 @@
           js.statement('if (receiver == null) return receiver'));
     }
     if (hasBool) {
-      statements.add(buildInterceptorCheck(backend.jsBoolClass));
+      statements.add(buildInterceptorCheck(helpers.jsBoolClass));
     }
     // TODO(ahe): It might be faster to check for Array before
     // function and bool.
     if (hasArray) {
-      statements.add(buildInterceptorCheck(backend.jsArrayClass));
+      statements.add(buildInterceptorCheck(helpers.jsArrayClass));
     }
 
     if (hasNative) {
@@ -147,18 +149,19 @@
           if (receiver instanceof #) return receiver;
           return #(receiver);
       }''', [
-          interceptorFor(backend.jsJavaScriptFunctionClass),
-          backend.emitter.constructorAccess(compiler.objectClass),
+          interceptorFor(helpers.jsJavaScriptFunctionClass),
+          backend.emitter.constructorAccess(compiler.coreClasses.objectClass),
           backend.emitter
-              .staticFunctionAccess(backend.getNativeInterceptorMethod)]));
+              .staticFunctionAccess(helpers.getNativeInterceptorMethod)]));
 
     } else {
-      ClassElement jsUnknown = backend.jsUnknownJavaScriptObjectClass;
+      ClassElement jsUnknown = helpers.jsUnknownJavaScriptObjectClass;
       if (compiler.codegenWorld
               .directlyInstantiatedClasses.contains(jsUnknown)) {
         statements.add(
             js.statement('if (!(receiver instanceof #)) return #;',
-                [backend.emitter.constructorAccess(compiler.objectClass),
+                [backend.emitter.constructorAccess(
+                     compiler.coreClasses.objectClass),
                  interceptorFor(jsUnknown)]));
       }
 
@@ -183,9 +186,9 @@
             return a0 != null && receiver === a0;
         }''');
       }
-      if (!classes.contains(backend.jsIntClass)
-          && !classes.contains(backend.jsNumberClass)
-          && !classes.contains(backend.jsDoubleClass)) {
+      if (!classes.contains(helpers.jsIntClass)
+          && !classes.contains(helpers.jsNumberClass)
+          && !classes.contains(helpers.jsDoubleClass)) {
         return null;
       }
       if (selector.argumentCount == 1) {
@@ -227,12 +230,12 @@
       //        return receiver[a0] = a1;
       //      }
       //    }
-      bool containsArray = classes.contains(backend.jsArrayClass);
-      bool containsString = classes.contains(backend.jsStringClass);
+      bool containsArray = classes.contains(helpers.jsArrayClass);
+      bool containsString = classes.contains(helpers.jsStringClass);
       bool containsJsIndexable =
-          backend.jsIndexingBehaviorInterface.isResolved && classes.any((cls) {
+          helpers.jsIndexingBehaviorInterface.isResolved && classes.any((cls) {
         return compiler.world.isSubtypeOf(cls,
-            backend.jsIndexingBehaviorInterface);
+            helpers.jsIndexingBehaviorInterface);
       });
       // The index set operator requires a check on its set value in
       // checked mode, so we don't optimize the interceptor if the
@@ -309,7 +312,7 @@
     }
 
     jsAst.Name invocationName = backend.namer.invocationName(selector);
-    String globalObject = namer.globalObjectFor(backend.interceptorsLibrary);
+    String globalObject = namer.globalObjectFor(helpers.interceptorsLibrary);
 
     jsAst.Statement optimizedPath =
         _fastPathForOneShotInterceptor(selector, classes);
diff --git a/pkg/compiler/lib/src/js_emitter/js_emitter.dart b/pkg/compiler/lib/src/js_emitter/js_emitter.dart
index 540aad6..dbc6c9b 100644
--- a/pkg/compiler/lib/src/js_emitter/js_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/js_emitter.dart
@@ -48,6 +48,8 @@
     TypeVariableElement;
 import '../js/js.dart' as jsAst;
 import '../js/js.dart' show js;
+import '../js_backend/backend_helpers.dart' show
+    BackendHelpers;
 import '../js_backend/js_backend.dart' show
     CheckedModeHelper,
     CompoundName,
diff --git a/pkg/compiler/lib/src/js_emitter/lazy_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/lazy_emitter/emitter.dart
index 6a325ff..b2db5ab 100644
--- a/pkg/compiler/lib/src/js_emitter/lazy_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/lazy_emitter/emitter.dart
@@ -150,7 +150,7 @@
     switch (builtin) {
       case JsBuiltin.dartObjectConstructor:
         return js.js.expressionTemplateYielding(
-            typeAccess(_compiler.objectClass));
+            typeAccess(_compiler.coreClasses.objectClass));
 
       case JsBuiltin.isCheckPropertyToJsConstructorName:
         int isPrefixLength = namer.operatorIsPrefix.length;
diff --git a/pkg/compiler/lib/src/js_emitter/lazy_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/lazy_emitter/model_emitter.dart
index 0545b57..485195e 100644
--- a/pkg/compiler/lib/src/js_emitter/lazy_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/lazy_emitter/model_emitter.dart
@@ -9,6 +9,8 @@
 import '../../constants/values.dart' show
     ConstantValue,
     FunctionConstantValue;
+import '../../core_types.dart' show
+    CoreClasses;
 import '../../elements/elements.dart' show
     ClassElement,
     FunctionElement;
@@ -346,12 +348,13 @@
   js.Property emitMangledGlobalNames() {
     List<js.Property> names = <js.Property>[];
 
+    CoreClasses coreClasses = compiler.coreClasses;
     // We want to keep the original names for the most common core classes when
     // calling toString on them.
     List<ClassElement> nativeClassesNeedingUnmangledName =
-        [compiler.intClass, compiler.doubleClass, compiler.numClass,
-         compiler.stringClass, compiler.boolClass, compiler.nullClass,
-         compiler.listClass];
+        [coreClasses.intClass, coreClasses.doubleClass, coreClasses.numClass,
+         coreClasses.stringClass, coreClasses.boolClass, coreClasses.nullClass,
+         coreClasses.listClass];
     nativeClassesNeedingUnmangledName.forEach((element) {
         names.add(new js.Property(js.quoteName(namer.className(element)),
                                   js.string(element.name)));
diff --git a/pkg/compiler/lib/src/js_emitter/main_call_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/main_call_stub_generator.dart
index f391ed9..d3204e9 100644
--- a/pkg/compiler/lib/src/js_emitter/main_call_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/main_call_stub_generator.dart
@@ -11,6 +11,8 @@
 
   MainCallStubGenerator(this.compiler, this.backend, this.emitterTask);
 
+  BackendHelpers get helpers => backend.helpers;
+
   /// Returns the code equivalent to:
   ///   `function(args) { $.startRootIsolate(X.main$closure(), args); }`
   jsAst.Expression _buildIsolateSetupClosure(Element appMain,
@@ -23,13 +25,12 @@
         [emitterTask.staticFunctionAccess(isolateMain), mainAccess]);
   }
 
-
   jsAst.Statement generateInvokeMain() {
     Element main = compiler.mainFunction;
     jsAst.Expression mainCallClosure = null;
     if (compiler.hasIsolateSupport) {
       Element isolateMain =
-        backend.isolateHelperLibrary.find(JavaScriptBackend.START_ROOT_ISOLATE);
+        helpers.isolateHelperLibrary.find(BackendHelpers.START_ROOT_ISOLATE);
       mainCallClosure = _buildIsolateSetupClosure(main, isolateMain);
     } else if (compiler.hasIncrementalSupport) {
       mainCallClosure = js(
diff --git a/pkg/compiler/lib/src/js_emitter/native_emitter.dart b/pkg/compiler/lib/src/js_emitter/native_emitter.dart
index 9f87335..378b4a53 100644
--- a/pkg/compiler/lib/src/js_emitter/native_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/native_emitter.dart
@@ -34,8 +34,10 @@
 
   JavaScriptBackend get backend => compiler.backend;
 
+  BackendHelpers get helpers => backend.helpers;
+
   jsAst.Expression get defPropFunction {
-    Element element = backend.findHelper('defineProperty');
+    Element element = helpers.defineProperty;
     return emitterTask.staticFunctionAccess(element);
   }
 
@@ -86,11 +88,11 @@
     Class jsInterceptorClass = null;
 
     void walk(Class cls) {
-      if (cls.element == compiler.objectClass) {
+      if (cls.element == compiler.coreClasses.objectClass) {
         objectClass = cls;
         return;
       }
-      if (cls.element == backend.jsInterceptorClass) {
+      if (cls.element == helpers.jsInterceptorClass) {
         jsInterceptorClass = cls;
         return;
       }
@@ -134,9 +136,10 @@
       } else if (extensionPoints.containsKey(cls)) {
         needed = true;
       }
-      if (classElement.isJsInterop) {
+      if (backend.isJsInterop(classElement)) {
         needed = true;  // TODO(jacobr): we don't need all interop classes.
-      } else if (cls.isNative && native.nativeTagsForcedNonLeaf(classElement)) {
+      } else if (cls.isNative &&
+                 backend.hasNativeTagsForcedNonLeaf(classElement)) {
         needed = true;
         nonLeafClasses.add(cls);
       }
@@ -155,8 +158,8 @@
 
     for (Class cls in classes) {
       if (!cls.isNative) continue;
-      if (cls.element.isJsInterop) continue;
-      List<String> nativeTags = native.nativeTagsOfClass(cls.element);
+      if (backend.isJsInterop(cls.element)) continue;
+      List<String> nativeTags = backend.getNativeTagsOfClass(cls.element);
 
       if (nonLeafClasses.contains(cls) ||
           extensionPoints.containsKey(cls)) {
@@ -261,7 +264,7 @@
       FunctionElement member,
       List<jsAst.Parameter> stubParameters) {
     FunctionSignature parameters = member.functionSignature;
-    Element converter = backend.findHelper('convertDartClosureToJS');
+    Element converter = helpers.closureConverter;
     jsAst.Expression closureConverter =
         emitterTask.staticFunctionAccess(converter);
     parameters.forEachParameter((ParameterElement parameter) {
@@ -312,7 +315,7 @@
     assert(invariant(member, nativeMethods.contains(member)));
     // When calling a JS method, we call it with the native name, and only the
     // arguments up until the last one provided.
-    target = member.fixedBackendName;
+    target = backend.getFixedBackendName(member);
 
     if (isInterceptedMethod) {
       receiver = argumentsBuffer[0];
@@ -323,7 +326,7 @@
       assert(invariant(member, member.isStatic));
       arguments = argumentsBuffer.sublist(0,
           indexOfLastOptionalArgumentInParameters + 1);
-      if (member.isJsInterop) {
+      if (backend.isJsInterop(member)) {
         // fixedBackendPath is allowed to have the form foo.bar.baz for
         // interop. This template is uncached to avoid possibly running out of
         // memory when Dart2Js is run in server mode. In reality the risk of
@@ -359,7 +362,7 @@
     // is whether the receiver can be native, not the type of the test.
     if (element == null || !element.isClass) return false;
     ClassElement cls = element;
-    if (Elements.isNativeOrExtendsNative(cls)) return true;
+    if (backend.isNativeOrExtendsNative(cls)) return true;
     return isSupertypeOfNativeClass(element);
   }
 }
\ No newline at end of file
diff --git a/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
index 0d95278..c006e05 100644
--- a/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
@@ -118,7 +118,7 @@
     });
 
     var body;  // List or jsAst.Statement.
-    if (member.hasFixedBackendName) {
+    if (backend.hasFixedBackendName(member)) {
       body = emitterTask.nativeEmitter.generateParameterStubStatements(
           member, isInterceptedMethod, namer.invocationName(selector),
           parametersBuffer, argumentsBuffer,
@@ -190,7 +190,7 @@
                                                    {bool canTearOff: true}) {
     if (member.enclosingElement.isClosure) {
       ClosureClassElement cls = member.enclosingElement;
-      if (cls.supertype.element == backend.boundClosureClass) {
+      if (cls.supertype.element == backend.helpers.boundClosureClass) {
         reporter.internalError(cls.methodElement, 'Bound closure1.');
       }
       if (cls.methodElement.isInstanceMember) {
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
index 62ba314..268d671 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
@@ -42,6 +42,10 @@
 
   JavaScriptBackend get backend => compiler.backend;
 
+  BackendHelpers get helpers => backend.helpers;
+
+  CoreClasses get coreClasses => compiler.coreClasses;
+
   Collector(this.compiler, this.namer, this.rtiNeededClasses, this.emitter);
 
   Set<ClassElement> computeInterceptorsReferencedFromConstants() {
@@ -67,7 +71,7 @@
     Set<ClassElement> unneededClasses = new Set<ClassElement>();
     // The [Bool] class is not marked as abstract, but has a factory
     // constructor that always throws. We never need to emit it.
-    unneededClasses.add(compiler.boolClass);
+    unneededClasses.add(coreClasses.boolClass);
 
     // Go over specialized interceptors and then constants to know which
     // interceptors are needed.
@@ -84,18 +88,18 @@
     // Add unneeded interceptors to the [unneededClasses] set.
     for (ClassElement interceptor in backend.interceptedClasses) {
       if (!needed.contains(interceptor)
-          && interceptor != compiler.objectClass) {
+          && interceptor != coreClasses.objectClass) {
         unneededClasses.add(interceptor);
       }
     }
 
     // These classes are just helpers for the backend's type system.
-    unneededClasses.add(backend.jsMutableArrayClass);
-    unneededClasses.add(backend.jsFixedArrayClass);
-    unneededClasses.add(backend.jsExtendableArrayClass);
-    unneededClasses.add(backend.jsUInt32Class);
-    unneededClasses.add(backend.jsUInt31Class);
-    unneededClasses.add(backend.jsPositiveIntClass);
+    unneededClasses.add(helpers.jsMutableArrayClass);
+    unneededClasses.add(helpers.jsFixedArrayClass);
+    unneededClasses.add(helpers.jsExtendableArrayClass);
+    unneededClasses.add(helpers.jsUInt32Class);
+    unneededClasses.add(helpers.jsUInt31Class);
+    unneededClasses.add(helpers.jsPositiveIntClass);
 
     return (ClassElement cls) => !unneededClasses.contains(cls);
   }
@@ -213,30 +217,30 @@
     neededClasses.addAll(classesOnlyNeededForRti);
 
     // TODO(18175, floitsch): remove once issue 18175 is fixed.
-    if (neededClasses.contains(backend.jsIntClass)) {
-      neededClasses.add(compiler.intClass);
+    if (neededClasses.contains(helpers.jsIntClass)) {
+      neededClasses.add(coreClasses.intClass);
     }
-    if (neededClasses.contains(backend.jsDoubleClass)) {
-      neededClasses.add(compiler.doubleClass);
+    if (neededClasses.contains(helpers.jsDoubleClass)) {
+      neededClasses.add(coreClasses.doubleClass);
     }
-    if (neededClasses.contains(backend.jsNumberClass)) {
-      neededClasses.add(compiler.numClass);
+    if (neededClasses.contains(helpers.jsNumberClass)) {
+      neededClasses.add(coreClasses.numClass);
     }
-    if (neededClasses.contains(backend.jsStringClass)) {
-      neededClasses.add(compiler.stringClass);
+    if (neededClasses.contains(helpers.jsStringClass)) {
+      neededClasses.add(coreClasses.stringClass);
     }
-    if (neededClasses.contains(backend.jsBoolClass)) {
-      neededClasses.add(compiler.boolClass);
+    if (neededClasses.contains(helpers.jsBoolClass)) {
+      neededClasses.add(coreClasses.boolClass);
     }
-    if (neededClasses.contains(backend.jsArrayClass)) {
-      neededClasses.add(compiler.listClass);
+    if (neededClasses.contains(helpers.jsArrayClass)) {
+      neededClasses.add(coreClasses.listClass);
     }
 
     // 4. Finally, sort the classes.
     List<ClassElement> sortedClasses = Elements.sortedByPosition(neededClasses);
 
     for (ClassElement element in sortedClasses) {
-      if (Elements.isNativeOrExtendsNative(element) &&
+      if (backend.isNativeOrExtendsNative(element) &&
           !classesOnlyNeededForRti.contains(element)) {
         // For now, native classes and related classes cannot be deferred.
         nativeClassesAndSubclasses.add(element);
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart b/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart
index 0388bc9..3a84f11 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart
@@ -80,7 +80,7 @@
       // Keep track of whether or not we're dealing with a field mixin
       // into a native class.
       bool isMixinNativeField =
-          isClass && element.isNative && holder.isMixinApplication;
+          isClass && backend.isNative(element) && holder.isMixinApplication;
 
       // See if we can dynamically create getters and setters.
       // We can only generate getters and setters for [element] since
@@ -93,7 +93,7 @@
         needsSetter = fieldNeedsSetter(field);
       }
 
-      if ((isInstantiated && !holder.isNative)
+      if ((isInstantiated && !backend.isNative(holder))
           || needsGetter
           || needsSetter) {
         js.Name accessorName = namer.fieldAccessorName(field);
@@ -165,6 +165,6 @@
     // We never generate accessors for top-level/static fields.
     if (!member.isInstanceMember) return true;
     DartType type = member.type;
-    return type.treatAsDynamic || (type.element == compiler.objectClass);
+    return type.treatAsDynamic || type.isObject;
   }
 }
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
index 8ac784a..9471cac 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
@@ -16,16 +16,19 @@
     TypeTestProperties;
 import '../model.dart';
 
+import '../../closure.dart' show
+    ClosureFieldElement;
 import '../../common.dart';
 import '../../common/names.dart' show
-    Names;
+    Names,
+    Selectors;
 import '../../compiler.dart' show
     Compiler;
 import '../../constants/values.dart' show
     ConstantValue,
     InterceptorConstantValue;
-import '../../closure.dart' show
-    ClosureFieldElement;
+import '../../core_types.dart' show
+    CoreClasses;
 import '../../dart_types.dart' show
     DartType,
     FunctionType,
@@ -45,13 +48,13 @@
     TypedefElement,
     VariableElement;
 import '../../js/js.dart' as js;
+import '../../js_backend/backend_helpers.dart' show
+    BackendHelpers;
 import '../../js_backend/js_backend.dart' show
     Namer,
     JavaScriptBackend,
     JavaScriptConstantCompiler,
     StringBackedName;
-import '../../universe/call_structure.dart' show
-    CallStructure;
 import '../../universe/selector.dart' show
     Selector;
 import '../../universe/universe.dart' show
@@ -96,6 +99,7 @@
         this._registry = new Registry(compiler);
 
   JavaScriptBackend get backend => _compiler.backend;
+  BackendHelpers get helpers => backend.helpers;
   Universe get universe => _compiler.codegenWorld;
 
   /// Mapping from [ClassElement] to constructed [Class]. We need this to
@@ -350,15 +354,14 @@
   }
 
   void _addJsInteropStubs(LibrariesMap librariesMap) {
-    if (_classes.containsKey(_compiler.objectClass)) {
-      var toStringInvocation = namer.invocationName(new Selector.call(
-          new Name("toString", _compiler.objectClass.library),
-          CallStructure.NO_ARGS));
+    if (_classes.containsKey(_compiler.coreClasses.objectClass)) {
+      var toStringInvocation = namer.invocationName(Selectors.toString_);
       // TODO(jacobr): register toString as used so that it is always accessible
       // from JavaScript.
-      _classes[_compiler.objectClass].callStubs.add(_buildStubMethod(
-          new StringBackedName("toString"),
-          js.js('function() { return this.#(this) }', toStringInvocation)));
+      _classes[_compiler.coreClasses.objectClass].callStubs.add(
+          _buildStubMethod(
+              new StringBackedName("toString"),
+              js.js('function() { return this.#(this) }', toStringInvocation)));
     }
 
     // We add all members from classes marked with isJsInterop to the base
@@ -368,11 +371,11 @@
     // a regular getter that returns a JavaScript function and tearing off
     // a method in the case where there exist multiple JavaScript classes
     // that conflict on whether the member is a getter or a method.
-    var interceptorClass = _classes[backend.jsJavaScriptObjectClass];
+    var interceptorClass = _classes[helpers.jsJavaScriptObjectClass];
     var stubNames = new Set<String>();
     librariesMap.forEach((LibraryElement library, List<Element> elements) {
       for (Element e in elements) {
-        if (e is ClassElement && e.isJsInterop) {
+        if (e is ClassElement && backend.isJsInterop(e)) {
           e.declaration.forEachMember((_, Element member) {
             if (!member.isInstanceMember) return;
             if (member.isGetter || member.isField || member.isFunction) {
@@ -423,7 +426,7 @@
                   functionType = returnType;
                 } else if (returnType.treatAsDynamic ||
                     _compiler.types.isSubtype(returnType,
-                        backend.resolution.coreTypes.functionType)) {
+                        backend.coreTypes.functionType)) {
                   if (returnType.isTypedef) {
                     TypedefType typedef = returnType;
                     // TODO(jacobr): can we just use typdef.unaliased instead?
@@ -499,7 +502,7 @@
         .map(_buildStaticMethod)
         .toList();
 
-    if (library == backend.interceptorsLibrary) {
+    if (library == helpers.interceptorsLibrary) {
       statics.addAll(_generateGetInterceptorMethods());
       statics.addAll(_generateOneShotInterceptors());
     }
@@ -531,12 +534,12 @@
         element, name, null, [], instanceFields, [], [], [], [], [], [], null,
         isDirectlyInstantiated: true,
         onlyForRti: false,
-        isNative: element.isNative);
+        isNative: backend.isNative(element));
   }
 
   Class _buildClass(ClassElement element) {
     bool onlyForRti = collector.classesOnlyNeededForRti.contains(element);
-    if (element.isJsInterop) {
+    if (backend.isJsInterop(element)) {
       // TODO(jacobr): check whether the class has any active static fields
       // if it does not we can suppress it completely.
       onlyForRti = true;
@@ -578,7 +581,7 @@
 
     List<StubMethod> noSuchMethodStubs = <StubMethod>[];
 
-    if (backend.enabledNoSuchMethod && element == _compiler.objectClass) {
+    if (backend.enabledNoSuchMethod && element.isObject) {
       Map<js.Name, Selector> selectors =
           classStubGenerator.computeSelectorsForNsmHandlers();
       selectors.forEach((js.Name name, Selector selector) {
@@ -594,7 +597,7 @@
       });
     }
 
-    if (element == backend.closureClass) {
+    if (element == helpers.closureClass) {
       // We add a special getter here to allow for tearing off a closure from
       // itself.
       js.Name name = namer.getterForMember(Names.call);
@@ -622,9 +625,9 @@
 
     List<StubMethod> checkedSetters = <StubMethod>[];
     List<StubMethod> isChecks = <StubMethod>[];
-    if (element.isJsInterop) {
+    if (backend.isJsInterop(element)) {
       typeTests.properties.forEach((js.Name name, js.Node code) {
-        _classes[backend.jsInterceptorClass].isChecks.add(
+        _classes[helpers.jsInterceptorClass].isChecks.add(
             _buildStubMethod(name, code));
       });
     } else {
@@ -649,12 +652,12 @@
     // TODO(floitsch): we shouldn't update the registry in the middle of
     // building a class.
     Holder holder = _registry.registerHolder(holderName);
-    bool isInstantiated = !element.isJsInterop &&
+    bool isInstantiated = !backend.isJsInterop(element) &&
         _compiler.codegenWorld.directlyInstantiatedClasses.contains(element);
 
     Class result;
     if (element.isMixinApplication && !onlyForRti) {
-      assert(!element.isNative);
+      assert(!backend.isNative(element));
       assert(methods.isEmpty);
 
       result = new MixinApplication(element,
@@ -680,7 +683,7 @@
                          typeTests.functionTypeIndex,
                          isDirectlyInstantiated: isInstantiated,
                          onlyForRti: onlyForRti,
-                         isNative: element.isNative);
+                         isNative: backend.isNative(element));
     }
     _classes[element] = result;
     return result;
@@ -864,7 +867,7 @@
     InterceptorStubGenerator stubGenerator =
         new InterceptorStubGenerator(_compiler, namer, backend);
 
-    String holderName = namer.globalObjectFor(backend.interceptorsLibrary);
+    String holderName = namer.globalObjectFor(helpers.interceptorsLibrary);
     // TODO(floitsch): we shouldn't update the registry in the middle of
     // generating the interceptor methods.
     Holder holder = _registry.registerHolder(holderName);
@@ -929,7 +932,7 @@
     InterceptorStubGenerator stubGenerator =
         new InterceptorStubGenerator(_compiler, namer, backend);
 
-    String holderName = namer.globalObjectFor(backend.interceptorsLibrary);
+    String holderName = namer.globalObjectFor(helpers.interceptorsLibrary);
     // TODO(floitsch): we shouldn't update the registry in the middle of
     // generating the interceptor methods.
     Holder holder = _registry.registerHolder(holderName);
diff --git a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
index 8b20e2d..61c1b08 100644
--- a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
@@ -68,7 +68,7 @@
     /// native classes.
     /// TODO(herhut): Generate tests for native classes dynamically, as well.
     void generateIsTest(Element other) {
-      if (classElement.isJsInterop || classElement.isNative ||
+      if (backend.isNative(classElement) ||
           !classElement.isSubclassOf(other)) {
         result.properties[namer.operatorIs(other)] = js('1');
       }
@@ -180,7 +180,8 @@
       return backend.rti.isTrivialSubstitution(a, b);
     }
 
-    if (superclass != null && superclass != compiler.objectClass &&
+    if (superclass != null &&
+        superclass != compiler.coreClasses.objectClass &&
         !haveSameTypeVariables(cls, superclass)) {
       // We cannot inherit the generated substitutions, because the type
       // variable layout for this class is different.  Instead we generate
@@ -216,7 +217,7 @@
 
     // 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) ||
+    if (checkedClasses.contains(compiler.coreClasses.functionClass) ||
         checkedFunctionTypes.isNotEmpty) {
       Element call = cls.lookupLocalMember(Identifiers.call);
       if (call == null) {
@@ -228,7 +229,7 @@
         // 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,
+          _generateInterfacesIsTests(compiler.coreClasses.functionClass,
                                     generateIsTest,
                                     generateSubstitution,
                                     generated);
@@ -313,7 +314,7 @@
               js.number(index));
     }
     jsAst.Expression convertRtiToRuntimeType = backend.emitter
-         .staticFunctionAccess(backend.findHelper('convertRtiToRuntimeType'));
+         .staticFunctionAccess(backend.helpers.convertRtiToRuntimeType);
 
     return new StubMethod(name,
                           js('function () { return #(#) }',
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
index 7f8e845..40fd877 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
@@ -146,7 +146,7 @@
     switch (builtin) {
       case JsBuiltin.dartObjectConstructor:
         return js.js.expressionTemplateYielding(
-            typeAccess(_compiler.objectClass));
+            typeAccess(_compiler.coreClasses.objectClass));
 
       case JsBuiltin.isCheckPropertyToJsConstructorName:
         int isPrefixLength = namer.operatorIsPrefix.length;
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
index c8e6a75..7fbd768 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
@@ -1091,12 +1091,13 @@
   js.Property emitMangledGlobalNames() {
     List<js.Property> names = <js.Property>[];
 
+    CoreClasses coreClasses = compiler.coreClasses;
     // We want to keep the original names for the most common core classes when
     // calling toString on them.
     List<ClassElement> nativeClassesNeedingUnmangledName =
-        [compiler.intClass, compiler.doubleClass, compiler.numClass,
-         compiler.stringClass, compiler.boolClass, compiler.nullClass,
-         compiler.listClass];
+        [coreClasses.intClass, coreClasses.doubleClass, coreClasses.numClass,
+          coreClasses.stringClass, coreClasses.boolClass, coreClasses.nullClass,
+          coreClasses.listClass];
     // TODO(floitsch): this should probably be on a per-fragment basis.
     nativeClassesNeedingUnmangledName.forEach((element) {
       names.add(new js.Property(js.quoteName(namer.className(element)),
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
index 2a06960..739fe77 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
@@ -35,6 +35,8 @@
     FunctionConstantValue;
 import '../../compiler.dart' show
     Compiler;
+import '../../core_types.dart' show
+    CoreClasses;
 import '../../elements/elements.dart' show
     ClassElement,
     FunctionElement;
diff --git a/pkg/compiler/lib/src/library_loader.dart b/pkg/compiler/lib/src/library_loader.dart
index 5759b52..71bfd9f 100644
--- a/pkg/compiler/lib/src/library_loader.dart
+++ b/pkg/compiler/lib/src/library_loader.dart
@@ -31,7 +31,6 @@
     PrefixElementX,
     SyntheticImportElement;
 
-import 'native/native.dart' as native;
 import 'script.dart';
 import 'tree/tree.dart';
 import 'util/util.dart' show
@@ -631,7 +630,6 @@
         handler.registerNewLibrary(element);
         libraryCanonicalUriMap[resolvedUri] = element;
       }
-      native.maybeEnableNative(compiler, element);
       compiler.scanner.scanLibrary(element);
       return element;
     });
@@ -975,7 +973,7 @@
 
     Element existingElement = exportScope[name];
     if (existingElement != null && existingElement != element) {
-      if (existingElement.isErroneous) {
+      if (existingElement.isMalformed) {
         createDuplicateExportMessage(element, exports);
         createDuplicateExportDeclMessage(element, exports);
         element = existingElement;
diff --git a/pkg/compiler/lib/src/mirrors/analyze.dart b/pkg/compiler/lib/src/mirrors/analyze.dart
index 733cbae..ad3c0ea 100644
--- a/pkg/compiler/lib/src/mirrors/analyze.dart
+++ b/pkg/compiler/lib/src/mirrors/analyze.dart
@@ -54,7 +54,7 @@
     diagnosticHandler(uri, begin, end, message, kind);
   }
 
-  Compiler compiler = new apiimpl.Compiler(
+  Compiler compiler = new apiimpl.CompilerImpl(
       new LegacyCompilerInput(inputProvider),
       new LegacyCompilerOutput(),
       new LegacyCompilerDiagnostics(internalDiagnosticHandler),
diff --git a/pkg/compiler/lib/src/mirrors/dart2js_type_mirrors.dart b/pkg/compiler/lib/src/mirrors/dart2js_type_mirrors.dart
index a5e6e94..b2a2ea5 100644
--- a/pkg/compiler/lib/src/mirrors/dart2js_type_mirrors.dart
+++ b/pkg/compiler/lib/src/mirrors/dart2js_type_mirrors.dart
@@ -397,7 +397,7 @@
 
   ClassMirror get originalDeclaration =>
       mirrorSystem._getTypeDeclarationMirror(
-          mirrorSystem.compiler.functionClass);
+          mirrorSystem.compiler.coreClasses.functionClass);
 
   // TODO(johnniwinther): Substitute type arguments for type variables.
   ClassMirror get superclass => originalDeclaration.superclass;
diff --git a/pkg/compiler/lib/src/native/enqueue.dart b/pkg/compiler/lib/src/native/enqueue.dart
index 42ceba2..c96f7da 100644
--- a/pkg/compiler/lib/src/native/enqueue.dart
+++ b/pkg/compiler/lib/src/native/enqueue.dart
@@ -95,9 +95,11 @@
         processedLibraries = compiler.cacheStrategy.newSet();
 
   JavaScriptBackend get backend => compiler.backend;
+  BackendHelpers get helpers => backend.helpers;
   Resolution get resolution => compiler.resolution;
 
   DiagnosticReporter get reporter => compiler.reporter;
+  CoreTypes get coreTypes => compiler.coreTypes;
 
   void processNativeClasses(Iterable<LibraryElement> libraries) {
     if (compiler.hasIncrementalSupport) {
@@ -107,8 +109,8 @@
       libraries = libraries.where(processedLibraries.add);
     }
     libraries.forEach(processNativeClassesInLibrary);
-    if (backend.isolateHelperLibrary != null) {
-      processNativeClassesInLibrary(backend.isolateHelperLibrary);
+    if (helpers.isolateHelperLibrary != null) {
+      processNativeClassesInLibrary(helpers.isolateHelperLibrary);
     }
     processSubclassesOfNativeClasses(libraries);
     if (!enableLiveTypeAnalysis) {
@@ -120,7 +122,7 @@
   void processNativeClassesInLibrary(LibraryElement library) {
     // Use implementation to ensure the inclusion of injected members.
     library.implementation.forEachLocalMember((Element element) {
-      if (element.isClass && element.isNative) {
+      if (element.isClass && backend.isNative(element)) {
         processNativeClass(element);
       }
     });
@@ -162,7 +164,7 @@
     // fact a subclass of a native class.
 
     ClassElement nativeSuperclassOf(ClassElement classElement) {
-      if (classElement.isNative) return classElement;
+      if (backend.isNative(classElement)) return classElement;
       if (classElement.superclass == null) return null;
       return nativeSuperclassOf(classElement.superclass);
     }
@@ -173,7 +175,7 @@
       ClassElement nativeSuperclass = nativeSuperclassOf(element);
       if (nativeSuperclass != null) {
         nativeClassesAndSubclasses.add(element);
-        if (!element.isNative) {
+        if (!backend.isNative(element)) {
           nonNativeSubclasses.putIfAbsent(nativeSuperclass,
               () => new Set<ClassElement>())
             .add(element);
@@ -268,7 +270,7 @@
   void findAnnotationClasses() {
     if (_annotationCreatesClass != null) return;
     ClassElement find(name) {
-      Element e = backend.findHelper(name);
+      Element e = helpers.findHelper(name);
       if (e == null || e is! ClassElement) {
         reporter.internalError(NO_LOCATION_SPANNABLE,
             "Could not find implementation class '${name}'.");
@@ -348,14 +350,17 @@
 
   registerElement(Element element) {
     reporter.withCurrentElement(element, () {
-      if (element.isFunction || element.isGetter || element.isSetter) {
+      if (element.isFunction ||
+          element.isFactoryConstructor ||
+          element.isGetter ||
+          element.isSetter) {
         handleMethodAnnotations(element);
-        if (element.isNative) {
+        if (backend.isNative(element)) {
           registerMethodUsed(element);
         }
       } else if (element.isField) {
         handleFieldAnnotations(element);
-        if (element.isNative) {
+        if (backend.isNative(element)) {
           registerFieldLoad(element);
           registerFieldStore(element);
         }
@@ -364,7 +369,7 @@
   }
 
   handleFieldAnnotations(Element element) {
-    if (element.enclosingElement.isNative) {
+    if (backend.isNative(element.enclosingElement)) {
       // Exclude non-instance (static) fields - they not really native and are
       // compiled as isolate globals.  Access of a property of a constructor
       // function or a non-method property in the prototype chain, must be coded
@@ -387,10 +392,10 @@
 
   /// Sets the native name of [element], either from an annotation, or
   /// defaulting to the Dart name.
-  void setNativeName(ElementX element) {
+  void setNativeName(MemberElement element) {
     String name = findJsNameFromAnnotation(element);
     if (name == null) name = element.name;
-    element.setNative(name);
+    backend.setNativeMemberName(element, name);
   }
 
   /// Sets the native name of the static native method [element], using the
@@ -401,26 +406,27 @@
   ///    use the declared @JSName as the expression
   /// 3. If [element] does not have a @JSName annotation, qualify the name of
   ///    the method with the @Native name of the enclosing class.
-  void setNativeNameForStaticMethod(ElementX element) {
+  void setNativeNameForStaticMethod(MethodElement element) {
     String name = findJsNameFromAnnotation(element);
     if (name == null) name = element.name;
     if (isIdentifier(name)) {
-      List<String> nativeNames = nativeTagsOfClassRaw(element.enclosingClass);
+      List<String> nativeNames =
+          backend.getNativeTagsOfClassRaw(element.enclosingClass);
       if (nativeNames.length != 1) {
         reporter.internalError(element,
             'Unable to determine a native name for the enclosing class, '
             'options: $nativeNames');
       }
-      element.setNative('${nativeNames[0]}.$name');
+      backend.setNativeMemberName(element, '${nativeNames[0]}.$name');
     } else {
-      element.setNative(name);
+      backend.setNativeMemberName(element, name);
     }
   }
 
   bool isIdentifier(String s) => _identifier.hasMatch(s);
 
   bool isNativeMethod(FunctionElementX element) {
-    if (!element.library.canUseNative) return false;
+    if (!backend.canLibraryUseNative(element.library)) return false;
     // Native method?
     return reporter.withCurrentElement(element, () {
       Node node = element.parseNode(resolution.parsing);
@@ -467,20 +473,20 @@
         continue;
       }
       if (type is InterfaceType) {
-        if (type.element == compiler.intClass) {
+        if (type == coreTypes.intType) {
           backend.registerInstantiatedType(type, world, registry);
-        } else if (type.element == compiler.doubleClass) {
+        } else if (type == coreTypes.doubleType) {
           backend.registerInstantiatedType(type, world, registry);
-        } else if (type.element == compiler.numClass) {
+        } else if (type == coreTypes.numType) {
           backend.registerInstantiatedType(
-              compiler.coreTypes.doubleType, world, registry);
+              coreTypes.doubleType, world, registry);
           backend.registerInstantiatedType(
-              compiler.coreTypes.intType, world, registry);
-        } else if (type.element == compiler.stringClass) {
+              coreTypes.intType, world, registry);
+        } else if (type == coreTypes.stringType) {
           backend.registerInstantiatedType(type, world, registry);
-        } else if (type.element == compiler.nullClass) {
+        } else if (type == coreTypes.nullType) {
           backend.registerInstantiatedType(type, world, registry);
-        } else if (type.element == compiler.boolClass) {
+        } else if (type == coreTypes.boolType) {
           backend.registerInstantiatedType(type, world, registry);
         } else if (compiler.types.isSubtype(
                       type, backend.listImplementation.rawType)) {
@@ -511,7 +517,7 @@
   onFirstNativeClass() {
     staticUse(name) {
       backend.enqueue(
-          world, backend.findHelper(name), compiler.globalDependencies);
+          world, helpers.findHelper(name), compiler.globalDependencies);
     }
 
     staticUse('defineProperty');
@@ -545,10 +551,10 @@
     super.processNativeClass(classElement);
 
     // Js Interop interfaces do not have tags.
-    if (classElement.isJsInterop) return;
+    if (backend.isJsInterop(classElement)) return;
     // Since we map from dispatch tags to classes, a dispatch tag must be used
     // on only one native class.
-    for (String tag in nativeTagsOfClass(classElement)) {
+    for (String tag in backend.getNativeTagsOfClass(classElement)) {
       ClassElement owner = tagOwner[tag];
       if (owner != null) {
         if (owner != classElement) {
@@ -648,7 +654,7 @@
   }
 
   void addSubtypes(ClassElement cls, NativeEmitter emitter) {
-    if (!cls.isNative) return;
+    if (!backend.isNative(cls)) return;
     if (doneAddSubtypes.contains(cls)) return;
     doneAddSubtypes.add(cls);
 
@@ -668,7 +674,7 @@
     // natives classes.
     ClassElement superclass = cls.superclass;
     while (superclass != null && superclass.isMixinApplication) {
-      assert(!superclass.isNative);
+      assert(!backend.isNative(superclass));
       superclass = superclass.superclass;
     }
 
diff --git a/pkg/compiler/lib/src/native/js.dart b/pkg/compiler/lib/src/native/js.dart
index 7dc7d70..5d1d37b 100644
--- a/pkg/compiler/lib/src/native/js.dart
+++ b/pkg/compiler/lib/src/native/js.dart
@@ -4,6 +4,35 @@
 
 part of native;
 
+
+class HasCapturedPlaceholders extends js.BaseVisitor {
+
+  HasCapturedPlaceholders._();
+
+  static bool check(js.Node node) {
+    HasCapturedPlaceholders visitor = new HasCapturedPlaceholders._();
+    node.accept(visitor);
+    return visitor.found;
+  }
+
+  int enclosingFunctions = 0;
+  bool found = false;
+
+  @override
+  visitFun(js.Fun node) {
+    ++enclosingFunctions;
+    node.visitChildren(this);
+    --enclosingFunctions;
+  }
+
+  @override
+  visitInterpolatedNode(js.InterpolatedNode node) {
+    if (enclosingFunctions > 0) {
+      found = true;
+    }
+  }
+}
+
 class SideEffectsVisitor extends js.BaseVisitor {
   final SideEffects sideEffects;
   SideEffectsVisitor(this.sideEffects);
diff --git a/pkg/compiler/lib/src/native/native.dart b/pkg/compiler/lib/src/native/native.dart
index 994ff37..ad88cbe 100644
--- a/pkg/compiler/lib/src/native/native.dart
+++ b/pkg/compiler/lib/src/native/native.dart
@@ -30,6 +30,8 @@
     FunctionElementX,
     LibraryElementX;
 import '../js/js.dart' as js;
+import '../js_backend/backend_helpers.dart' show
+    BackendHelpers;
 import '../js_backend/js_backend.dart';
 import '../js_emitter/js_emitter.dart' show
     CodeEmitterTask,
@@ -56,8 +58,8 @@
 part 'scanner.dart';
 part 'ssa.dart';
 
-void maybeEnableNative(Compiler compiler,
-                       LibraryElementX library) {
+bool maybeEnableNative(Compiler compiler,
+                       LibraryElement library) {
   String libraryName = library.canonicalUri.toString();
   if (library.entryCompilationUnit.script.name.contains(
           'sdk/tests/compiler/dart2js_native')
@@ -72,21 +74,7 @@
       || libraryName == 'dart:web_gl'
       || libraryName == 'dart:web_sql'
       || compiler.allowNativeExtensions) {
-    library.canUseNative = true;
+    return true;
   }
+  return false;
 }
-
-// The tags string contains comma-separated 'words' which are either dispatch
-// tags (having JavaScript identifier syntax) and directives that begin with
-// `!`.
-List<String> nativeTagsOfClassRaw(ClassElement cls) {
-  String quotedName = cls.nativeTagInfo;
-  return quotedName.substring(1, quotedName.length - 1).split(',');
-}
-
-List<String> nativeTagsOfClass(ClassElement cls) {
-  return nativeTagsOfClassRaw(cls).where((s) => !s.startsWith('!')).toList();
-}
-
-bool nativeTagsForcedNonLeaf(ClassElement cls) =>
-    nativeTagsOfClassRaw(cls).contains('!nonleaf');
diff --git a/pkg/compiler/lib/src/native/scanner.dart b/pkg/compiler/lib/src/native/scanner.dart
index cfdb703..c18bfa8 100644
--- a/pkg/compiler/lib/src/native/scanner.dart
+++ b/pkg/compiler/lib/src/native/scanner.dart
@@ -5,8 +5,7 @@
 part of native;
 
 void checkAllowedLibrary(ElementListener listener, Token token) {
-  LibraryElement currentLibrary = listener.compilationUnitElement.library;
-  if (currentLibrary.canUseNative) return;
+  if (listener.scannerOptions.canUseNative) return;
   listener.reportError(token, MessageKind.NATIVE_NOT_SUPPORTED);
 }
 
diff --git a/pkg/compiler/lib/src/native/ssa.dart b/pkg/compiler/lib/src/native/ssa.dart
index 1dfa536..b51c64d 100644
--- a/pkg/compiler/lib/src/native/ssa.dart
+++ b/pkg/compiler/lib/src/native/ssa.dart
@@ -35,8 +35,8 @@
   // 3) foo() native "return 42";
   //      hasBody = true
   bool hasBody = false;
-  assert(element.isNative);
-  String nativeMethodName = element.fixedBackendName;
+  assert(backend.isNative(element));
+  String nativeMethodName = backend.getFixedBackendName(element);
   if (nativeBody != null) {
     LiteralString jsCode = nativeBody.asLiteralString();
     String str = jsCode.dartString.slowToString();
diff --git a/pkg/compiler/lib/src/ordered_typeset.dart b/pkg/compiler/lib/src/ordered_typeset.dart
index a5da246..cd6dd0e 100644
--- a/pkg/compiler/lib/src/ordered_typeset.dart
+++ b/pkg/compiler/lib/src/ordered_typeset.dart
@@ -157,13 +157,13 @@
 
   void add(Compiler compiler, InterfaceType type) {
     if (type.element == cls) {
-      if (type.element != compiler.objectClass) {
-        allSupertypes.addLast(compiler.objectClass.rawType);
+      if (type.element != compiler.coreClasses.objectClass) {
+        allSupertypes.addLast(compiler.coreTypes.objectType);
       }
       DiagnosticReporter reporter = compiler.reporter;
       _addAtDepth(reporter, type, maxDepth + 1);
     } else {
-      if (type.element != compiler.objectClass) {
+      if (type.element != compiler.coreClasses.objectClass) {
         allSupertypes.addLast(type);
       }
       DiagnosticReporter reporter = compiler.reporter;
diff --git a/pkg/compiler/lib/src/parser/diet_parser_task.dart b/pkg/compiler/lib/src/parser/diet_parser_task.dart
index 4ae413b..10a0a9f 100644
--- a/pkg/compiler/lib/src/parser/diet_parser_task.dart
+++ b/pkg/compiler/lib/src/parser/diet_parser_task.dart
@@ -17,7 +17,8 @@
 import 'listener.dart' show
     ParserError;
 import 'element_listener.dart' show
-    ElementListener;
+    ElementListener,
+    ScannerOptions;
 import 'partial_parser.dart' show
     PartialParser;
 
@@ -28,8 +29,11 @@
   dietParse(CompilationUnitElement compilationUnit, Token tokens) {
     measure(() {
       Function idGenerator = compiler.getNextFreeClassId;
-      ElementListener listener =
-          new ElementListener(compiler.reporter, compilationUnit, idGenerator);
+      ScannerOptions scannerOptions = new ScannerOptions(
+          canUseNative: compiler.backend.canLibraryUseNative(
+              compilationUnit.library));
+      ElementListener listener = new ElementListener(
+          scannerOptions, compiler.reporter, compilationUnit, idGenerator);
       PartialParser parser = new PartialParser(listener);
       try {
         parser.parseUnit(tokens);
diff --git a/pkg/compiler/lib/src/parser/element_listener.dart b/pkg/compiler/lib/src/parser/element_listener.dart
index 94da7df..0cdf72e 100644
--- a/pkg/compiler/lib/src/parser/element_listener.dart
+++ b/pkg/compiler/lib/src/parser/element_listener.dart
@@ -54,6 +54,16 @@
 
 typedef int IdGenerator();
 
+/// Options used for scanning.
+///
+/// Use this to conditionally support special tokens.
+class ScannerOptions {
+  /// If `true` the pseudo keyword `native` is supported.
+  final bool canUseNative;
+
+  const ScannerOptions({this.canUseNative: false});
+}
+
 /**
  * A parser event listener designed to work with [PartialParser]. It
  * builds elements representing the top-level declarations found in
@@ -63,6 +73,7 @@
 class ElementListener extends Listener {
   final IdGenerator idGenerator;
   final DiagnosticReporter reporter;
+  final ScannerOptions scannerOptions;
   final CompilationUnitElementX compilationUnitElement;
   final StringValidator stringValidator;
   Link<StringQuoting> interpolationScope;
@@ -84,6 +95,7 @@
   bool suppressParseErrors = false;
 
   ElementListener(
+      this.scannerOptions,
       DiagnosticReporter reporter,
       this.compilationUnitElement,
       this.idGenerator)
diff --git a/pkg/compiler/lib/src/parser/member_listener.dart b/pkg/compiler/lib/src/parser/member_listener.dart
index a6856b3..0399d71 100644
--- a/pkg/compiler/lib/src/parser/member_listener.dart
+++ b/pkg/compiler/lib/src/parser/member_listener.dart
@@ -19,20 +19,23 @@
     Token;
 import '../tree/tree.dart';
 
+import 'element_listener.dart' show
+    ScannerOptions;
+import 'node_listener.dart' show
+    NodeListener;
 import 'partial_elements.dart' show
     PartialConstructorElement,
     PartialFunctionElement,
     PartialMetadataAnnotation;
-import 'node_listener.dart' show
-    NodeListener;
 
 class MemberListener extends NodeListener {
   final ClassElementX enclosingClass;
 
-  MemberListener(DiagnosticReporter listener,
+  MemberListener(ScannerOptions scannerOptions,
+                 DiagnosticReporter listener,
                  ClassElementX enclosingElement)
       : this.enclosingClass = enclosingElement,
-        super(listener, enclosingElement.compilationUnit);
+        super(scannerOptions, listener, enclosingElement.compilationUnit);
 
   bool isConstructorName(Node nameNode) {
     if (enclosingClass == null ||
@@ -116,7 +119,7 @@
     }
     Element memberElement = new PartialConstructorElement(
         name, beginToken, endToken,
-        ElementKind.FUNCTION,
+        ElementKind.FACTORY_CONSTRUCTOR,
         method.modifiers,
         enclosingClass);
     addMember(memberElement);
diff --git a/pkg/compiler/lib/src/parser/node_listener.dart b/pkg/compiler/lib/src/parser/node_listener.dart
index c6bd18a..3a3e91b 100644
--- a/pkg/compiler/lib/src/parser/node_listener.dart
+++ b/pkg/compiler/lib/src/parser/node_listener.dart
@@ -21,15 +21,17 @@
     Link;
 
 import 'element_listener.dart' show
-    ElementListener;
+    ElementListener,
+    ScannerOptions;
 import 'partial_elements.dart' show
     PartialFunctionElement;
 
 class NodeListener extends ElementListener {
   NodeListener(
+      ScannerOptions scannerOptions,
       DiagnosticReporter reporter,
       CompilationUnitElement element)
-    : super(reporter, element, null);
+    : super(scannerOptions, reporter, element, null);
 
   void addLibraryTag(LibraryTag tag) {
     pushNode(tag);
diff --git a/pkg/compiler/lib/src/parser/parser_task.dart b/pkg/compiler/lib/src/parser/parser_task.dart
index 0a84c12..5ea0247 100644
--- a/pkg/compiler/lib/src/parser/parser_task.dart
+++ b/pkg/compiler/lib/src/parser/parser_task.dart
@@ -16,6 +16,8 @@
 import '../tree/tree.dart' show
     Node;
 
+import 'element_listener.dart' show
+    ScannerOptions;
 import 'listener.dart' show
     ParserError;
 import 'node_listener.dart' show
@@ -33,7 +35,8 @@
 
   Node parseCompilationUnit(Token token) {
     return measure(() {
-      NodeListener listener = new NodeListener(reporter, null);
+      NodeListener listener = new NodeListener(
+          const ScannerOptions(), reporter, null);
       Parser parser = new Parser(listener);
       try {
         parser.parseUnit(token);
diff --git a/pkg/compiler/lib/src/parser/partial_elements.dart b/pkg/compiler/lib/src/parser/partial_elements.dart
index 6e3e11c..e26d838 100644
--- a/pkg/compiler/lib/src/parser/partial_elements.dart
+++ b/pkg/compiler/lib/src/parser/partial_elements.dart
@@ -66,7 +66,7 @@
 
   bool hasParseError = false;
 
-  bool get isErroneous => hasParseError;
+  bool get isMalformed => hasParseError;
 
   DeclarationSite get declarationSite => this;
 }
@@ -237,6 +237,8 @@
   }
 }
 
+// TODO(johnniwinther): Create [PartialGenerativeConstructor] and
+// [PartialFactoryConstructor] subclasses and make this abstract.
 class PartialConstructorElement extends ConstructorElementX
     with PartialElement, PartialFunctionMixin {
   PartialConstructorElement(String name,
@@ -342,7 +344,7 @@
 
   PartialMetadataAnnotation(this.beginToken, this.tokenAfterEndToken);
 
-  bool get isErroneous => hasParseError;
+  bool get isMalformed => hasParseError;
 
   DeclarationSite get declarationSite => this;
 
@@ -421,7 +423,8 @@
     DiagnosticReporter reporter = parsing.reporter;
     reporter.withCurrentElement(this, () {
       parsing.measure(() {
-        MemberListener listener = new MemberListener(reporter, this);
+        MemberListener listener = new MemberListener(
+            parsing.getScannerOptionsFor(this), reporter, this);
         Parser parser = new ClassElementParser(listener);
         try {
           Token token = parser.parseTopLevelDeclaration(beginToken);
@@ -479,7 +482,8 @@
   return parsing.measure(() {
     return reporter.withCurrentElement(element, () {
       CompilationUnitElement unit = element.compilationUnit;
-      NodeListener listener = new NodeListener(reporter, unit);
+      NodeListener listener = new NodeListener(
+          parsing.getScannerOptionsFor(element), reporter, unit);
       listener.memberErrors = listener.memberErrors.prepend(false);
       try {
         if (partial.hasParseError) {
diff --git a/pkg/compiler/lib/src/patch_parser.dart b/pkg/compiler/lib/src/patch_parser.dart
index 1b9e8f3..4edabb3 100644
--- a/pkg/compiler/lib/src/patch_parser.dart
+++ b/pkg/compiler/lib/src/patch_parser.dart
@@ -233,7 +233,9 @@
 
   PatchMemberListener(Compiler compiler, ClassElement enclosingClass)
       : this.compiler = compiler,
-        super(compiler.reporter, enclosingClass);
+        super(compiler.parsing.getScannerOptionsFor(enclosingClass),
+              compiler.reporter,
+              enclosingClass);
 
   @override
   void addMember(Element patch) {
@@ -249,6 +251,9 @@
         // Skip this element.
       }
     } else {
+      if (Name.isPublicName(patch.name)) {
+        reporter.reportErrorMessage(patch, MessageKind.INJECTED_PUBLIC_MEMBER);
+      }
       enclosingClass.addMember(patch, reporter);
     }
   }
@@ -274,7 +279,8 @@
                        CompilationUnitElement patchElement,
                        int idGenerator())
     : this.compiler = compiler,
-      super(compiler.reporter, patchElement, idGenerator);
+      super(compiler.parsing.getScannerOptionsFor(patchElement),
+            compiler.reporter, patchElement, idGenerator);
 
   @override
   void pushElement(Element patch) {
@@ -292,6 +298,9 @@
         // Skip this element.
       }
     } else {
+      if (Name.isPublicName(patch.name)) {
+        reporter.reportErrorMessage(patch, MessageKind.INJECTED_PUBLIC_MEMBER);
+      }
       compilationUnitElement.addMember(patch, reporter);
     }
   }
@@ -445,8 +454,8 @@
     if (element.isClass) {
       String native = getNativeAnnotation(annotation);
       if (native != null) {
-        ClassElementX declaration = element.declaration;
-        declaration.setNative(native);
+        JavaScriptBackend backend = compiler.backend;
+        backend.setNativeClassTagInfo(element, native);
         return native;
       }
     }
@@ -478,7 +487,8 @@
              MetadataAnnotation annotation) {
     bool hasJsInterop = hasJsNameAnnotation(annotation);
     if (hasJsInterop) {
-      element.markAsJsInterop();
+      JavaScriptBackend backend = compiler.backend;
+      backend.markAsJsInterop(element);
     }
     // Due to semantics of apply in the baseclass we have to return null to
     // indicate that no match was found.
@@ -492,7 +502,7 @@
                 ConstantValue constant) {
     JavaScriptBackend backend = compiler.backend;
     if (constant.getType(compiler.coreTypes).element !=
-        backend.jsAnnotationClass) {
+        backend.helpers.jsAnnotationClass) {
       compiler.reporter.internalError(annotation, 'Invalid @JS(...) annotation.');
     }
   }
diff --git a/pkg/compiler/lib/src/platform_configuration.dart b/pkg/compiler/lib/src/platform_configuration.dart
new file mode 100644
index 0000000..41da852
--- /dev/null
+++ b/pkg/compiler/lib/src/platform_configuration.dart
@@ -0,0 +1,142 @@
+// Copyright (c) 2015, the Fletch 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.md file.
+
+/// Tools for loading and parsing platform-configuration files.
+library plaform_configuration;
+
+import "dart:async";
+import "package:charcode/ascii.dart";
+import "../compiler_new.dart" as api;
+
+/// Parses an Ini-like format.
+///
+/// Sections are initialized with a name enclosed in brackets.
+/// Each section contain zero or more properties of the form "name:value".
+/// Empty lines are ignored.
+/// Lines starting with # are ignored.
+/// Duplicate names are not allowed.
+/// All keys and values will be passed through [String.trim].
+///
+/// If an error is found, a [FormatException] is thrown, using [sourceUri] in
+/// the error message.
+///
+/// Example
+/// ```
+/// [a]
+/// b:c
+///
+/// [d]
+/// e:file:///tmp/bla
+/// ```
+/// Will parse to {"a": {"b":"c"}, "d": {"e": "file:///tmp/bla"}}.
+
+Map<String, Map<String, String>> parseIni(List<int> source,
+    {Set<String> allowedSections, Uri sourceUri}) {
+  int startOfLine = 0;
+  int currentLine = 0;
+
+  error(String message, int index) {
+    int column = index - startOfLine + 1;
+    throw new FormatException(
+        "$sourceUri:$currentLine:$column: $message", sourceUri, index);
+  }
+
+  Map<String, Map<String, String>> result =
+      new Map<String, Map<String, String>>();
+  Map<String, String> currentSection = null;
+
+  if (source.length == 0) return result;
+  bool endOfFile = false;
+
+  // Iterate once per $lf in file.
+  while (!endOfFile) {
+    currentLine += 1;
+    int endOfLine = source.indexOf($lf, startOfLine);
+    if (endOfLine == -1) {
+      // The dart2js provider adds a final 0 to the file.
+      endOfLine = source.last == 0 ? source.length - 1 : source.length;
+      endOfFile = true;
+    }
+    if (startOfLine != endOfLine) {
+      int firstChar = source[startOfLine];
+      if (firstChar == $hash) {
+        // Comment, do nothing.
+      } else if (firstChar == $open_bracket) {
+        // Section header
+        int endOfHeader = source.indexOf($close_bracket, startOfLine);
+        if (endOfHeader == -1) {
+          error("'[' must be matched by ']' on the same line.", startOfLine);
+        }
+        if (endOfHeader == startOfLine + 1) {
+          error("Empty header name", startOfLine + 1);
+        }
+        if (endOfHeader != endOfLine - 1) {
+          error("Section heading lines must end with ']'", endOfHeader + 1);
+        }
+        int startOfSectionName = startOfLine + 1;
+        String sectionName = new String.fromCharCodes(
+            source, startOfSectionName, endOfHeader).trim();
+        currentSection = new Map<String, String>();
+        if (result.containsKey(sectionName)) {
+          error("Duplicate section name '$sectionName'", startOfSectionName);
+        }
+        if (allowedSections != null && !allowedSections.contains(sectionName)) {
+          error("Unrecognized section name '$sectionName'", startOfSectionName);
+        }
+        result[sectionName] = currentSection;
+      } else {
+        // Property line
+        if (currentSection == null) {
+          error("Property outside section", startOfLine);
+        }
+        int separator = source.indexOf($colon, startOfLine);
+        if (separator == startOfLine) {
+          error("Empty property name", startOfLine);
+        }
+        if (separator == -1 || separator > endOfLine) {
+          error("Property line without ':'", startOfLine);
+        }
+        String propertyName =
+            new String.fromCharCodes(source, startOfLine, separator).trim();
+        if (currentSection.containsKey(propertyName)) {
+          error("Duplicate property name '$propertyName'", startOfLine);
+        }
+        String propertyValue =
+            new String.fromCharCodes(source, separator + 1, endOfLine).trim();
+        currentSection[propertyName] = propertyValue;
+      }
+    }
+    startOfLine = endOfLine + 1;
+  }
+  return result;
+}
+
+const String librariesSection = "libraries";
+const String dartSpecSection = "dart-spec";
+const String featuresSection = "features";
+
+Map<String, Uri> libraryMappings(
+    Map<String, Map<String, String>> sections, Uri baseLocation) {
+  assert(sections.containsKey(librariesSection));
+  Map<String, Uri> result = new Map<String, Uri>();
+  sections[librariesSection].forEach((String name, String value) {
+    result[name] = baseLocation.resolve(value);
+  });
+  return result;
+}
+
+final Set<String> allowedSections =
+    new Set.from([librariesSection, dartSpecSection, featuresSection]);
+
+Future<Map<String, Uri>> load(Uri location, api.CompilerInput provider) {
+  return provider.readFromUri(location).then((contents) {
+    if (contents is String) {
+      contents = contents.codeUnits;
+    }
+    return libraryMappings(
+        parseIni(contents,
+            allowedSections: allowedSections, sourceUri: location),
+        location);
+  });
+}
diff --git a/pkg/compiler/lib/src/resolution/access_semantics.dart b/pkg/compiler/lib/src/resolution/access_semantics.dart
index a41b867..baead69 100644
--- a/pkg/compiler/lib/src/resolution/access_semantics.dart
+++ b/pkg/compiler/lib/src/resolution/access_semantics.dart
@@ -180,8 +180,12 @@
   SUPER_GETTER_FIELD,
 
   /// Read from a superclass where the getter is unresolved.
+  // TODO(johnniwinther): Use [AccessKind.SUPER_GETTER] when the erroneous
+  // element is no longer needed.
   UNRESOLVED_SUPER_GETTER,
   /// Read from a superclass getter and write to an unresolved setter.
+  // TODO(johnniwinther): Use [AccessKind.SUPER_SETTER] when the erroneous
+  // element is no longer needed.
   UNRESOLVED_SUPER_SETTER,
 }
 
@@ -388,49 +392,31 @@
 /// Enum representing the different kinds of destinations which a constructor
 /// invocation might refer to.
 enum ConstructorAccessKind {
-  /// An invocation of a generative constructor.
+  /// An invocation of a (redirecting) generative constructor.
   ///
   /// For instance
   ///     class C {
   ///       C();
+  ///       C.redirect() : this();
   ///     }
-  ///     m() => new C();
+  ///     m1() => new C();
+  ///     m2() => new C.redirect();
   ///
   GENERATIVE,
 
-  /// An invocation of a redirecting generative constructor.
-  ///
-  /// For instance
-  ///     class C {
-  ///       C() : this._();
-  ///       C._();
-  ///     }
-  ///     m() => new C();
-  ///
-  REDIRECTING_GENERATIVE,
-
-  /// An invocation of a factory constructor.
+  /// An invocation of a (redirecting) factory constructor.
   ///
   /// For instance
   ///     class C {
   ///       factory C() => new C._();
+  ///       factory C.redirect() => C._;
   ///       C._();
   ///     }
-  ///     m() => new C();
+  ///     m1() => new C();
+  ///     m2() => new C.redirect();
   ///
   FACTORY,
 
-  /// An invocation of a redirecting factory constructor.
-  ///
-  /// For instance
-  ///     class C {
-  ///       factory C() = C._;
-  ///       C._();
-  ///     }
-  ///     m() => new C();
-  ///
-  REDIRECTING_FACTORY,
-
   /// An invocation of a (redirecting) generative constructor of an abstract
   /// class.
   ///
@@ -469,17 +455,6 @@
   ///
   NON_CONSTANT_CONSTRUCTOR,
 
-  /// An invocation of an ill-defined redirecting factory constructor.
-  ///
-  /// For instance
-  ///     class C {
-  ///       factory C() = Unresolved;
-  ///     }
-  ///     m() => new C();
-  ///
-  ERRONEOUS_REDIRECTING_FACTORY,
-
-
   /// An invocation of a constructor with incompatible arguments.
   ///
   /// For instance
@@ -504,35 +479,5 @@
 
   ConstructorAccessSemantics(this.kind, this.element, this.type);
 
-  /// The effect target of the access. Used to defined redirecting factory
-  /// constructor invocations.
-  ConstructorAccessSemantics get effectiveTargetSemantics => this;
-
-  /// `true` if this invocation is erroneous.
-  bool get isErroneous {
-    return kind == ConstructorAccessKind.ABSTRACT ||
-           kind == ConstructorAccessKind.UNRESOLVED_TYPE ||
-           kind == ConstructorAccessKind.UNRESOLVED_CONSTRUCTOR ||
-           kind == ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR ||
-           kind == ConstructorAccessKind.ERRONEOUS_REDIRECTING_FACTORY ||
-           kind == ConstructorAccessKind.INCOMPATIBLE;
-  }
-
   String toString() => 'ConstructorAccessSemantics($kind, $element, $type)';
 }
-
-/// Data structure used to classify the semantics of a redirecting factory
-/// constructor invocation.
-class RedirectingFactoryConstructorAccessSemantics
-    extends ConstructorAccessSemantics {
-  final ConstructorAccessSemantics effectiveTargetSemantics;
-
-  RedirectingFactoryConstructorAccessSemantics(
-      ConstructorAccessKind kind,
-      Element element,
-      DartType type,
-      this.effectiveTargetSemantics)
-      : super(kind, element, type);
-}
-
-
diff --git a/pkg/compiler/lib/src/resolution/class_hierarchy.dart b/pkg/compiler/lib/src/resolution/class_hierarchy.dart
index c156e8f..64fb6a7 100644
--- a/pkg/compiler/lib/src/resolution/class_hierarchy.dart
+++ b/pkg/compiler/lib/src/resolution/class_hierarchy.dart
@@ -5,8 +5,13 @@
 library dart2js.resolution.class_hierarchy;
 
 import '../common.dart';
+import '../common/resolution.dart' show
+    Feature;
 import '../compiler.dart' show
     Compiler;
+import '../core_types.dart' show
+    CoreClasses,
+    CoreTypes;
 import '../dart_types.dart';
 import '../elements/elements.dart';
 import '../elements/modelx.dart' show
@@ -49,7 +54,7 @@
         scope = Scope.buildEnclosingScope(element),
         super(compiler, registry);
 
-  DartType get objectType => compiler.objectClass.rawType;
+  DartType get objectType => compiler.coreTypes.objectType;
 
   void resolveTypeVariableBounds(NodeList node) {
     if (node == null) return;
@@ -190,15 +195,24 @@
 
     if (!element.hasConstructor) {
       Element superMember = element.superclass.localLookup('');
-      if (superMember == null || !superMember.isGenerativeConstructor) {
-        MessageKind kind = MessageKind.CANNOT_FIND_CONSTRUCTOR;
-        Map arguments = {'constructorName': ''};
+      if (superMember == null) {
+        MessageKind kind = MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR;
+        Map arguments = {'className': element.superclass.name};
         // TODO(ahe): Why is this a compile-time error? Or if it is an error,
         // why do we bother to registerThrowNoSuchMethod below?
         reporter.reportErrorMessage(node, kind, arguments);
         superMember = new ErroneousElementX(
             kind, arguments, '', element);
-        registry.registerThrowNoSuchMethod();
+        registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
+      } else if (!superMember.isGenerativeConstructor) {
+          MessageKind kind = MessageKind.SUPER_CALL_TO_FACTORY;
+          Map arguments = {'className': element.superclass.name};
+          // TODO(ahe): Why is this a compile-time error? Or if it is an error,
+          // why do we bother to registerThrowNoSuchMethod below?
+          reporter.reportErrorMessage(node, kind, arguments);
+          superMember = new ErroneousElementX(
+              kind, arguments, '', element);
+          registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
       } else {
         ConstructorElement superConstructor = superMember;
         superConstructor.computeType(resolution);
@@ -211,7 +225,7 @@
       }
       FunctionElement constructor =
           new SynthesizedConstructorElementX.forDefault(superMember, element);
-      if (superMember.isErroneous) {
+      if (superMember.isMalformed) {
         compiler.elementsWithCompileTimeErrors.add(constructor);
       }
       element.setDefaultConstructor(constructor, reporter);
@@ -374,7 +388,7 @@
       // [supertype] is not null if there was a cycle.
       assert(invariant(node, compiler.compilationFailed));
       supertype = mixinApplication.supertype;
-      assert(invariant(node, supertype.element == compiler.objectClass));
+      assert(invariant(node, supertype.isObject));
     } else {
       mixinApplication.supertype = supertype;
     }
@@ -582,7 +596,7 @@
       allSupertypes.add(compiler, cls.computeType(resolution));
       cls.allSupertypesAndSelf = allSupertypes.toTypeSet();
     } else {
-      assert(identical(cls, compiler.objectClass));
+      assert(cls == compiler.coreClasses.objectClass);
       cls.allSupertypesAndSelf =
           new OrderedTypeSet.singleton(cls.computeType(resolution));
     }
@@ -608,16 +622,17 @@
 
   isBlackListed(DartType type) {
     LibraryElement lib = element.library;
+    CoreTypes coreTypes = compiler.coreTypes;
     return
       !identical(lib, compiler.coreLibrary) &&
       !compiler.backend.isBackendLibrary(lib) &&
       (type.isDynamic ||
-       identical(type.element, compiler.boolClass) ||
-       identical(type.element, compiler.numClass) ||
-       identical(type.element, compiler.intClass) ||
-       identical(type.element, compiler.doubleClass) ||
-       identical(type.element, compiler.stringClass) ||
-       identical(type.element, compiler.nullClass));
+       type == coreTypes.boolType ||
+       type == coreTypes.numType ||
+       type == coreTypes.intType ||
+       type == coreTypes.doubleType ||
+       type == coreTypes.stringType ||
+       type == coreTypes.nullType);
   }
 }
 
@@ -630,6 +645,8 @@
       this.classElement = cls,
       super(compiler);
 
+  CoreClasses get coreClasses => compiler.coreClasses;
+
   void loadSupertype(ClassElement element, Node from) {
     if (!element.isResolved) {
       compiler.resolver.loadSupertypes(element, from);
@@ -647,8 +664,8 @@
 
   void visitClassNode(ClassNode node) {
     if (node.superclass == null) {
-      if (!identical(classElement, compiler.objectClass)) {
-        loadSupertype(compiler.objectClass, node);
+      if (classElement != coreClasses.objectClass) {
+        loadSupertype(coreClasses.objectClass, node);
       }
     } else {
       node.superclass.accept(this);
@@ -657,7 +674,7 @@
   }
 
   void visitEnum(Enum node) {
-    loadSupertype(compiler.objectClass, node);
+    loadSupertype(coreClasses.objectClass, node);
   }
 
   void visitMixinApplication(MixinApplication node) {
diff --git a/pkg/compiler/lib/src/resolution/class_members.dart b/pkg/compiler/lib/src/resolution/class_members.dart
index 125d4bf..a23a490 100644
--- a/pkg/compiler/lib/src/resolution/class_members.dart
+++ b/pkg/compiler/lib/src/resolution/class_members.dart
@@ -314,20 +314,21 @@
   void checkImplementsFunctionWithCall() {
     assert(!cls.isAbstract);
 
-    if (cls.asInstanceOf(compiler.functionClass) == null) return;
+    ClassElement functionClass = compiler.coreClasses.functionClass;
+    if (cls.asInstanceOf(functionClass) == null) return;
     if (cls.lookupMember(Identifiers.call) != null) return;
     // TODO(johnniwinther): Make separate methods for backend exceptions.
     // Avoid warnings on backend implementation classes for closures.
     if (compiler.backend.isBackendLibrary(cls.library)) return;
 
-    reportMessage(compiler.functionClass, MessageKind.UNIMPLEMENTED_METHOD, () {
+    reportMessage(functionClass, MessageKind.UNIMPLEMENTED_METHOD, () {
       reporter.reportWarningMessage(
           cls,
           MessageKind.UNIMPLEMENTED_METHOD_ONE,
           {'class': cls.name,
            'name': Identifiers.call,
            'method': Identifiers.call,
-           'declarer': compiler.functionClass.name});
+           'declarer': functionClass.name});
     });
   }
 
diff --git a/pkg/compiler/lib/src/resolution/constructors.dart b/pkg/compiler/lib/src/resolution/constructors.dart
index 76aa6fc..26e7b48b 100644
--- a/pkg/compiler/lib/src/resolution/constructors.dart
+++ b/pkg/compiler/lib/src/resolution/constructors.dart
@@ -5,6 +5,8 @@
 library dart2js.resolution.constructors;
 
 import '../common.dart';
+import '../common/resolution.dart' show
+    Feature;
 import '../compiler.dart' show
     Compiler;
 import '../constants/constructors.dart' show
@@ -26,8 +28,8 @@
     Link;
 import '../universe/call_structure.dart' show
     CallStructure;
-import '../universe/selector.dart' show
-    Selector;
+import '../universe/use.dart' show
+    StaticUse;
 
 import 'members.dart' show
     lookupInScope,
@@ -125,9 +127,11 @@
     }
     if (target != null) {
       registry.useElement(init, target);
-      registry.registerStaticUse(target);
       checkForDuplicateInitializers(target, init);
     }
+    if (field != null) {
+      registry.registerStaticUse(new StaticUse.fieldInit(field));
+    }
     // Resolve initializing value.
     ResolutionResult result = visitor.visitInStaticContext(
         init.arguments.head,
@@ -146,7 +150,7 @@
                                            {bool isSuperCall}) {
     if (isSuperCall) {
       // Calculate correct lookup target and constructor name.
-      if (identical(constructor.enclosingClass, visitor.compiler.objectClass)) {
+      if (constructor.enclosingClass.isObject) {
         reporter.reportErrorMessage(
             diagnosticNode, MessageKind.SUPER_INITIALIZER_IN_OBJECT);
         isValidAsConstant = false;
@@ -157,42 +161,49 @@
     return constructor.enclosingClass.thisType;
   }
 
-  ResolutionResult resolveSuperOrThisForSend(Send call) {
+  ResolutionResult resolveSuperOrThisForSend(Send node) {
     // Resolve the selector and the arguments.
     ArgumentsResult argumentsResult = visitor.inStaticContext(() {
-      visitor.resolveSelector(call, null);
-      return visitor.resolveArguments(call.argumentsNode);
+      // TODO(johnniwinther): Remove this when [SendStructure] is used directly.
+      visitor.resolveSelector(node, null);
+      return visitor.resolveArguments(node.argumentsNode);
     }, inConstantInitializer: isConst);
 
-    bool isSuperCall = Initializers.isSuperConstructorCall(call);
+    bool isSuperCall = Initializers.isSuperConstructorCall(node);
     InterfaceType targetType =
-        getSuperOrThisLookupTarget(call, isSuperCall: isSuperCall);
+        getSuperOrThisLookupTarget(node, isSuperCall: isSuperCall);
     ClassElement lookupTarget = targetType.element;
-    Selector constructorSelector =
-        visitor.getRedirectingThisOrSuperConstructorSelector(call);
-    ConstructorElement calledConstructor = findConstructor(
-        constructor.library, lookupTarget, constructorSelector.name);
+    String constructorName =
+        visitor.getRedirectingThisOrSuperConstructorName(node).text;
+    ConstructorElement foundConstructor = findConstructor(
+        constructor.library, lookupTarget, constructorName);
 
     final bool isImplicitSuperCall = false;
     final String className = lookupTarget.name;
-    verifyThatConstructorMatchesCall(calledConstructor,
-                                     argumentsResult.callStructure,
-                                     isImplicitSuperCall,
-                                     call,
-                                     className,
-                                     constructorSelector);
-    if (calledConstructor != null) {
-      registry.useElement(call, calledConstructor);
-      registry.registerStaticUse(calledConstructor);
+    CallStructure callStructure = argumentsResult.callStructure;
+    ConstructorElement calledConstructor = verifyThatConstructorMatchesCall(
+        node,
+        foundConstructor,
+        callStructure,
+        className,
+        constructorName: constructorName,
+        isThisCall: !isSuperCall,
+        isImplicitSuperCall: false);
+    // TODO(johnniwinther): Remove this when information is pulled from an
+    // [InitializerStructure].
+    registry.useElement(node, calledConstructor);
+    if (!calledConstructor.isError) {
+      registry.registerStaticUse(
+          new StaticUse.superConstructorInvoke(
+              calledConstructor, callStructure));
     }
     if (isConst) {
       if (isValidAsConstant &&
           calledConstructor.isConst &&
           argumentsResult.isValidAsConstant) {
-        CallStructure callStructure = argumentsResult.callStructure;
         List<ConstantExpression> arguments = argumentsResult.constantArguments;
         return new ConstantResult(
-            call,
+            node,
             new ConstructedConstantExpression(
                 targetType,
                 calledConstructor,
@@ -210,36 +221,33 @@
     // If the class has a super resolve the implicit super call.
     ClassElement classElement = constructor.enclosingClass;
     ClassElement superClass = classElement.superclass;
-    if (classElement != visitor.compiler.objectClass) {
+    if (!classElement.isObject) {
       assert(superClass != null);
       assert(superClass.isResolved);
 
       InterfaceType targetType =
           getSuperOrThisLookupTarget(functionNode, isSuperCall: true);
       ClassElement lookupTarget = targetType.element;
-      Selector constructorSelector = new Selector.callDefaultConstructor();
-      ConstructorElement calledConstructor = findConstructor(
-          constructor.library,
-          lookupTarget,
-          constructorSelector.name);
+      ConstructorElement calledConstructor =
+          findConstructor(constructor.library, lookupTarget, '');
 
       final String className = lookupTarget.name;
-      final bool isImplicitSuperCall = true;
-      verifyThatConstructorMatchesCall(calledConstructor,
-                                       CallStructure.NO_ARGS,
-                                       isImplicitSuperCall,
-                                       functionNode,
-                                       className,
-                                       constructorSelector);
-      if (calledConstructor != null) {
-        registry.registerImplicitSuperCall(calledConstructor);
-        registry.registerStaticUse(calledConstructor);
+      CallStructure callStructure = CallStructure.NO_ARGS;
+      ConstructorElement result = verifyThatConstructorMatchesCall(
+          functionNode,
+          calledConstructor,
+          callStructure,
+          className,
+          isImplicitSuperCall: true);
+      if (!result.isError) {
+        registry.registerStaticUse(
+            new StaticUse.constructorInvoke(calledConstructor, callStructure));
       }
 
       if (isConst && isValidAsConstant) {
         return new ConstructedConstantExpression(
             targetType,
-            calledConstructor,
+            result,
             CallStructure.NO_ARGS,
             const <ConstantExpression>[]);
       }
@@ -247,41 +255,65 @@
     return null;
   }
 
-  void verifyThatConstructorMatchesCall(
+  ConstructorElement reportAndCreateErroneousConstructor(
+      Spannable diagnosticNode,
+      String name,
+      MessageKind kind,
+      Map arguments) {
+    isValidAsConstant = false;
+    reporter.reportErrorMessage(
+        diagnosticNode, kind, arguments);
+    return new ErroneousConstructorElementX(
+        kind, arguments, name, visitor.currentClass);
+  }
+
+  /// Checks that [lookedupConstructor] is valid as a target for the super/this
+  /// constructor call using with the given [callStructure].
+  ///
+  /// If [lookedupConstructor] is valid it is returned, otherwise an error is
+  /// reported and an [ErroneousConstructorElement] is returned.
+  ConstructorElement verifyThatConstructorMatchesCall(
+      Node node,
       ConstructorElementX lookedupConstructor,
-      CallStructure call,
-      bool isImplicitSuperCall,
-      Node diagnosticNode,
+      CallStructure callStructure,
       String className,
-      Selector constructorSelector) {
-    if (lookedupConstructor == null ||
-        !lookedupConstructor.isGenerativeConstructor) {
-      String fullConstructorName = Elements.constructorNameForDiagnostics(
-              className,
-              constructorSelector.name);
+      {String constructorName: '',
+       bool isImplicitSuperCall: false,
+       bool isThisCall: false}) {
+    Element result = lookedupConstructor;
+    if (lookedupConstructor == null) {
+      String fullConstructorName =
+          Elements.constructorNameForDiagnostics(className, constructorName);
       MessageKind kind = isImplicitSuperCall
           ? MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT
           : MessageKind.CANNOT_RESOLVE_CONSTRUCTOR;
-      reporter.reportErrorMessage(
-          diagnosticNode, kind, {'constructorName': fullConstructorName});
-      isValidAsConstant = false;
+      result = reportAndCreateErroneousConstructor(
+          node, constructorName,
+          kind, {'constructorName': fullConstructorName});
+    } else if (!lookedupConstructor.isGenerativeConstructor) {
+      MessageKind kind = isThisCall
+          ? MessageKind.THIS_CALL_TO_FACTORY
+          : MessageKind.SUPER_CALL_TO_FACTORY;
+      result = reportAndCreateErroneousConstructor(
+          node, constructorName, kind, {});
     } else {
       lookedupConstructor.computeType(visitor.resolution);
-      if (!call.signatureApplies(lookedupConstructor.functionSignature)) {
+      if (!callStructure.signatureApplies(
+               lookedupConstructor.functionSignature)) {
         MessageKind kind = isImplicitSuperCall
-                           ? MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT
-                           : MessageKind.NO_MATCHING_CONSTRUCTOR;
-        reporter.reportErrorMessage(diagnosticNode, kind);
-        isValidAsConstant = false;
-      } else if (constructor.isConst
-                 && !lookedupConstructor.isConst) {
+            ? MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT
+            : MessageKind.NO_MATCHING_CONSTRUCTOR;
+        result = reportAndCreateErroneousConstructor(
+            node, constructorName, kind, {});
+      } else if (constructor.isConst && !lookedupConstructor.isConst) {
         MessageKind kind = isImplicitSuperCall
-                           ? MessageKind.CONST_CALLS_NON_CONST_FOR_IMPLICIT
-                           : MessageKind.CONST_CALLS_NON_CONST;
-        reporter.reportErrorMessage(diagnosticNode, kind);
-        isValidAsConstant = false;
+            ? MessageKind.CONST_CALLS_NON_CONST_FOR_IMPLICIT
+            : MessageKind.CONST_CALLS_NON_CONST;
+        result = reportAndCreateErroneousConstructor(
+            node, constructorName, kind, {});
       }
     }
+    return result;
   }
 
   /**
@@ -455,9 +487,9 @@
       {bool isError: false,
        bool missingConstructor: false}) {
     if (missingConstructor) {
-      registry.registerThrowNoSuchMethod();
+      registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
     } else {
-      registry.registerThrowRuntimeError();
+      registry.registerFeature(Feature.THROW_RUNTIME_ERROR);
     }
     if (isError || inConstContext) {
       reporter.reportErrorMessage(
@@ -471,10 +503,11 @@
     if (type == null) {
       type = new MalformedType(error, null);
     }
-    return new ConstructorResult(resultKind, error, type);
+    return new ConstructorResult.forError(resultKind, error, type);
   }
 
   ConstructorResult resolveConstructor(
+      PrefixElement prefix,
       InterfaceType type,
       Node diagnosticNode,
       String constructorName) {
@@ -483,37 +516,46 @@
     ConstructorElement constructor = findConstructor(
         resolver.enclosingElement.library, cls, constructorName);
     if (constructor == null) {
-      String fullConstructorName =
-          Elements.constructorNameForDiagnostics(cls.name, constructorName);
+      MessageKind kind = constructorName.isEmpty
+          ? MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR
+          : MessageKind.CANNOT_FIND_CONSTRUCTOR;
       return reportAndCreateErroneousConstructorElement(
           diagnosticNode,
           ConstructorResultKind.UNRESOLVED_CONSTRUCTOR, type,
-          cls, constructorName,
-          MessageKind.CANNOT_FIND_CONSTRUCTOR,
-          {'constructorName': fullConstructorName},
+          cls, constructorName, kind,
+          {'className': cls.name, 'constructorName': constructorName},
           missingConstructor: true);
     } else if (inConstContext && !constructor.isConst) {
       reporter.reportErrorMessage(
           diagnosticNode, MessageKind.CONSTRUCTOR_IS_NOT_CONST);
       return new ConstructorResult(
-          ConstructorResultKind.NON_CONSTANT, constructor, type);
+          ConstructorResultKind.NON_CONSTANT, prefix, constructor, type);
     } else {
+      if (cls.isEnumClass && resolver.currentClass != cls) {
+        return reportAndCreateErroneousConstructorElement(
+            diagnosticNode,
+            ConstructorResultKind.INVALID_TYPE, type,
+            cls, constructorName,
+            MessageKind.CANNOT_INSTANTIATE_ENUM,
+            {'enumName': cls.name},
+            isError: true);
+      }
       if (constructor.isGenerativeConstructor) {
         if (cls.isAbstract) {
           reporter.reportWarningMessage(
               diagnosticNode, MessageKind.ABSTRACT_CLASS_INSTANTIATION);
-          registry.registerAbstractClassInstantiation();
+          registry.registerFeature(Feature.ABSTRACT_CLASS_INSTANTIATION);
           return new ConstructorResult(
-              ConstructorResultKind.ABSTRACT, constructor, type);
+              ConstructorResultKind.ABSTRACT, prefix, constructor, type);
         } else {
           return new ConstructorResult(
-              ConstructorResultKind.GENERATIVE, constructor, type);
+              ConstructorResultKind.GENERATIVE, prefix, constructor, type);
         }
       } else {
         assert(invariant(diagnosticNode, constructor.isFactoryConstructor,
             message: "Unexpected constructor $constructor."));
         return new ConstructorResult(
-            ConstructorResultKind.FACTORY, constructor, type);
+            ConstructorResultKind.FACTORY, prefix, constructor, type);
       }
     }
   }
@@ -544,10 +586,11 @@
     // class.
     if (result.type != null) {
       // The unnamed constructor may not exist, so [e] may become unresolved.
-      result = resolveConstructor(result.type, diagnosticNode, '');
+      result = resolveConstructor(
+          result.prefix, result.type, diagnosticNode, '');
     } else {
       Element element = result.element;
-      if (element.isErroneous) {
+      if (element.isMalformed) {
         result = constructorResultForErroneous(diagnosticNode, element);
       } else {
         result = reportAndCreateErroneousConstructorElement(
@@ -568,8 +611,18 @@
         node,
         malformedIsError: inConstContext,
         deferredIsMalformed: false);
-    registry.registerRequiredType(type, resolver.enclosingElement);
-    return constructorResultForType(node, type);
+    Send send = node.typeName.asSend();
+    PrefixElement prefix;
+    if (send != null) {
+      // The type name is of the form [: prefix . identifier :].
+      String name = send.receiver.asIdentifier().source;
+      Element element = resolver.reportLookupErrorIfAny(
+          lookupInScope(reporter, send, resolver.scope, name), node, name);
+      if (element != null && element.isPrefix) {
+        prefix = element;
+      }
+    }
+    return constructorResultForType(node, type, prefix: prefix);
   }
 
   ConstructorResult visitSend(Send node) {
@@ -577,7 +630,7 @@
     assert(invariant(node.receiver, receiver != null,
         message: 'No result returned for $node.receiver.'));
     if (receiver.kind != null) {
-      assert(invariant(node, receiver.element.isErroneous,
+      assert(invariant(node, receiver.element.isMalformed,
           message: "Unexpected prefix result: $receiver."));
       // We have already found an error.
       return receiver;
@@ -590,7 +643,8 @@
 
     if (receiver.type != null) {
       if (receiver.type.isInterfaceType) {
-        return resolveConstructor(receiver.type, name, name.source);
+        return resolveConstructor(
+            receiver.prefix, receiver.type, name, name.source);
       } else {
         // TODO(johnniwinther): Update the message for the different types.
         return reportAndCreateErroneousConstructorElement(
@@ -602,7 +656,8 @@
     } else if (receiver.element.isPrefix) {
       PrefixElement prefix = receiver.element;
       Element member = prefix.lookupLocalMember(name.source);
-      return constructorResultForElement(node, name.source, member);
+      return constructorResultForElement(
+          node, name.source, member, prefix: prefix);
     } else {
       return reporter.internalError(
           node.receiver, 'unexpected receiver $receiver');
@@ -626,7 +681,8 @@
   }
 
   ConstructorResult constructorResultForElement(
-      Node node, String name, Element element) {
+      Node node, String name, Element element,
+      {PrefixElement prefix}) {
     element = Elements.unwrap(element, reporter, node);
     if (element == null) {
       return reportAndCreateErroneousConstructorElement(
@@ -635,14 +691,14 @@
           resolver.enclosingElement, name,
           MessageKind.CANNOT_RESOLVE,
           {'name': name});
-    } else if (element.isErroneous) {
+    } else if (element.isMalformed) {
       return constructorResultForErroneous(node, element);
     } else if (element.isClass) {
       ClassElement cls = element;
       cls.computeType(resolution);
-      return constructorResultForType(node, cls.rawType);
+      return constructorResultForType(node, cls.rawType, prefix: prefix);
     } else if (element.isPrefix) {
-      return new ConstructorResult.forElement(element);
+      return new ConstructorResult.forPrefix(element);
     } else if (element.isTypedef) {
       TypedefElement typdef = element;
       typdef.ensureResolved(resolution);
@@ -666,9 +722,9 @@
       error = new ErroneousConstructorElementX(
           MessageKind.NOT_A_TYPE, {'node': node},
           error.name, error);
-      registry.registerThrowRuntimeError();
+      registry.registerFeature(Feature.THROW_RUNTIME_ERROR);
     }
-    return new ConstructorResult(
+    return new ConstructorResult.forError(
         ConstructorResultKind.INVALID_TYPE,
         error,
         new MalformedType(error, null));
@@ -676,13 +732,14 @@
 
   ConstructorResult constructorResultForType(
       Node node,
-      DartType type) {
+      DartType type,
+      {PrefixElement prefix}) {
     String name = type.name;
     if (type.isMalformed) {
-      return new ConstructorResult(
+      return new ConstructorResult.forError(
           ConstructorResultKind.INVALID_TYPE, type.element, type);
     } else if (type.isInterfaceType) {
-      return new ConstructorResult.forType(type);
+      return new ConstructorResult.forType(prefix, type);
     } else if (type.isTypedef) {
       return reportAndCreateErroneousConstructorElement(
           node,
@@ -702,40 +759,88 @@
 
 }
 
+/// The kind of constructor found by the [ConstructorResolver].
 enum ConstructorResultKind {
+  /// A generative or redirecting generative constructor.
   GENERATIVE,
+  /// A factory or redirecting factory constructor.
   FACTORY,
+  /// A generative or redirecting generative constructor on an abstract class.
   ABSTRACT,
+  /// No constructor was found because the type was invalid, for instance
+  /// unresolved, an enum class, a type variable, a typedef or a non-type.
   INVALID_TYPE,
+  /// No constructor of the sought name was found on the class.
   UNRESOLVED_CONSTRUCTOR,
+  /// A non-constant constructor was found for a const constructor invocation.
   NON_CONSTANT,
 }
 
+/// The (partial) result of the resolution of a new expression used in
+/// [ConstructorResolver].
 class ConstructorResult {
+  /// The prefix used to access the constructor. For instance `prefix` in `new
+  /// prefix.Class.constructorName()`.
+  final PrefixElement prefix;
+
+  /// The kind of the found constructor.
   final ConstructorResultKind kind;
+
+  /// The currently found element. Since [ConstructorResult] is used for partial
+  /// results, this might be a [PrefixElement], a [ClassElement], a
+  /// [ConstructorElement] or in the negative cases an [ErroneousElement].
   final Element element;
+
+  /// The type of the new expression. For instance `Foo<String>` in
+  /// `new prefix.Foo<String>.constructorName()`.
   final DartType type;
 
-  ConstructorResult(this.kind, this.element, this.type);
+  /// Creates a fully resolved constructor access where [element] is resolved
+  /// to a constructor and [type] to an interface type.
+  ConstructorResult(this.kind,
+                    this.prefix,
+                    ConstructorElement this.element,
+                    InterfaceType this.type);
 
-  ConstructorResult.forElement(this.element)
-      : kind = null,
+  /// Creates a fully resolved constructor access where [element] is an
+  /// [ErroneousElement].
+  // TODO(johnniwinther): Do we still need the prefix for cases like
+  // `new deferred.Class.unresolvedConstructor()` ?
+  ConstructorResult.forError(
+      this.kind, ErroneousElement this.element, this.type)
+      : prefix = null;
+
+  /// Creates a constructor access that is partially resolved to a prefix. For
+  /// instance `prefix` of `new prefix.Class()`.
+  ConstructorResult.forPrefix(this.element)
+      : prefix = null,
+        kind = null,
         type = null;
 
-  ConstructorResult.forType(this.type)
+  /// Creates a constructor access that is partially resolved to a type. For
+  /// instance `Foo<String>` of `new Foo<String>.constructorName()`.
+  ConstructorResult.forType(this.prefix, this.type)
       : kind = null,
         element = null;
 
+  bool get isDeferred => prefix != null && prefix.isDeferred;
+
   String toString() {
     StringBuffer sb = new StringBuffer();
     sb.write('ConstructorResult(');
     if (kind != null) {
       sb.write('kind=$kind,');
+      if (prefix != null) {
+        sb.write('prefix=$prefix,');
+      }
       sb.write('element=$element,');
       sb.write('type=$type');
     } else if (element != null) {
       sb.write('element=$element');
     } else {
+      if (prefix != null) {
+        sb.write('prefix=$prefix,');
+      }
       sb.write('type=$type');
     }
     sb.write(')');
diff --git a/pkg/compiler/lib/src/resolution/member_impl.dart b/pkg/compiler/lib/src/resolution/member_impl.dart
index 072ddd1..9a2d7b0 100644
--- a/pkg/compiler/lib/src/resolution/member_impl.dart
+++ b/pkg/compiler/lib/src/resolution/member_impl.dart
@@ -227,7 +227,7 @@
 
   bool get isMethod => member.isMethod;
 
-  bool get isErroneous => false;
+  bool get isMalformed => false;
 
   String toString() => '${type.getStringAsDeclared('$name')} synthesized '
                        'from ${inheritedMembers}';
@@ -248,7 +248,7 @@
 
   bool get isMethod => false;
 
-  bool get isErroneous => true;
+  bool get isMalformed => true;
 
   String toString() => "erroneous member '$name' synthesized "
                        "from ${inheritedMembers}";
diff --git a/pkg/compiler/lib/src/resolution/members.dart b/pkg/compiler/lib/src/resolution/members.dart
index 90f5365..6d41d9c 100644
--- a/pkg/compiler/lib/src/resolution/members.dart
+++ b/pkg/compiler/lib/src/resolution/members.dart
@@ -7,6 +7,8 @@
 import '../common.dart';
 import '../common/names.dart' show
     Selectors;
+import '../common/resolution.dart' show
+    Feature;
 import '../compiler.dart' show
     Compiler;
 import '../constants/constructors.dart' show
@@ -37,8 +39,10 @@
     CallStructure;
 import '../universe/selector.dart' show
     Selector;
-import '../universe/universe.dart' show
-    UniverseSelector;
+import '../universe/use.dart' show
+    DynamicUse,
+    StaticUse,
+    TypeUse;
 
 import 'access_semantics.dart';
 import 'class_members.dart' show MembersCreator;
@@ -47,7 +51,8 @@
 
 import 'constructors.dart' show
     ConstructorResolver,
-    ConstructorResult;
+    ConstructorResult,
+    ConstructorResultKind;
 import 'label_scope.dart' show
     StatementScope;
 import 'registry.dart' show
@@ -184,6 +189,8 @@
           ? ConstantState.CONSTANT : ConstantState.NON_CONSTANT,
       super(compiler, registry);
 
+  CoreClasses get coreClasses => compiler.coreClasses;
+
   CoreTypes get coreTypes => compiler.coreTypes;
 
   AsyncMarker get currentAsyncMarker {
@@ -228,14 +235,6 @@
     return element;
   }
 
-  doInCheckContext(action()) {
-    bool wasInCheckContext = inCheckContext;
-    inCheckContext = true;
-    var result = action();
-    inCheckContext = wasInCheckContext;
-    return result;
-  }
-
   doInPromotionScope(Node node, action()) {
     promotionScope = promotionScope.prepend(node);
     var result = action();
@@ -339,7 +338,7 @@
     } else {
       kind = MessageKind.CANNOT_RESOLVE;
     }
-    registry.registerThrowNoSuchMethod();
+    registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
     return reportAndCreateErroneousElement(
         node, name, kind, arguments, isError: inInitializer);
   }
@@ -367,7 +366,7 @@
       if (Elements.isUnresolved(element) && name == 'dynamic') {
         // TODO(johnniwinther): Remove this hack when we can return more complex
         // objects than [Element] from this method.
-        element = compiler.typeClass;
+        element = coreClasses.typeClass;
         // Set the type to be `dynamic` to mark that this is a type literal.
         registry.setType(node, const DynamicType());
       }
@@ -376,8 +375,8 @@
         if (!inInstanceContext) {
           element = reportCannotResolve(node, name);
         }
-      } else if (element.isErroneous) {
-        // Use the erroneous element.
+      } else if (element.isMalformed) {
+        // Use the malformed element.
       } else {
         if ((element.kind.category & allowedCategory) == 0) {
           element = reportAndCreateErroneousElement(
@@ -406,20 +405,19 @@
   TypeResult visitTypeAnnotation(TypeAnnotation node) {
     DartType type = resolveTypeAnnotation(node);
     if (inCheckContext) {
-      registry.registerCheckedModeCheck(type);
+      registry.registerTypeUse(new TypeUse.checkedModeCheck(type));
     }
     return new TypeResult(type);
   }
 
   bool isNamedConstructor(Send node) => node.receiver != null;
 
-  Selector getRedirectingThisOrSuperConstructorSelector(Send node) {
+  Name getRedirectingThisOrSuperConstructorName(Send node) {
     if (isNamedConstructor(node)) {
       String constructorName = node.selector.asIdentifier().source;
-      return new Selector.callConstructor(
-          new Name(constructorName, enclosingElement.library));
+      return new Name(constructorName, enclosingElement.library);
     } else {
-      return new Selector.callDefaultConstructor();
+      return const PublicName('');
     }
   }
 
@@ -432,10 +430,10 @@
     Link<Node> initializers = node.initializers.nodes;
     if (!initializers.isEmpty &&
         Initializers.isConstructorRedirect(initializers.head)) {
-      Selector selector =
-          getRedirectingThisOrSuperConstructorSelector(initializers.head);
+      Name name =
+          getRedirectingThisOrSuperConstructorName(initializers.head);
       final ClassElement classElement = constructor.enclosingClass;
-      return classElement.lookupConstructor(selector.name);
+      return classElement.lookupConstructor(name.text);
     }
     return null;
   }
@@ -492,7 +490,7 @@
     });
     if (inCheckContext) {
       functionParameters.forEachParameter((ParameterElement element) {
-        registry.registerCheckedModeCheck(element.type);
+        registry.registerTypeUse(new TypeUse.checkedModeCheck(element.type));
       });
     }
   }
@@ -506,7 +504,8 @@
     }
     // TODO(sra): We could completely ignore the assert in production mode if we
     // didn't need it to be resolved for type checking.
-    registry.registerAssert(node.hasMessage);
+    registry.registerFeature(
+        node.hasMessage ? Feature.ASSERT_WITH_MESSAGE : Feature.ASSERT);
     visit(node.condition);
     visit(node.message);
     return const NoneResult();
@@ -638,8 +637,7 @@
     scope = oldScope;
     enclosingElement = previousEnclosingElement;
 
-    registry.registerClosure(function);
-    registry.registerInstantiatedClass(compiler.functionClass);
+    registry.registerStaticUse(new StaticUse.closure(function));
     return const NoneResult();
   }
 
@@ -781,7 +779,7 @@
           node, 'super',
           MessageKind.NO_SUPER_IN_STATIC, {},
           isError: true);
-      registry.registerCompileTimeError(error);
+      registry.registerFeature(Feature.COMPILE_TIME_ERROR);
       return new StaticAccess.invalid(error);
     }
     if (node.isConditional) {
@@ -790,7 +788,7 @@
           node, 'super',
           MessageKind.INVALID_USE_OF_SUPER, {},
           isError: true);
-      registry.registerCompileTimeError(error);
+      registry.registerFeature(Feature.COMPILE_TIME_ERROR);
       return new StaticAccess.invalid(error);
     }
     if (currentClass.supertype == null) {
@@ -801,7 +799,7 @@
           MessageKind.GENERIC,
           {'text': "Object has no superclass"},
           isError: true);
-      registry.registerCompileTimeError(error);
+      registry.registerFeature(Feature.COMPILE_TIME_ERROR);
       return new StaticAccess.invalid(error);
     }
     registry.registerSuperUse(node);
@@ -816,7 +814,7 @@
           node, 'this',
           MessageKind.NO_THIS_AVAILABLE, const {},
           isError: true);
-      registry.registerCompileTimeError(error);
+      registry.registerFeature(Feature.COMPILE_TIME_ERROR);
       return new StaticAccess.invalid(error);
     }
     return null;
@@ -824,7 +822,7 @@
 
   /// Compute the [AccessSemantics] corresponding to a super access of [target].
   AccessSemantics computeSuperAccessSemantics(Spannable node, Element target) {
-    if (target.isErroneous) {
+    if (target.isMalformed) {
       return new StaticAccess.unresolvedSuper(target);
     } else if (target.isGetter) {
       return new StaticAccess.superGetter(target);
@@ -850,8 +848,8 @@
       Element getter,
       Element setter,
       {bool isIndex: false}) {
-    if (getter.isErroneous) {
-      if (setter.isErroneous) {
+    if (getter.isMalformed) {
+      if (setter.isMalformed) {
         return new StaticAccess.unresolvedSuper(getter);
       } else if (setter.isFunction) {
         assert(invariant(node, setter.name == '[]=',
@@ -865,7 +863,7 @@
             CompoundAccessKind.UNRESOLVED_SUPER_GETTER, getter, setter);
       }
     } else if (getter.isField) {
-      if (setter.isErroneous) {
+      if (setter.isMalformed) {
         assert(invariant(node, getter.isFinal,
             message: "Unexpected super setter '$setter' for getter '$getter."));
         return new StaticAccess.superFinalField(getter);
@@ -886,7 +884,7 @@
             CompoundAccessKind.SUPER_FIELD_SETTER, getter, setter);
       }
     } else if (getter.isGetter) {
-      if (setter.isErroneous) {
+      if (setter.isMalformed) {
         return new CompoundAccessSemantics(
             CompoundAccessKind.UNRESOLVED_SUPER_SETTER, getter, setter);
       } else if (setter.isField) {
@@ -901,7 +899,7 @@
     } else {
       assert(invariant(node, getter.isFunction,
           message: "Unexpected super getter '$getter'."));
-      if (setter.isErroneous) {
+      if (setter.isMalformed) {
         if (isIndex) {
           return new CompoundAccessSemantics(
               CompoundAccessKind.UNRESOLVED_SUPER_SETTER, getter, setter);
@@ -953,10 +951,8 @@
       Element target) {
 
     target = target.declaration;
-    if (target.isErroneous) {
+    if (target.isMalformed) {
       // This handles elements with parser errors.
-      // TODO(johnniwinther): Elements with parse error should not set
-      // [isErroneous] to `true`.
       return new StaticAccess.unresolved(target);
     }
     if (target.isStatic) {
@@ -1042,8 +1038,8 @@
       }
       // We still need to register the invocation, because we might
       // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn].
-      registry.registerDynamicInvocation(new UniverseSelector(selector, null));
-      registry.registerSuperNoSuchMethod();
+      registry.registerDynamicUse(new DynamicUse(selector, null));
+      registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD);
     }
     return computeSuperAccessSemantics(node, target);
   }
@@ -1109,17 +1105,17 @@
     if (getterError) {
       // We still need to register the invocation, because we might
       // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn].
-      registry.registerDynamicInvocation(
-          new UniverseSelector(getterSelector, null));
+      registry.registerDynamicUse(
+          new DynamicUse(getterSelector, null));
     }
     if (setterError) {
       // We still need to register the invocation, because we might
       // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn].
-      registry.registerDynamicInvocation(
-          new UniverseSelector(setterSelector, null));
+      registry.registerDynamicUse(
+          new DynamicUse(setterSelector, null));
     }
     if (getterError || setterError) {
-      registry.registerSuperNoSuchMethod();
+      registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD);
     }
     return computeCompoundSuperAccessSemantics(
         node, getter, setter, isIndex: isIndex);
@@ -1170,7 +1166,7 @@
       type = resolveTypeAnnotation(typeNode);
       sendStructure = new IsStructure(type);
     }
-    registry.registerIsCheck(type);
+    registry.registerTypeUse(new TypeUse.isCheck(type));
     registry.registerSendStructure(node, sendStructure);
     return const NoneResult();
   }
@@ -1182,7 +1178,7 @@
 
     Node typeNode = node.arguments.head;
     DartType type = resolveTypeAnnotation(typeNode);
-    registry.registerAsCast(type);
+    registry.registerTypeUse(new TypeUse.asCast(type));
     registry.registerSendStructure(node, new AsStructure(type));
     return const NoneResult();
   }
@@ -1219,7 +1215,10 @@
         // TODO(johnniwinther): Add information to [AccessSemantics] about
         // whether it is erroneous.
         if (semantics.kind == AccessKind.SUPER_METHOD) {
-          registry.registerStaticUse(semantics.element.declaration);
+          registry.registerStaticUse(
+              new StaticUse.superInvoke(
+                  semantics.element.declaration,
+                  selector.callStructure));
         }
         // TODO(23998): Remove this when all information goes through
         // the [SendStructure].
@@ -1228,7 +1227,7 @@
     } else {
       ResolutionResult expressionResult = visitExpression(expression);
       semantics = const DynamicAccess.expression();
-      registry.registerDynamicInvocation(new UniverseSelector(selector, null));
+      registry.registerDynamicUse(new DynamicUse(selector, null));
 
       if (expressionResult.isConstant) {
         bool isValidConstant;
@@ -1391,7 +1390,10 @@
         // TODO(johnniwinther): Add information to [AccessSemantics] about
         // whether it is erroneous.
         if (semantics.kind == AccessKind.SUPER_METHOD) {
-          registry.registerStaticUse(semantics.element.declaration);
+          registry.registerStaticUse(
+              new StaticUse.superInvoke(
+                  semantics.element.declaration,
+                  selector.callStructure));
         }
         // TODO(23998): Remove this when all information goes through
         // the [SendStructure].
@@ -1401,7 +1403,7 @@
     } else {
       ResolutionResult leftResult = visitExpression(left);
       ResolutionResult rightResult = visitExpression(right);
-      registry.registerDynamicInvocation(new UniverseSelector(selector, null));
+      registry.registerDynamicUse(new DynamicUse(selector, null));
       semantics = const DynamicAccess.expression();
 
       if (leftResult.isConstant && rightResult.isConstant) {
@@ -1536,7 +1538,7 @@
     // TODO(23998): Remove this when all information goes through the
     // [SendStructure].
     registry.setSelector(node, selector);
-    registry.registerDynamicInvocation(new UniverseSelector(selector, null));
+    registry.registerDynamicUse(new DynamicUse(selector, null));
     registry.registerSendStructure(node,
         new InvokeStructure(const DynamicAccess.expression(), selector));
     return const NoneResult();
@@ -1569,8 +1571,8 @@
       AccessSemantics accessSemantics = checkThisAccess(node);
       if (accessSemantics == null) {
         accessSemantics = const DynamicAccess.thisAccess();
-        registry.registerDynamicInvocation(
-            new UniverseSelector(selector, null));
+        registry.registerDynamicUse(
+            new DynamicUse(selector, null));
       }
       registry.registerSendStructure(node,
           new InvokeStructure(accessSemantics, selector));
@@ -1610,22 +1612,24 @@
           superMethod.computeType(resolution);
           if (!callStructure.signatureApplies(
                   superMethod.functionSignature)) {
-            registry.registerThrowNoSuchMethod();
-            registry.registerDynamicInvocation(
-                new UniverseSelector(selector, null));
-            registry.registerSuperNoSuchMethod();
+            registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
+            registry.registerDynamicUse(
+                new DynamicUse(selector, null));
+            registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD);
             isIncompatibleInvoke = true;
           } else {
-            registry.registerStaticInvocation(semantics.element);
+            registry.registerStaticUse(
+                new StaticUse.superInvoke(semantics.element, callStructure));
           }
           break;
         case AccessKind.SUPER_FIELD:
         case AccessKind.SUPER_FINAL_FIELD:
         case AccessKind.SUPER_GETTER:
-          registry.registerStaticUse(semantics.element);
+          registry.registerStaticUse(
+              new StaticUse.superGet(semantics.element));
           selector = callStructure.callSelector;
-          registry.registerDynamicInvocation(
-              new UniverseSelector(selector, null));
+          registry.registerDynamicUse(
+              new DynamicUse(selector, null));
           break;
         case AccessKind.SUPER_SETTER:
         case AccessKind.UNRESOLVED_SUPER:
@@ -1648,12 +1652,14 @@
         case AccessKind.SUPER_METHOD:
           // TODO(johnniwinther): Method this should be registered as a
           // closurization.
-          registry.registerStaticUse(semantics.element);
+          registry.registerStaticUse(
+              new StaticUse.superTearOff(semantics.element));
           break;
         case AccessKind.SUPER_FIELD:
         case AccessKind.SUPER_FINAL_FIELD:
         case AccessKind.SUPER_GETTER:
-          registry.registerStaticUse(semantics.element);
+          registry.registerStaticUse(
+              new StaticUse.superGet(semantics.element));
           break;
         case AccessKind.SUPER_SETTER:
         case AccessKind.UNRESOLVED_SUPER:
@@ -1743,7 +1749,7 @@
       Send node, Name name, ClassElement receiverClass) {
     // TODO(johnniwinther): Share code with [handleStaticInstanceMemberAccess]
     // and [handlePrivateStaticMemberAccess].
-    registry.registerThrowNoSuchMethod();
+    registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
     // TODO(johnniwinther): Produce a different error if [name] is resolves to
     // a constructor.
 
@@ -1769,7 +1775,7 @@
       SendSet node, Name name, ClassElement receiverClass) {
     // TODO(johnniwinther): Share code with [handleStaticInstanceMemberUpdate]
     // and [handlePrivateStaticMemberUpdate].
-    registry.registerThrowNoSuchMethod();
+    registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
     // TODO(johnniwinther): Produce a different error if [name] is resolves to
     // a constructor.
 
@@ -1791,7 +1797,7 @@
   ResolutionResult handleStaticInstanceMemberAccess(
       Send node, Name name, ClassElement receiverClass, Element member) {
 
-    registry.registerThrowNoSuchMethod();
+    registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
     // TODO(johnniwinther): With the simplified [TreeElements] invariant,
     // try to resolve injected elements if [currentClass] is in the patch
     // library of [receiverClass].
@@ -1814,7 +1820,7 @@
   ResolutionResult handleStaticInstanceMemberUpdate(
       SendSet node, Name name, ClassElement receiverClass, Element member) {
 
-    registry.registerThrowNoSuchMethod();
+    registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
     // TODO(johnniwinther): With the simplified [TreeElements] invariant,
     // try to resolve injected elements if [currentClass] is in the patch
     // library of [receiverClass].
@@ -1834,7 +1840,7 @@
   /// but `a` is not defined in the current library.
   ResolutionResult handlePrivateStaticMemberAccess(
       Send node, Name name, ClassElement receiverClass, Element member) {
-    registry.registerThrowNoSuchMethod();
+    registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
     ErroneousElement error = reportAndCreateErroneousElement(
         node, name.text, MessageKind.PRIVATE_ACCESS,
         {'libraryName': member.library.libraryOrScriptName,
@@ -1850,7 +1856,7 @@
   /// `a` but `a` is not defined in the current library.
   ResolutionResult handlePrivateStaticMemberUpdate(
       SendSet node, Name name, ClassElement receiverClass, Element member) {
-    registry.registerThrowNoSuchMethod();
+    registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
     ErroneousElement error = reportAndCreateErroneousElement(
         node, name.text, MessageKind.PRIVATE_ACCESS,
         {'libraryName': member.library.libraryOrScriptName,
@@ -1937,7 +1943,7 @@
           MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
           {'typeVariableName': name},
           isError: true);
-      registry.registerCompileTimeError(error);
+      registry.registerFeature(Feature.COMPILE_TIME_ERROR);
       semantics = new StaticAccess.invalid(error);
       // TODO(johnniwinther): Clean up registration of elements and selectors
       // for this case.
@@ -1979,7 +1985,7 @@
           MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
           {'typeVariableName': name},
           isError: true);
-      registry.registerCompileTimeError(error);
+      registry.registerFeature(Feature.COMPILE_TIME_ERROR);
       semantics = new StaticAccess.invalid(error);
     } else {
       ErroneousElement error;
@@ -2001,7 +2007,7 @@
       registry.useElement(node, error);
       // TODO(johnniwinther): Register only on read?
       registry.registerTypeLiteral(node, element.type);
-      registry.registerThrowNoSuchMethod();
+      registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
       semantics = new StaticAccess.typeParameterTypeLiteral(element);
     }
     return handleUpdate(node, name, semantics);
@@ -2080,7 +2086,7 @@
     // the [SendStructure].
     registry.useElement(node, error);
     registry.registerTypeLiteral(node, type);
-    registry.registerThrowNoSuchMethod();
+    registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
 
     return handleUpdate(node, name, semantics);
   }
@@ -2121,7 +2127,8 @@
         node.isCall ? coreTypes.typeType : type);
     AccessSemantics semantics = new ConstantAccess.dynamicTypeLiteral(constant);
     return handleConstantTypeLiteralAccess(
-        node, const PublicName('dynamic'), compiler.typeClass, type, semantics);
+        node, const PublicName('dynamic'),
+        coreClasses.typeClass, type, semantics);
   }
 
   /// Handle update to a type literal of the type 'dynamic'. Like `dynamic++` or
@@ -2132,7 +2139,8 @@
         new TypeConstantExpression(const DynamicType());
     AccessSemantics semantics = new ConstantAccess.dynamicTypeLiteral(constant);
     return handleConstantTypeLiteralUpdate(
-        node, const PublicName('dynamic'), compiler.typeClass, type, semantics);
+        node, const PublicName('dynamic'),
+        coreClasses.typeClass, type, semantics);
   }
 
   /// Handle access to a type literal of a class. Like `C` or
@@ -2207,7 +2215,7 @@
     ResolutionResult result;
     Element member = prefix.lookupLocalMember(name.text);
     if (member == null) {
-      registry.registerThrowNoSuchMethod();
+      registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
       Element error = reportAndCreateErroneousElement(
           node, name.text, MessageKind.NO_SUCH_LIBRARY_MEMBER,
           {'libraryName': prefix.name, 'memberName': name});
@@ -2235,7 +2243,7 @@
     ResolutionResult result;
     Element member = prefix.lookupLocalMember(name.text);
     if (member == null) {
-      registry.registerThrowNoSuchMethod();
+      registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
       Element error = reportAndCreateErroneousElement(
           node, name.text, MessageKind.NO_SUCH_LIBRARY_MEMBER,
           {'libraryName': prefix.name, 'memberName': name});
@@ -2269,7 +2277,7 @@
           MessageKind.PREFIX_AS_EXPRESSION,
           {'prefix': name},
           isError: true);
-      registry.registerCompileTimeError(error);
+      registry.registerFeature(Feature.COMPILE_TIME_ERROR);
       return handleErroneousAccess(
           node, name, new StaticAccess.invalid(error));
     }
@@ -2333,14 +2341,14 @@
       CallStructure callStructure =
           resolveArguments(node.argumentsNode).callStructure;
       selector = new Selector.call(name, callStructure);
-      registry.registerDynamicInvocation(
-          new UniverseSelector(selector, null));
+      registry.registerDynamicUse(
+          new DynamicUse(selector, null));
       sendStructure = new InvokeStructure(semantics, selector);
     } else {
       assert(invariant(node, node.isPropertyAccess));
       selector = new Selector.getter(name);
-      registry.registerDynamicGetter(
-          new UniverseSelector(selector, null));
+      registry.registerDynamicUse(
+          new DynamicUse(selector, null));
       sendStructure = new GetStructure(semantics);
     }
     registry.registerSendStructure(node, sendStructure);
@@ -2355,11 +2363,11 @@
       SendSet node, Name name, Element element, AccessSemantics semantics) {
     Selector getterSelector = new Selector.getter(name);
     Selector setterSelector = new Selector.setter(name.setter);
-    registry.registerDynamicSetter(
-        new UniverseSelector(setterSelector, null));
+    registry.registerDynamicUse(
+        new DynamicUse(setterSelector, null));
     if (node.isComplex) {
-      registry.registerDynamicGetter(
-          new UniverseSelector(getterSelector, null));
+      registry.registerDynamicUse(
+          new DynamicUse(getterSelector, null));
     }
 
     // TODO(23998): Remove these when elements are only accessed through the
@@ -2388,7 +2396,7 @@
         name.text,
         MessageKind.THIS_PROPERTY, {},
         isError: true);
-    registry.registerCompileTimeError(error);
+    registry.registerFeature(Feature.COMPILE_TIME_ERROR);
     AccessSemantics accessSemantics = new StaticAccess.invalid(error);
     return handleErroneousAccess(node, name, accessSemantics);
   }
@@ -2479,12 +2487,12 @@
       CallStructure callStructure =
           resolveArguments(node.argumentsNode).callStructure;
       selector = new Selector.call(name, callStructure);
-      registry.registerDynamicInvocation(new UniverseSelector(selector, null));
+      registry.registerDynamicUse(new DynamicUse(selector, null));
       sendStructure = new InvokeStructure(semantics, selector);
     } else {
       assert(invariant(node, node.isPropertyAccess));
       selector = new Selector.getter(name);
-      registry.registerDynamicGetter(new UniverseSelector(selector, null));
+      registry.registerDynamicUse(new DynamicUse(selector, null));
       sendStructure = new GetStructure(semantics);
     }
     // TODO(23998): Remove this when all information goes through
@@ -2507,7 +2515,7 @@
         element.messageKind,
         element.messageArguments,
         infos: element.computeInfos(enclosingElement, reporter));
-    registry.registerThrowNoSuchMethod();
+    registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
 
     // TODO(johnniwinther): Support ambiguous access as an [AccessSemantics].
     AccessSemantics semantics = new StaticAccess.unresolved(error);
@@ -2526,7 +2534,7 @@
         element.messageKind,
         element.messageArguments,
         infos: element.computeInfos(enclosingElement, reporter));
-    registry.registerThrowNoSuchMethod();
+    registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
 
     // TODO(johnniwinther): Support ambiguous access as an [AccessSemantics].
     AccessSemantics accessSemantics = new StaticAccess.unresolved(error);
@@ -2541,7 +2549,7 @@
         isError: true);
     // TODO(johnniwinther): Support static instance access as an
     // [AccessSemantics].
-    registry.registerCompileTimeError(error);
+    registry.registerFeature(Feature.COMPILE_TIME_ERROR);
     return new StaticAccess.invalid(error);
   }
 
@@ -2560,9 +2568,9 @@
           LocalFunctionElementX function = semantics.element;
           function.computeType(resolution);
           if (!callStructure.signatureApplies(function.functionSignature)) {
-            registry.registerThrowNoSuchMethod();
-            registry.registerDynamicInvocation(
-                new UniverseSelector(selector, null));
+            registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
+            registry.registerDynamicUse(
+                new DynamicUse(selector, null));
             isIncompatibleInvoke = true;
           }
           break;
@@ -2571,8 +2579,8 @@
         case AccessKind.LOCAL_VARIABLE:
         case AccessKind.FINAL_LOCAL_VARIABLE:
           selector = callStructure.callSelector;
-          registry.registerDynamicInvocation(
-              new UniverseSelector(selector, null));
+          registry.registerDynamicUse(
+              new DynamicUse(selector, null));
           break;
         default:
           reporter.internalError(node,
@@ -2681,7 +2689,7 @@
 
     ResolutionResult result = handleUpdate(node, name, semantics);
     if (error != null) {
-      registry.registerThrowNoSuchMethod();
+      registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
       // TODO(23998): Remove this when all information goes through
       // the [SendStructure].
       registry.useElement(node, error);
@@ -2733,12 +2741,13 @@
           MethodElement method = semantics.element;
           method.computeType(resolution);
           if (!callStructure.signatureApplies(method.functionSignature)) {
-            registry.registerThrowNoSuchMethod();
-            registry.registerDynamicInvocation(
-                new UniverseSelector(selector, null));
+            registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
+            registry.registerDynamicUse(
+                new DynamicUse(selector, null));
             isIncompatibleInvoke = true;
           } else {
-            registry.registerStaticUse(semantics.element);
+            registry.registerStaticUse(
+                new StaticUse.staticInvoke(semantics.element, callStructure));
             handleForeignCall(node, semantics.element, callStructure);
             if (method == compiler.identicalFunction &&
                 argumentsResult.isValidAsConstant) {
@@ -2755,15 +2764,16 @@
         case AccessKind.TOPLEVEL_FIELD:
         case AccessKind.FINAL_TOPLEVEL_FIELD:
         case AccessKind.TOPLEVEL_GETTER:
-          registry.registerStaticUse(semantics.element);
+          registry.registerStaticUse(
+              new StaticUse.staticGet(semantics.element));
           selector = callStructure.callSelector;
-          registry.registerDynamicInvocation(
-              new UniverseSelector(selector, null));
+          registry.registerDynamicUse(
+              new DynamicUse(selector, null));
           break;
         case AccessKind.STATIC_SETTER:
         case AccessKind.TOPLEVEL_SETTER:
         case AccessKind.UNRESOLVED:
-          registry.registerThrowNoSuchMethod();
+          registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
           member = reportAndCreateErroneousElement(
               node.selector, name.text,
               MessageKind.CANNOT_RESOLVE_GETTER, const {});
@@ -2782,10 +2792,8 @@
       switch (semantics.kind) {
         case AccessKind.STATIC_METHOD:
         case AccessKind.TOPLEVEL_METHOD:
-          // TODO(johnniwinther): Method this should be registered as a
-          // closurization.
-          registry.registerStaticUse(semantics.element);
-          registry.registerGetOfStaticFunction(semantics.element);
+          registry.registerStaticUse(
+              new StaticUse.staticTearOff(semantics.element));
           break;
         case AccessKind.STATIC_FIELD:
         case AccessKind.FINAL_STATIC_FIELD:
@@ -2793,12 +2801,13 @@
         case AccessKind.TOPLEVEL_FIELD:
         case AccessKind.FINAL_TOPLEVEL_FIELD:
         case AccessKind.TOPLEVEL_GETTER:
-          registry.registerStaticUse(semantics.element);
+          registry.registerStaticUse(
+              new StaticUse.staticGet(semantics.element));
           break;
         case AccessKind.STATIC_SETTER:
         case AccessKind.TOPLEVEL_SETTER:
         case AccessKind.UNRESOLVED:
-          registry.registerThrowNoSuchMethod();
+          registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
           member = reportAndCreateErroneousElement(
               node.selector, name.text,
               MessageKind.CANNOT_RESOLVE_GETTER, const {});
@@ -2836,7 +2845,7 @@
         ErroneousElement error = reportAndCreateErroneousElement(
             node.selector, name.text,
             MessageKind.CANNOT_RESOLVE_SETTER, const {});
-        registry.registerThrowNoSuchMethod();
+        registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
 
         if (node.isComplex) {
           // `a++` or `a += b` where `a` has no setter.
@@ -2852,13 +2861,14 @@
               ? new StaticAccess.topLevelGetter(abstractField.getter)
               : new StaticAccess.staticGetter(abstractField.getter);
         }
-        registry.registerStaticUse(abstractField.getter);
+        registry.registerStaticUse(
+            new StaticUse.staticGet(abstractField.getter));
       } else if (node.isComplex) {
         if (abstractField.getter == null) {
           ErroneousElement error = reportAndCreateErroneousElement(
               node.selector, name.text,
               MessageKind.CANNOT_RESOLVE_GETTER, const {});
-          registry.registerThrowNoSuchMethod();
+          registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
           // `a++` or `a += b` where `a` has no getter.
           semantics = new CompoundAccessSemantics(
               element.isTopLevel
@@ -2866,7 +2876,8 @@
                   : CompoundAccessKind.UNRESOLVED_STATIC_GETTER,
               error,
               abstractField.setter);
-          registry.registerStaticUse(abstractField.setter);
+          registry.registerStaticUse(
+              new StaticUse.staticSet(abstractField.setter));
         } else {
           // `a++` or `a += b` where `a` has both a getter and a setter.
           semantics = new CompoundAccessSemantics(
@@ -2875,23 +2886,25 @@
                   : CompoundAccessKind.STATIC_GETTER_SETTER,
               abstractField.getter,
               abstractField.setter);
-          registry.registerStaticUse(abstractField.getter);
-          registry.registerStaticUse(abstractField.setter);
+          registry.registerStaticUse(
+              new StaticUse.staticGet(abstractField.getter));
+          registry.registerStaticUse(
+              new StaticUse.staticSet(abstractField.setter));
         }
       } else {
         // `a = b` where `a` has a setter.
         semantics = element.isTopLevel
             ? new StaticAccess.topLevelSetter(abstractField.setter)
             : new StaticAccess.staticSetter(abstractField.setter);
-        registry.registerStaticUse(abstractField.setter);
+        registry.registerStaticUse(
+            new StaticUse.staticSet(abstractField.setter));
       }
     } else {
       MemberElement member = element;
       // TODO(johnniwinther): Needed to provoke a parsing and with it discovery
       // of parse errors to make [element] erroneous. Fix this!
       member.computeType(resolution);
-      registry.registerStaticUse(member);
-      if (member.isErroneous) {
+      if (member.isMalformed) {
         // [member] has parse errors.
         semantics = new StaticAccess.unresolved(member);
       } else if (member.isFunction) {
@@ -2899,10 +2912,11 @@
         ErroneousElement error = reportAndCreateErroneousElement(
             node.selector, name.text,
             MessageKind.ASSIGNING_METHOD, const {});
-        registry.registerThrowNoSuchMethod();
+        registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
         if (node.isComplex) {
           // `a++` or `a += b` where `a` is a function.
-          registry.registerGetOfStaticFunction(element);
+          registry.registerStaticUse(
+              new StaticUse.staticTearOff(element));
         }
         semantics = member.isTopLevel
             ? new StaticAccess.topLevelMethod(member)
@@ -2911,15 +2925,20 @@
         // `a = b`, `a++` or `a += b` where `a` is a field.
         assert(invariant(node, member.isField,
             message: "Unexpected element: $member."));
+        if (node.isComplex) {
+          // `a++` or `a += b` where `a` is a field.
+          registry.registerStaticUse(new StaticUse.staticGet(member));
+        }
         if (member.isFinal || member.isConst) {
           ErroneousElement error = reportAndCreateErroneousElement(
                node.selector, name.text,
                MessageKind.CANNOT_RESOLVE_SETTER, const {});
-          registry.registerThrowNoSuchMethod();
+          registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
           semantics = member.isTopLevel
               ? new StaticAccess.finalTopLevelField(member)
               : new StaticAccess.finalStaticField(member);
         } else {
+          registry.registerStaticUse(new StaticUse.staticSet(member));
           semantics = member.isTopLevel
               ? new StaticAccess.topLevelField(member)
               : new StaticAccess.staticField(member);
@@ -2934,10 +2953,8 @@
     if (element.isAmbiguous) {
       return handleAmbiguousSend(node, name, element);
     }
-    if (element.isErroneous) {
+    if (element.isMalformed) {
       // This handles elements with parser errors.
-      // TODO(johnniwinther): Elements with parse error should not set
-      // [isErroneous] to `true`.
       assert(invariant(node, element is! ErroneousElement,
           message: "Unexpected erroneous element $element."));
       return handleErroneousAccess(node, name,
@@ -2976,10 +2993,8 @@
     if (element.isAmbiguous) {
       return handleAmbiguousUpdate(node, name, element);
     }
-    if (element.isErroneous) {
-      // This handles elements with parser errors.
-      // TODO(johnniwinther): Elements with parse error should not set
-      // [isErroneous] to `true`.
+    if (element.isMalformed) {
+      // This handles elements with parser errors..
       assert(invariant(node, element is! ErroneousElement,
           message: "Unexpected erroneous element $element."));
       return handleUpdate(node, name,new StaticAccess.unresolved(element));
@@ -3000,6 +3015,17 @@
     } else if (element.isTypeVariable) {
       // `T = b`, `T++`, or 'T += b` where 'T' is a type variable.
       return handleTypeVariableTypeLiteralUpdate(node, name, element);
+    } else if (element.isPrefix) {
+      // `p = b` where `p` is a prefix.
+      ErroneousElement error = reportAndCreateErroneousElement(
+           node,
+           name.text,
+           MessageKind.PREFIX_AS_EXPRESSION,
+           {'prefix': name},
+           isError: true);
+      registry.registerFeature(Feature.COMPILE_TIME_ERROR);
+      return handleUpdate(
+          node, name, new StaticAccess.invalid(error));
     } else if (element.isLocal) {
       return handleLocalUpdate(node, name, element);
     } else if (element.isStatic || element.isTopLevel) {
@@ -3132,12 +3158,12 @@
       registry.setSelector(node, setterSelector);
       registry.setOperatorSelectorInComplexSendSet(node, operatorSelector);
 
-      registry.registerDynamicInvocation(
-          new UniverseSelector(getterSelector, null));
-      registry.registerDynamicInvocation(
-          new UniverseSelector(setterSelector, null));
-      registry.registerDynamicInvocation(
-          new UniverseSelector(operatorSelector, null));
+      registry.registerDynamicUse(
+          new DynamicUse(getterSelector, null));
+      registry.registerDynamicUse(
+          new DynamicUse(setterSelector, null));
+      registry.registerDynamicUse(
+          new DynamicUse(operatorSelector, null));
 
       SendStructure sendStructure = node.isPrefix
           ? new IndexPrefixStructure(semantics, operator)
@@ -3156,8 +3182,8 @@
         // TODO(23998): Remove this when selectors are only accessed
         // through the send structure.
         registry.setSelector(node, setterSelector);
-        registry.registerDynamicInvocation(
-            new UniverseSelector(setterSelector, null));
+        registry.registerDynamicUse(
+            new DynamicUse(setterSelector, null));
 
         SendStructure sendStructure = new IndexSetStructure(semantics);
         registry.registerSendStructure(node, sendStructure);
@@ -3175,12 +3201,12 @@
         registry.setSelector(node, setterSelector);
         registry.setOperatorSelectorInComplexSendSet(node, operatorSelector);
 
-        registry.registerDynamicInvocation(
-            new UniverseSelector(getterSelector, null));
-        registry.registerDynamicInvocation(
-            new UniverseSelector(setterSelector, null));
-        registry.registerDynamicInvocation(
-            new UniverseSelector(operatorSelector, null));
+        registry.registerDynamicUse(
+            new DynamicUse(getterSelector, null));
+        registry.registerDynamicUse(
+            new DynamicUse(setterSelector, null));
+        registry.registerDynamicUse(
+            new DynamicUse(operatorSelector, null));
 
         SendStructure sendStructure =
             new CompoundIndexSetStructure(semantics, operator);
@@ -3197,6 +3223,7 @@
     String operatorText = node.assignmentOperator.source;
     Node index = node.arguments.head;
     visitExpression(index);
+
     AccessSemantics semantics = checkSuperAccess(node);
     if (node.isPrefix || node.isPostfix) {
       // `super[a]++` or `++super[a]`.
@@ -3216,16 +3243,24 @@
         semantics = computeSuperAccessSemanticsForSelectors(
             node, getterSelector, setterSelector, isIndex: true);
 
-        registry.registerStaticInvocation(semantics.getter);
-        registry.registerStaticInvocation(semantics.setter);
+        if (!semantics.getter.isError) {
+          registry.registerStaticUse(
+              new StaticUse.superInvoke(
+                  semantics.getter, getterSelector.callStructure));
+        }
+        if (!semantics.setter.isError) {
+          registry.registerStaticUse(
+              new StaticUse.superInvoke(
+                  semantics.setter, setterSelector.callStructure));
+        }
 
         // TODO(23998): Remove these when elements are only accessed
         // through the send structure.
         registry.useElement(node, semantics.setter);
         registry.useElement(node.selector, semantics.getter);
       }
-      registry.registerDynamicInvocation(
-          new UniverseSelector(operatorSelector, null));
+      registry.registerDynamicUse(
+          new DynamicUse(operatorSelector, null));
 
       SendStructure sendStructure = node.isPrefix
           ? new IndexPrefixStructure(semantics, operator)
@@ -3252,7 +3287,11 @@
         // TODO(23998): Remove this when selectors are only accessed
         // through the send structure.
         registry.setSelector(node, setterSelector);
-        registry.registerStaticInvocation(semantics.setter);
+        if (!semantics.setter.isError) {
+          registry.registerStaticUse(
+              new StaticUse.superInvoke(
+                  semantics.setter, setterSelector.callStructure));
+        }
 
         SendStructure sendStructure = new IndexSetStructure(semantics);
         registry.registerSendStructure(node, sendStructure);
@@ -3267,8 +3306,16 @@
           semantics = computeSuperAccessSemanticsForSelectors(
               node, getterSelector, setterSelector, isIndex: true);
 
-          registry.registerStaticInvocation(semantics.getter);
-          registry.registerStaticInvocation(semantics.setter);
+          if (!semantics.getter.isError) {
+            registry.registerStaticUse(
+                new StaticUse.superInvoke(
+                    semantics.getter, getterSelector.callStructure));
+          }
+          if (!semantics.setter.isError) {
+            registry.registerStaticUse(
+                new StaticUse.superInvoke(
+                    semantics.setter, setterSelector.callStructure));
+          }
 
           // TODO(23998): Remove these when elements are only accessed
           // through the send structure.
@@ -3282,8 +3329,8 @@
         registry.setSelector(node, setterSelector);
         registry.setOperatorSelectorInComplexSendSet(node, operatorSelector);
 
-        registry.registerDynamicInvocation(
-            new UniverseSelector(operatorSelector, null));
+        registry.registerDynamicUse(
+            new DynamicUse(operatorSelector, null));
 
         SendStructure sendStructure =
             new CompoundIndexSetStructure(semantics, operator);
@@ -3303,14 +3350,69 @@
     String operatorText = node.assignmentOperator.source;
     Selector getterSelector = new Selector.getter(name);
     Selector setterSelector = new Selector.setter(name);
+
+    void registerStaticUses(AccessSemantics semantics) {
+      switch (semantics.kind) {
+        case AccessKind.SUPER_METHOD:
+          registry.registerStaticUse(
+              new StaticUse.superTearOff(semantics.element));
+          break;
+        case AccessKind.SUPER_GETTER:
+          registry.registerStaticUse(new StaticUse.superGet(semantics.getter));
+          break;
+        case AccessKind.SUPER_SETTER:
+          registry.registerStaticUse(new StaticUse.superSet(semantics.setter));
+          break;
+        case AccessKind.SUPER_FIELD:
+          registry.registerStaticUse(
+              new StaticUse.superGet(semantics.element));
+          registry.registerStaticUse(
+              new StaticUse.superSet(semantics.element));
+          break;
+        case AccessKind.SUPER_FINAL_FIELD:
+          registry.registerStaticUse(
+              new StaticUse.superGet(semantics.element));
+          break;
+        case AccessKind.COMPOUND:
+          CompoundAccessSemantics compoundSemantics = semantics;
+          switch (compoundSemantics.compoundAccessKind) {
+            case CompoundAccessKind.SUPER_GETTER_SETTER:
+            case CompoundAccessKind.SUPER_GETTER_FIELD:
+            case CompoundAccessKind.SUPER_FIELD_SETTER:
+            case CompoundAccessKind.SUPER_FIELD_FIELD:
+              registry.registerStaticUse(
+                  new StaticUse.superGet(semantics.getter));
+              registry.registerStaticUse(
+                  new StaticUse.superSet(semantics.setter));
+              break;
+            case CompoundAccessKind.SUPER_METHOD_SETTER:
+              registry.registerStaticUse(
+                  new StaticUse.superSet(semantics.setter));
+              break;
+            case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
+              registry.registerStaticUse(
+                  new StaticUse.superSet(semantics.setter));
+              break;
+            case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
+              registry.registerStaticUse(
+                  new StaticUse.superGet(semantics.getter));
+              break;
+            default:
+              break;
+          }
+          break;
+        default:
+          break;
+      }
+    }
+
     AccessSemantics semantics = checkSuperAccess(node);
     if (node.isPrefix || node.isPostfix) {
       // `super.a++` or `++super.a`.
       if (semantics == null) {
         semantics = computeSuperAccessSemanticsForSelectors(
             node, getterSelector, setterSelector);
-        registry.registerStaticInvocation(semantics.getter);
-        registry.registerStaticInvocation(semantics.setter);
+        registerStaticUses(semantics);
       }
       return handleUpdate(node, name, semantics);
     } else {
@@ -3321,7 +3423,6 @@
           semantics =
               computeSuperAccessSemanticsForSelector(
                   node, setterSelector, alternateName: name);
-          registry.registerStaticInvocation(semantics.setter);
           switch (semantics.kind) {
             case AccessKind.SUPER_FINAL_FIELD:
               reporter.reportWarningMessage(
@@ -3330,9 +3431,9 @@
                   {'name': name,
                    'superclassName': semantics.setter.enclosingClass.name});
               // TODO(johnniwinther): This shouldn't be needed.
-              registry.registerDynamicInvocation(
-                  new UniverseSelector(setterSelector, null));
-              registry.registerSuperNoSuchMethod();
+              registry.registerDynamicUse(
+                  new DynamicUse(setterSelector, null));
+              registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD);
               break;
             case AccessKind.SUPER_METHOD:
               reporter.reportWarningMessage(
@@ -3340,12 +3441,16 @@
                   {'name': name,
                    'superclassName': semantics.setter.enclosingClass.name});
               // TODO(johnniwinther): This shouldn't be needed.
-              registry.registerDynamicInvocation(
-                  new UniverseSelector(setterSelector, null));
-              registry.registerSuperNoSuchMethod();
+              registry.registerDynamicUse(
+                  new DynamicUse(setterSelector, null));
+              registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD);
+              break;
+            case AccessKind.SUPER_FIELD:
+            case AccessKind.SUPER_SETTER:
+              registry.registerStaticUse(
+                  new StaticUse.superSet(semantics.setter));
               break;
             default:
-              registry.registerStaticInvocation(semantics.setter);
               break;
           }
         }
@@ -3355,8 +3460,7 @@
         if (semantics == null) {
           semantics = computeSuperAccessSemanticsForSelectors(
               node, getterSelector, setterSelector);
-          registry.registerStaticInvocation(semantics.getter);
-          registry.registerStaticInvocation(semantics.setter);
+          registerStaticUses(semantics);
         }
         return handleUpdate(node, name, semantics);
       }
@@ -3390,14 +3494,14 @@
       registry.useElement(node, semantics.setter);
       registry.useElement(node.selector, semantics.getter);
 
-      registry.registerDynamicInvocation(
-          new UniverseSelector(operatorSelector, null));
+      registry.registerDynamicUse(
+          new DynamicUse(operatorSelector, null));
 
       SendStructure sendStructure = node.isPrefix
           ? new PrefixStructure(semantics, operator)
           : new PostfixStructure(semantics, operator);
       registry.registerSendStructure(node, sendStructure);
-      registry.registerIncDecOperation();
+      registry.registerFeature(Feature.INC_DEC_OPERATION);
     } else {
       Node rhs = node.arguments.head;
       visitExpression(rhs);
@@ -3432,8 +3536,8 @@
         registry.setSelector(node, setterSelector);
         registry.setOperatorSelectorInComplexSendSet(node, operatorSelector);
 
-        registry.registerDynamicInvocation(
-            new UniverseSelector(operatorSelector, null));
+        registry.registerDynamicUse(
+            new DynamicUse(operatorSelector, null));
 
         SendStructure sendStructure;
         if (operator.kind == AssignmentOperatorKind.IF_NULL) {
@@ -3468,56 +3572,33 @@
     }
   }
 
-  void registerSend(Selector selector, Element target) {
-    if (target == null || target.isInstanceMember) {
-      if (selector.isGetter) {
-        registry.registerDynamicGetter(
-            new UniverseSelector(selector, null));
-      } else if (selector.isSetter) {
-        registry.registerDynamicSetter(
-            new UniverseSelector(selector, null));
-      } else {
-        registry.registerDynamicInvocation(
-            new UniverseSelector(selector, null));
-      }
-    } else if (Elements.isStaticOrTopLevel(target)) {
-      // Avoid registration of type variables since they are not analyzable but
-      // instead resolved through their enclosing type declaration.
-      if (!target.isTypeVariable) {
-        // [target] might be the implementation element and only declaration
-        // elements may be registered.
-        registry.registerStaticUse(target.declaration);
-      }
-    }
-  }
-
   ConstantResult visitLiteralInt(LiteralInt node) {
-    registry.registerInstantiatedType(coreTypes.intType);
     ConstantExpression constant = new IntConstantExpression(node.value);
+    registry.registerConstantLiteral(constant);
     registry.setConstant(node, constant);
     return new ConstantResult(node, constant);
   }
 
   ConstantResult visitLiteralDouble(LiteralDouble node) {
-    registry.registerInstantiatedType(coreTypes.doubleType);
     ConstantExpression constant = new DoubleConstantExpression(node.value);
+    registry.registerConstantLiteral(constant);
     registry.setConstant(node, constant);
     return new ConstantResult(node, constant);
   }
 
   ConstantResult visitLiteralBool(LiteralBool node) {
-    registry.registerInstantiatedType(coreTypes.boolType);
     ConstantExpression constant = new BoolConstantExpression(node.value);
+    registry.registerConstantLiteral(constant);
     registry.setConstant(node, constant);
     return new ConstantResult(node, constant);
   }
 
   ResolutionResult visitLiteralString(LiteralString node) {
-    registry.registerInstantiatedType(coreTypes.stringType);
     if (node.dartString != null) {
       // [dartString] might be null on parser errors.
       ConstantExpression constant =
           new StringConstantExpression(node.dartString.slowToString());
+      registry.registerConstantLiteral(constant);
       registry.setConstant(node, constant);
       return new ConstantResult(node, constant);
     }
@@ -3525,16 +3606,15 @@
   }
 
   ConstantResult visitLiteralNull(LiteralNull node) {
-    registry.registerInstantiatedType(coreTypes.nullType);
     ConstantExpression constant = new NullConstantExpression();
+    registry.registerConstantLiteral(constant);
     registry.setConstant(node, constant);
     return new ConstantResult(node, constant);
   }
 
   ConstantResult visitLiteralSymbol(LiteralSymbol node) {
-    registry.registerInstantiatedClass(compiler.symbolClass);
-    registry.registerStaticUse(compiler.symbolConstructor.declaration);
     String name = node.slowNameString;
+    // TODO(johnniwinther): Use [registerConstantLiteral] instead.
     registry.registerConstSymbol(name);
     if (!validateSymbol(node, name, reportError: false)) {
       reporter.reportErrorMessage(
@@ -3549,7 +3629,7 @@
   }
 
   ResolutionResult visitStringJuxtaposition(StringJuxtaposition node) {
-    registry.registerInstantiatedType(coreTypes.stringType);
+    registry.registerFeature(Feature.STRING_JUXTAPOSITION);
     ResolutionResult first = visit(node.first);
     ResolutionResult second = visit(node.second);
     if (first.isConstant && second.isConstant) {
@@ -3598,37 +3678,54 @@
   }
 
   ResolutionResult visitYield(Yield node) {
-    compiler.streamClass.ensureResolved(resolution);
-    compiler.iterableClass.ensureResolved(resolution);
+    coreClasses.streamClass.ensureResolved(resolution);
+    coreClasses.iterableClass.ensureResolved(resolution);
     visit(node.expression);
     return const NoneResult();
   }
 
   ResolutionResult visitRedirectingFactoryBody(RedirectingFactoryBody node) {
-    final isSymbolConstructor = enclosingElement == compiler.symbolConstructor;
     if (!enclosingElement.isFactoryConstructor) {
       reporter.reportErrorMessage(
           node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY);
       reporter.reportHintMessage(
           enclosingElement, MessageKind.MISSING_FACTORY_KEYWORD);
     }
+
     ConstructorElementX constructor = enclosingElement;
     bool isConstConstructor = constructor.isConst;
     bool isValidAsConstant = isConstConstructor;
-    ConstructorElement redirectionTarget = resolveRedirectingFactory(
-        node, inConstContext: isConstConstructor).element;
+    ConstructorResult result = resolveRedirectingFactory(
+        node, inConstContext: isConstConstructor);
+    ConstructorElement redirectionTarget = result.element;
     constructor.immediateRedirectionTarget = redirectionTarget;
 
     Node constructorReference = node.constructorReference;
-    if (constructorReference is Send) {
-      constructor.redirectionDeferredPrefix =
-          compiler.deferredLoadTask.deferredPrefixElement(constructorReference,
-                                                          registry.mapping);
+    if (result.isDeferred) {
+      constructor.redirectionDeferredPrefix = result.prefix;
     }
 
     registry.setRedirectingTargetConstructor(node, redirectionTarget);
+    switch (result.kind) {
+      case ConstructorResultKind.GENERATIVE:
+      case ConstructorResultKind.FACTORY:
+        // Register a post process to check for cycles in the redirection chain
+        // and set the actual generative constructor at the end of the chain.
+        addDeferredAction(constructor, () {
+          compiler.resolver.resolveRedirectionChain(constructor, node);
+        });
+        break;
+      case ConstructorResultKind.ABSTRACT:
+      case ConstructorResultKind.INVALID_TYPE:
+      case ConstructorResultKind.UNRESOLVED_CONSTRUCTOR:
+      case ConstructorResultKind.NON_CONSTANT:
+        isValidAsConstant = false;
+        constructor.setEffectiveTarget(
+            result.element, result.type, isMalformed: true);
+        break;
+    }
     if (Elements.isUnresolved(redirectionTarget)) {
-      registry.registerThrowNoSuchMethod();
+      registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
       return const NoneResult();
     } else {
       if (isConstConstructor &&
@@ -3650,15 +3747,17 @@
     // redirecting constructor.
     ClassElement targetClass = redirectionTarget.enclosingClass;
     InterfaceType type = registry.getType(node);
-    FunctionType targetType = redirectionTarget.computeType(resolution)
-        .subst(type.typeArguments, targetClass.typeVariables);
+    FunctionType targetConstructorType =
+        redirectionTarget.computeType(resolution)
+            .subst(type.typeArguments, targetClass.typeVariables);
     FunctionType constructorType = constructor.computeType(resolution);
-    bool isSubtype = compiler.types.isSubtype(targetType, constructorType);
+    bool isSubtype = compiler.types.isSubtype(
+        targetConstructorType, constructorType);
     if (!isSubtype) {
       reporter.reportWarningMessage(
           node,
           MessageKind.NOT_ASSIGNABLE,
-          {'fromType': targetType, 'toType': constructorType});
+          {'fromType': targetConstructorType, 'toType': constructorType});
       // TODO(johnniwinther): Handle this (potentially) erroneous case.
       isValidAsConstant = false;
     }
@@ -3669,22 +3768,19 @@
     FunctionSignature constructorSignature = constructor.functionSignature;
     if (!targetSignature.isCompatibleWith(constructorSignature)) {
       assert(!isSubtype);
-      registry.registerThrowNoSuchMethod();
+      registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
       isValidAsConstant = false;
     }
 
-    // Register a post process to check for cycles in the redirection chain and
-    // set the actual generative constructor at the end of the chain.
-    addDeferredAction(constructor, () {
-      compiler.resolver.resolveRedirectionChain(constructor, node);
-    });
-
-    registry.registerStaticUse(redirectionTarget);
-    // TODO(johnniwinther): Register the effective target type instead.
-    registry.registerInstantiatedClass(
-        redirectionTarget.enclosingClass.declaration);
-    if (isSymbolConstructor) {
-      registry.registerSymbolConstructor();
+    registry.registerStaticUse(
+        new StaticUse.constructorRedirect(redirectionTarget));
+    // TODO(johnniwinther): Register the effective target type as part of the
+    // static use instead.
+    registry.registerTypeUse(new TypeUse.instantiation(
+        redirectionTarget.enclosingClass.thisType
+            .subst(type.typeArguments, targetClass.typeVariables)));
+    if (enclosingElement == compiler.symbolConstructor) {
+      registry.registerFeature(Feature.SYMBOL_CONSTRUCTOR);
     }
     if (isValidAsConstant) {
       List<String> names = <String>[];
@@ -3714,13 +3810,13 @@
   }
 
   ResolutionResult visitThrow(Throw node) {
-    registry.registerThrowExpression();
+    registry.registerFeature(Feature.THROW_EXPRESSION);
     visit(node.expression);
     return const NoneResult();
   }
 
   ResolutionResult visitAwait(Await node) {
-    compiler.futureClass.ensureResolved(resolution);
+    coreClasses.futureClass.ensureResolved(resolution);
     visit(node.expression);
     return const NoneResult();
   }
@@ -3758,7 +3854,7 @@
     if (modifiers.isVar && (modifiers.isConst || node.type != null)) {
       reportExtraModifier('var');
     }
-    if (enclosingElement.isFunction) {
+    if (enclosingElement.isFunction || enclosingElement.isConstructor) {
       if (modifiers.isAbstract) {
         reportExtraModifier('abstract');
       }
@@ -3798,12 +3894,8 @@
   }
 
   ResolutionResult visitNewExpression(NewExpression node) {
-    bool isValidAsConstant = true;
-    ConstructorElement constructor = resolveConstructor(node).element;
-    final bool isSymbolConstructor = constructor == compiler.symbolConstructor;
-    final bool isMirrorsUsedConstant =
-        node.isConst && (constructor == compiler.mirrorsUsedConstructor);
-    Selector callSelector = resolveSelector(node.send, constructor);
+    ConstructorResult result = resolveConstructor(node);
+    ConstructorElement constructor = result.element;
     ArgumentsResult argumentsResult;
     if (node.isConst) {
       argumentsResult =
@@ -3811,43 +3903,88 @@
     } else {
       argumentsResult = resolveArguments(node.send.argumentsNode);
     }
+    // TODO(johnniwinther): Avoid the need for a [Selector].
+    Selector selector = resolveSelector(node.send, constructor);
+    CallStructure callStructure = selector.callStructure;
     registry.useElement(node.send, constructor);
-    if (Elements.isUnresolved(constructor)) {
-      return new ResolutionResult.forElement(constructor);
-    }
-    constructor.computeType(resolution);
-    if (!callSelector.applies(constructor, compiler.world)) {
-      registry.registerThrowNoSuchMethod();
+
+    DartType type = result.type;
+    ConstructorAccessKind kind;
+    NewStructure newStructure;
+    bool isInvalid = false;
+    switch (result.kind) {
+      case ConstructorResultKind.GENERATIVE:
+        // Ensure that the signature of [constructor] has been computed.
+        constructor.computeType(resolution);
+        if (!callStructure.signatureApplies(constructor.functionSignature)) {
+          isInvalid = true;
+          kind = ConstructorAccessKind.INCOMPATIBLE;
+          registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
+        } else {
+          kind = ConstructorAccessKind.GENERATIVE;
+        }
+        break;
+      case ConstructorResultKind.FACTORY:
+        // Ensure that the signature of [constructor] has been computed.
+        constructor.computeType(resolution);
+        if (!callStructure.signatureApplies(constructor.functionSignature)) {
+          // The effective target might still be valid(!) so the is not an
+          // invalid case in itself. For instance
+          //
+          //    class A {
+          //       factory A() = A.a;
+          //       A.a(a);
+          //    }
+          //    m() => new A(0); // This creates a warning but works at runtime.
+          //
+          registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
+        }
+        kind = ConstructorAccessKind.FACTORY;
+        break;
+      case ConstructorResultKind.ABSTRACT:
+        isInvalid = true;
+        kind = ConstructorAccessKind.ABSTRACT;
+        break;
+      case ConstructorResultKind.INVALID_TYPE:
+        isInvalid = true;
+        kind = ConstructorAccessKind.UNRESOLVED_TYPE;
+        break;
+      case ConstructorResultKind.UNRESOLVED_CONSTRUCTOR:
+        // TODO(johnniwinther): Unify codepaths to only have one return.
+        registry.registerNewStructure(node,
+            new NewInvokeStructure(
+                new ConstructorAccessSemantics(
+                    ConstructorAccessKind.UNRESOLVED_CONSTRUCTOR,
+                    constructor,
+                    type),
+                selector));
+        return new ResolutionResult.forElement(constructor);
+      case ConstructorResultKind.NON_CONSTANT:
+        registry.registerNewStructure(node,
+            new NewInvokeStructure(
+                new ConstructorAccessSemantics(
+                    ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR,
+                    constructor,
+                    type),
+                selector));
+        return new ResolutionResult.forElement(constructor);
     }
 
-    // [constructor] might be the implementation element
-    // and only declaration elements may be registered.
-    registry.registerStaticUse(constructor.declaration);
-    ClassElement cls = constructor.enclosingClass;
-    if (cls.isEnumClass && currentClass != cls) {
-      reporter.reportErrorMessage(
-          node,
-          MessageKind.CANNOT_INSTANTIATE_ENUM,
-          {'enumName': cls.name});
-      isValidAsConstant = false;
+    if (!isInvalid) {
+      // [constructor] might be the implementation element
+      // and only declaration elements may be registered.
+      registry.registerStaticUse(
+          new StaticUse.constructorInvoke(
+              constructor.declaration, callStructure));
+      // TODO(johniwinther): Avoid registration of `type` in face of redirecting
+      // factory constructors.
+      registry.registerTypeUse(new TypeUse.instantiation(type));
     }
 
-    InterfaceType type = registry.getType(node);
-    if (node.isConst && type.containsTypeVariables) {
-      reporter.reportErrorMessage(
-          node.send.selector,
-          MessageKind.TYPE_VARIABLE_IN_CONSTANT);
-      isValidAsConstant = false;
-    }
-    // TODO(johniwinther): Avoid registration of `type` in face of redirecting
-    // factory constructors.
-    registry.registerInstantiatedType(type);
-    if (constructor.isGenerativeConstructor && cls.isAbstract) {
-      isValidAsConstant = false;
-    }
+    if (node.isConst) {
+      bool isValidAsConstant = !isInvalid && constructor.isConst;
 
-    if (isSymbolConstructor) {
-      if (node.isConst) {
+      if (constructor == compiler.symbolConstructor) {
         Node argumentNode = node.send.arguments.head;
         ConstantExpression constant =
             compiler.resolver.constantCompiler.compileNode(
@@ -3866,47 +4003,67 @@
             registry.registerConstSymbol(nameString);
           }
         }
-      } else {
-        if (!compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(
-                enclosingElement)) {
-          reporter.reportHintMessage(
-              node.newToken, MessageKind.NON_CONST_BLOAT,
-              {'name': compiler.symbolClass.name});
-        }
+      } else if (constructor == compiler.mirrorsUsedConstructor) {
+        compiler.mirrorUsageAnalyzerTask.validate(node, registry.mapping);
       }
-    } else if (isMirrorsUsedConstant) {
-      compiler.mirrorUsageAnalyzerTask.validate(node, registry.mapping);
-    }
-    if (node.isConst) {
+
       analyzeConstantDeferred(node);
 
-      // TODO(johnniwinther): Compute this in the [ConstructorResolver].
-      // Check that the constructor is not deferred.
-      Send send = node.send.selector.asSend();
-      if (send != null) {
-        // Of the form `const a.b(...)`.
-        if (compiler.deferredLoadTask.deferredPrefixElement(
-                send, registry.mapping) != null) {
-          // `a` is a deferred prefix.
-          isValidAsConstant = false;
-          // TODO(johnniwinther): Create an [ErroneousConstantExpression] here
-          // when constants are only created during resolution.
-        }
+      if (type.containsTypeVariables) {
+        reporter.reportErrorMessage(
+            node.send.selector,
+            MessageKind.TYPE_VARIABLE_IN_CONSTANT);
+        isValidAsConstant = false;
+        isInvalid = true;
+      }
+
+      if (result.isDeferred) {
+        isValidAsConstant = false;
       }
 
       if (isValidAsConstant &&
-          constructor.isConst &&
-          argumentsResult.isValidAsConstant) {
+          argumentsResult.isValidAsConstant &&
+          // TODO(johnniwinther): Remove this when all constants are computed
+          // in resolution.
+          !constructor.isFromEnvironmentConstructor) {
         CallStructure callStructure = argumentsResult.callStructure;
         List<ConstantExpression> arguments = argumentsResult.constantArguments;
+
         ConstructedConstantExpression constant =
             new ConstructedConstantExpression(
                 type,
                 constructor,
                 callStructure,
                 arguments);
+        registry.registerNewStructure(node,
+            new ConstInvokeStructure(ConstantInvokeKind.CONSTRUCTED, constant));
         return new ConstantResult(node, constant);
+      } else if (isInvalid) {
+        // Known to be non-constant.
+        kind == ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR;
+        registry.registerNewStructure(node,
+            new NewInvokeStructure(
+                new ConstructorAccessSemantics(kind, constructor, type),
+                selector));
+      } else {
+        // Might be valid but we don't know for sure. The compile-time constant
+        // evaluator will compute the actual constant as a deferred action.
+        registry.registerNewStructure(node,
+            new LateConstInvokeStructure(registry.mapping));
       }
+
+    } else {
+      // Not constant.
+      if (constructor == compiler.symbolConstructor &&
+          !compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) {
+          reporter.reportHintMessage(
+              node.newToken, MessageKind.NON_CONST_BLOAT,
+              {'name': coreClasses.symbolClass.name});
+      }
+      registry.registerNewStructure(node,
+          new NewInvokeStructure(
+              new ConstructorAccessSemantics(kind, constructor, type),
+              selector));
     }
 
     return const NoneResult();
@@ -3919,9 +4076,9 @@
       ObjectConstantValue objectConstant = key;
       DartType keyType = objectConstant.type;
       ClassElement cls = keyType.element;
-      if (cls == compiler.stringClass) continue;
+      if (cls == coreClasses.stringClass) continue;
       Element equals = cls.lookupMember('==');
-      if (equals.enclosingClass != compiler.objectClass) {
+      if (equals.enclosingClass != coreClasses.objectClass) {
         reporter.reportErrorMessage(
             spannable,
             MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS,
@@ -3994,8 +4151,7 @@
         this, node, malformedIsError: malformedIsError,
         deferredIsMalformed: deferredIsMalformed);
     if (inCheckContext) {
-      registry.registerCheckedModeCheck(type);
-      registry.registerRequiredType(type, enclosingElement);
+      registry.registerTypeUse(new TypeUse.checkedModeCheck(type));
     }
     return type;
   }
@@ -4039,7 +4195,6 @@
         listType,
         isConstant: node.isConst,
         isEmpty: node.elements.isEmpty);
-    registry.registerRequiredType(listType, enclosingElement);
     if (node.isConst) {
       List<ConstantExpression> constantExpressions = <ConstantExpression>[];
       inConstantContext(() {
@@ -4088,8 +4243,10 @@
   }
 
   ResolutionResult visitStringInterpolation(StringInterpolation node) {
-    registry.registerInstantiatedType(coreTypes.stringType);
-    registry.registerStringInterpolation();
+    // TODO(johnniwinther): This should be a consequence of the registration
+    // of [registerStringInterpolation].
+    registry.registerTypeUse(new TypeUse.instantiation(coreTypes.stringType));
+    registry.registerFeature(Feature.STRING_INTERPOLATION);
     registerImplicitInvocation(Selectors.toString_);
 
     bool isValidAsConstant = true;
@@ -4180,17 +4337,15 @@
   }
 
   registerImplicitInvocation(Selector selector) {
-    registry.registerDynamicInvocation(new UniverseSelector(selector, null));
+    registry.registerDynamicUse(new DynamicUse(selector, null));
   }
 
   ResolutionResult visitAsyncForIn(AsyncForIn node) {
-    registry.registerAsyncForIn(node);
-    registry.setCurrentSelector(node, Selectors.current);
-    registry.registerDynamicGetter(
-        new UniverseSelector(Selectors.current, null));
-    registry.setMoveNextSelector(node, Selectors.moveNext);
-    registry.registerDynamicInvocation(
-        new UniverseSelector(Selectors.moveNext, null));
+    registry.registerFeature(Feature.ASYNC_FOR_IN);
+    registry.registerDynamicUse(
+        new DynamicUse(Selectors.current, null));
+    registry.registerDynamicUse(
+        new DynamicUse(Selectors.moveNext, null));
 
     visit(node.expression);
 
@@ -4201,16 +4356,13 @@
   }
 
   ResolutionResult visitSyncForIn(SyncForIn node) {
-    registry.registerSyncForIn(node);
-    registry.setIteratorSelector(node, Selectors.iterator);
-    registry.registerDynamicGetter(
-        new UniverseSelector(Selectors.iterator, null));
-    registry.setCurrentSelector(node, Selectors.current);
-    registry.registerDynamicGetter(
-        new UniverseSelector(Selectors.current, null));
-    registry.setMoveNextSelector(node, Selectors.moveNext);
-    registry.registerDynamicInvocation(
-        new UniverseSelector(Selectors.moveNext, null));
+    registry.registerFeature(Feature.SYNC_FOR_IN);
+    registry.registerDynamicUse(
+        new DynamicUse(Selectors.iterator, null));
+    registry.registerDynamicUse(
+        new DynamicUse(Selectors.current, null));
+    registry.registerDynamicUse(
+        new DynamicUse(Selectors.moveNext, null));
 
     visit(node.expression);
 
@@ -4272,7 +4424,13 @@
     }
     if (loopVariableSelector != null) {
       registry.setSelector(declaration, loopVariableSelector);
-      registerSend(loopVariableSelector, loopVariable);
+      if (loopVariable == null || loopVariable.isInstanceMember) {
+        registry.registerDynamicUse(
+            new DynamicUse(loopVariableSelector, null));
+      } else if (loopVariable.isStatic || loopVariable.isTopLevel) {
+        registry.registerStaticUse(
+            new StaticUse.staticSet(loopVariable.declaration));
+      }
     } else {
       // The selector may only be null if we reported an error.
       assert(invariant(declaration, compiler.compilationFailed));
@@ -4363,9 +4521,8 @@
         mapType,
         isConstant: node.isConst,
         isEmpty: node.entries.isEmpty);
-    registry.registerRequiredType(mapType, enclosingElement);
-    if (node.isConst) {
 
+    if (node.isConst) {
       List<ConstantExpression> keyExpressions = <ConstantExpression>[];
       List<ConstantExpression> valueExpressions = <ConstantExpression>[];
       inConstantContext(() {
@@ -4407,12 +4564,12 @@
   }
 
   DartType typeOfConstant(ConstantValue constant) {
-    if (constant.isInt) return compiler.intClass.rawType;
-    if (constant.isBool) return compiler.boolClass.rawType;
-    if (constant.isDouble) return compiler.doubleClass.rawType;
-    if (constant.isString) return compiler.stringClass.rawType;
-    if (constant.isNull) return compiler.nullClass.rawType;
-    if (constant.isFunction) return compiler.functionClass.rawType;
+    if (constant.isInt) return coreTypes.intType;
+    if (constant.isBool) return coreTypes.boolType;
+    if (constant.isDouble) return coreTypes.doubleType;
+    if (constant.isString) return coreTypes.stringType;
+    if (constant.isNull) return coreTypes.nullType;
+    if (constant.isFunction) return coreTypes.functionType;
     assert(constant.isObject);
     ObjectConstantValue objectConstant = constant;
     return objectConstant.type;
@@ -4421,7 +4578,7 @@
   bool overridesEquals(DartType type) {
     ClassElement cls = type.element;
     Element equals = cls.lookupMember('==');
-    return equals.enclosingClass != compiler.objectClass;
+    return equals.enclosingClass != coreClasses.objectClass;
   }
 
   void checkCaseExpressions(SwitchStatement node) {
@@ -4446,7 +4603,7 @@
             message: 'No constant computed for $node'));
 
         ConstantValue value = compiler.constants.getConstantValue(constant);
-        DartType caseType = typeOfConstant(value);
+        DartType caseType = value.getType(coreTypes);//typeOfConstant(value);
 
         if (firstCaseType == null) {
           firstCase = caseMatch;
@@ -4454,12 +4611,12 @@
 
           // We only report the bad type on the first class element. All others
           // get a "type differs" error.
-          if (caseType.element == compiler.doubleClass) {
+          if (caseType == coreTypes.doubleType) {
             reporter.reportErrorMessage(
                 node,
                 MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS,
                 {'type': "double"});
-          } else if (caseType.element == compiler.functionClass) {
+          } else if (caseType == coreTypes.functionType) {
             reporter.reportErrorMessage(
                 node, MessageKind.SWITCH_CASE_FORBIDDEN,
                 {'type': "Function"});
@@ -4575,7 +4732,7 @@
     });
     // TODO(15575): We should warn if we can detect a fall through
     // error.
-    registry.registerFallThroughError();
+    registry.registerFeature(Feature.FALL_THROUGH_ERROR);
     return const NoneResult();
   }
 
@@ -4606,7 +4763,7 @@
   }
 
   ResolutionResult visitCatchBlock(CatchBlock node) {
-    registry.registerCatchStatement();
+    registry.registerFeature(Feature.CATCH_STATEMENT);
     // Check that if catch part is present, then
     // it has one or two formal parameters.
     VariableDefinitions exceptionDefinition;
@@ -4628,7 +4785,7 @@
                   extra, MessageKind.EXTRA_CATCH_DECLARATION);
             }
           }
-          registry.registerStackTraceInCatch();
+          registry.registerFeature(Feature.STACK_TRACE_IN_CATCH);
         }
       }
 
@@ -4659,26 +4816,29 @@
     }
 
     Scope blockScope = new BlockScope(scope);
-    doInCheckContext(() => visitIn(node.type, blockScope));
+    TypeResult exceptionTypeResult = visitIn(node.type, blockScope);
     visitIn(node.formals, blockScope);
     var oldInCatchBlock = inCatchBlock;
     inCatchBlock = true;
     visitIn(node.block, blockScope);
     inCatchBlock = oldInCatchBlock;
 
-    if (node.type != null && exceptionDefinition != null) {
-      DartType exceptionType = registry.getType(node.type);
-      Node exceptionVariable = exceptionDefinition.definitions.nodes.head;
-      VariableElementX exceptionElement =
-          registry.getDefinition(exceptionVariable);
-      exceptionElement.variables.type = exceptionType;
+    if (exceptionTypeResult != null) {
+      DartType exceptionType = exceptionTypeResult.type;
+      if (exceptionDefinition != null) {
+        Node exceptionVariable = exceptionDefinition.definitions.nodes.head;
+        VariableElementX exceptionElement =
+            registry.getDefinition(exceptionVariable);
+        exceptionElement.variables.type = exceptionType;
+      }
+      registry.registerTypeUse(new TypeUse.catchType(exceptionType));
     }
     if (stackTraceDefinition != null) {
       Node stackTraceVariable = stackTraceDefinition.definitions.nodes.head;
       VariableElementX stackTraceElement =
           registry.getDefinition(stackTraceVariable);
-      registry.registerInstantiatedClass(compiler.stackTraceClass);
-      stackTraceElement.variables.type = compiler.stackTraceClass.rawType;
+      InterfaceType stackTraceType = coreTypes.stackTraceType;
+      stackTraceElement.variables.type = stackTraceType;
     }
     return const NoneResult();
   }
diff --git a/pkg/compiler/lib/src/resolution/registry.dart b/pkg/compiler/lib/src/resolution/registry.dart
index b93c6e9..a01b17c 100644
--- a/pkg/compiler/lib/src/resolution/registry.dart
+++ b/pkg/compiler/lib/src/resolution/registry.dart
@@ -29,8 +29,12 @@
     CallStructure;
 import '../universe/selector.dart' show
     Selector;
-import '../universe/universe.dart' show
-    UniverseSelector;
+import '../universe/use.dart' show
+    DynamicUse,
+    StaticUse,
+    TypeUse;
+import '../universe/world_impact.dart' show
+    WorldImpactBuilder;
 import '../world.dart' show World;
 
 import 'send_structure.dart';
@@ -40,165 +44,15 @@
 import 'tree_elements.dart' show
     TreeElementMapping;
 
-// TODO(johnniwinther): Remove this.
-class EagerRegistry extends Registry {
-  final Compiler compiler;
-  final TreeElementMapping mapping;
-
-  EagerRegistry(this.compiler, this.mapping);
-
-  ResolutionEnqueuer get world => compiler.enqueuer.resolution;
-
-  @override
-  bool get isForResolution => true;
-
-  @override
-  void registerDynamicGetter(UniverseSelector selector) {
-    world.registerDynamicGetter(selector);
-  }
-
-  @override
-  void registerDynamicInvocation(UniverseSelector selector) {
-    world.registerDynamicInvocation(selector);
-  }
-
-  @override
-  void registerDynamicSetter(UniverseSelector selector) {
-    world.registerDynamicSetter(selector);
-  }
-
-  @override
-  void registerGetOfStaticFunction(FunctionElement element) {
-    world.registerGetOfStaticFunction(element);
-  }
-
-  @override
-  void registerInstantiation(InterfaceType type) {
-    world.registerInstantiatedType(type);
-  }
-
-  @override
-  void registerStaticInvocation(Element element) {
-    registerDependency(element);
-    world.registerStaticUse(element);
-  }
-
-  String toString() => 'EagerRegistry for ${mapping.analyzedElement}';
-}
-
-class _ResolutionWorldImpact implements ResolutionImpact {
-  final Registry registry;
-  // TODO(johnniwinther): Do we benefit from lazy initialization of the
-  // [Setlet]s?
-  Setlet<UniverseSelector> _dynamicInvocations;
-  Setlet<UniverseSelector> _dynamicGetters;
-  Setlet<UniverseSelector> _dynamicSetters;
-  Setlet<InterfaceType> _instantiatedTypes;
-  Setlet<Element> _staticUses;
-  Setlet<DartType> _isChecks;
-  Setlet<DartType> _asCasts;
-  Setlet<DartType> _checkedModeChecks;
-  Setlet<MethodElement> _closurizedFunctions;
-  Setlet<LocalFunctionElement> _closures;
+class _ResolutionWorldImpact extends ResolutionImpact with WorldImpactBuilder {
+  final String name;
   Setlet<Feature> _features;
-  // TODO(johnniwinther): This seems to be a union of other sets.
-  Setlet<DartType> _requiredTypes;
   Setlet<MapLiteralUse> _mapLiterals;
   Setlet<ListLiteralUse> _listLiterals;
-  Setlet<DartType> _typeLiterals;
   Setlet<String> _constSymbolNames;
+  Setlet<ConstantExpression> _constantLiterals;
 
-  _ResolutionWorldImpact(Compiler compiler, TreeElementMapping mapping)
-      : this.registry = new EagerRegistry(compiler, mapping);
-
-  void registerDependency(Element element) {
-    assert(element != null);
-    registry.registerDependency(element);
-  }
-
-  void registerDynamicGetter(UniverseSelector selector) {
-    assert(selector != null);
-    if (_dynamicGetters == null) {
-      _dynamicGetters = new Setlet<UniverseSelector>();
-    }
-    _dynamicGetters.add(selector);
-  }
-
-  @override
-  Iterable<UniverseSelector> get dynamicGetters {
-    return _dynamicGetters != null
-        ? _dynamicGetters : const <UniverseSelector>[];
-  }
-
-  void registerDynamicInvocation(UniverseSelector selector) {
-    assert(selector != null);
-    if (_dynamicInvocations == null) {
-      _dynamicInvocations = new Setlet<UniverseSelector>();
-    }
-    _dynamicInvocations.add(selector);
-  }
-
-  @override
-  Iterable<UniverseSelector> get dynamicInvocations {
-    return _dynamicInvocations != null
-        ? _dynamicInvocations : const <UniverseSelector>[];
-  }
-
-  void registerDynamicSetter(UniverseSelector selector) {
-    assert(selector != null);
-    if (_dynamicSetters == null) {
-      _dynamicSetters = new Setlet<UniverseSelector>();
-    }
-    _dynamicSetters.add(selector);
-  }
-
-  @override
-  Iterable<UniverseSelector> get dynamicSetters {
-    return _dynamicSetters != null
-        ? _dynamicSetters : const <UniverseSelector>[];
-  }
-
-  void registerInstantiatedType(InterfaceType type) {
-    assert(type != null);
-    if (_instantiatedTypes == null) {
-      _instantiatedTypes = new Setlet<InterfaceType>();
-    }
-    _instantiatedTypes.add(type);
-  }
-
-  @override
-  Iterable<InterfaceType> get instantiatedTypes {
-    return _instantiatedTypes != null
-        ? _instantiatedTypes : const <InterfaceType>[];
-  }
-
-  void registerTypeLiteral(DartType type) {
-    assert(type != null);
-    if (_typeLiterals == null) {
-      _typeLiterals = new Setlet<DartType>();
-    }
-    _typeLiterals.add(type);
-  }
-
-  @override
-  Iterable<DartType> get typeLiterals {
-    return _typeLiterals != null
-        ? _typeLiterals : const <DartType>[];
-  }
-
-  void registerRequiredType(DartType type) {
-    assert(type != null);
-    if (_requiredTypes == null) {
-      _requiredTypes = new Setlet<DartType>();
-    }
-    _requiredTypes.add(type);
-  }
-
-  @override
-  Iterable<DartType> get requiredTypes {
-    return _requiredTypes != null
-        ? _requiredTypes : const <DartType>[];
-  }
+  _ResolutionWorldImpact(this.name);
 
   void registerMapLiteral(MapLiteralUse mapLiteralUse) {
     assert(mapLiteralUse != null);
@@ -228,85 +82,6 @@
         ? _listLiterals : const <ListLiteralUse>[];
   }
 
-  void registerStaticUse(Element element) {
-    assert(element != null);
-    if (_staticUses == null) {
-      _staticUses = new Setlet<Element>();
-    }
-    _staticUses.add(element);
-  }
-
-  @override
-  Iterable<Element> get staticUses {
-    return _staticUses != null ? _staticUses : const <Element>[];
-  }
-
-  void registerIsCheck(DartType type) {
-    assert(type != null);
-    if (_isChecks == null) {
-      _isChecks = new Setlet<DartType>();
-    }
-    _isChecks.add(type);
-  }
-
-  @override
-  Iterable<DartType> get isChecks {
-    return _isChecks != null
-        ? _isChecks : const <DartType>[];
-  }
-
-  void registerAsCast(DartType type) {
-    if (_asCasts == null) {
-      _asCasts = new Setlet<DartType>();
-    }
-    _asCasts.add(type);
-  }
-
-  @override
-  Iterable<DartType> get asCasts {
-    return _asCasts != null
-        ? _asCasts : const <DartType>[];
-  }
-
-  void registerCheckedModeCheckedType(DartType type) {
-    if (_checkedModeChecks == null) {
-      _checkedModeChecks = new Setlet<DartType>();
-    }
-    _checkedModeChecks.add(type);
-  }
-
-  @override
-  Iterable<DartType> get checkedModeChecks {
-    return _checkedModeChecks != null
-        ? _checkedModeChecks : const <DartType>[];
-  }
-
-  void registerClosurizedFunction(MethodElement element) {
-    if (_closurizedFunctions == null) {
-      _closurizedFunctions = new Setlet<MethodElement>();
-    }
-    _closurizedFunctions.add(element);
-  }
-
-  @override
-  Iterable<MethodElement> get closurizedFunctions {
-    return _closurizedFunctions != null
-        ? _closurizedFunctions : const <MethodElement>[];
-  }
-
-  void registerClosure(LocalFunctionElement element) {
-    if (_closures == null) {
-      _closures = new Setlet<LocalFunctionElement>();
-    }
-    _closures.add(element);
-  }
-
-  @override
-  Iterable<LocalFunctionElement> get closures {
-    return _closures != null
-        ? _closures : const <LocalFunctionElement>[];
-  }
-
   void registerConstSymbolName(String name) {
     if (_constSymbolNames == null) {
       _constSymbolNames = new Setlet<String>();
@@ -332,7 +107,19 @@
     return _features != null ? _features : const <Feature>[];
   }
 
-  String toString() => '$registry';
+  void registerConstantLiteral(ConstantExpression constant) {
+    if (_constantLiterals == null) {
+      _constantLiterals = new Setlet<ConstantExpression>();
+    }
+    _constantLiterals.add(constant);
+  }
+
+  Iterable<ConstantExpression> get constantLiterals {
+    return _constantLiterals != null
+        ? _constantLiterals : const <ConstantExpression>[];
+  }
+
+  String toString() => '_ResolutionWorldImpact($name)';
 }
 
 /// [ResolutionRegistry] collects all resolution information. It stores node
@@ -347,7 +134,8 @@
   ResolutionRegistry(Compiler compiler, TreeElementMapping mapping)
       : this.compiler = compiler,
         this.mapping = mapping,
-        this.worldImpact = new _ResolutionWorldImpact(compiler, mapping);
+        this.worldImpact = new _ResolutionWorldImpact(
+            mapping.analyzedElement.toString());
 
   bool get isForResolution => true;
 
@@ -407,8 +195,6 @@
     mapping.setSelector(node, selector);
   }
 
-  Selector getSelector(Node node) => mapping.getSelector(node);
-
   void setGetterSelectorInComplexSendSet(SendSet node, Selector selector) {
     mapping.setGetterSelectorInComplexSendSet(node, selector);
   }
@@ -417,18 +203,6 @@
     mapping.setOperatorSelectorInComplexSendSet(node, selector);
   }
 
-  void setIteratorSelector(ForIn node, Selector selector) {
-    mapping.setIteratorSelector(node, selector);
-  }
-
-  void setMoveNextSelector(ForIn node, Selector selector) {
-    mapping.setMoveNextSelector(node, selector);
-  }
-
-  void setCurrentSelector(ForIn node, Selector selector) {
-    mapping.setCurrentSelector(node, selector);
-  }
-
   //////////////////////////////////////////////////////////////////////////////
   //  Node-to-Type mapping functionality.
   //////////////////////////////////////////////////////////////////////////////
@@ -527,83 +301,26 @@
   //  Various Backend/Enqueuer/World registration.
   //////////////////////////////////////////////////////////////////////////////
 
-  void registerStaticUse(Element element) {
-    worldImpact.registerStaticUse(element);
-  }
-
-  void registerImplicitSuperCall(FunctionElement superConstructor) {
-    registerDependency(superConstructor);
-  }
-
-  // TODO(johnniwinther): Remove this.
-  // Use [registerInstantiatedType] of `rawType` instead.
-  @deprecated
-  void registerInstantiatedClass(ClassElement element) {
-    element.ensureResolved(compiler.resolution);
-    registerInstantiatedType(element.rawType);
-  }
-
-  void registerLazyField() {
-    worldImpact.registerFeature(Feature.LAZY_FIELD);
+  void registerStaticUse(StaticUse staticUse) {
+    worldImpact.registerStaticUse(staticUse);
   }
 
   void registerMetadataConstant(MetadataAnnotation metadata) {
     backend.registerMetadataConstant(metadata, metadata.annotatedElement, this);
   }
 
-  void registerThrowRuntimeError() {
-    worldImpact.registerFeature(Feature.THROW_RUNTIME_ERROR);
-  }
-
-  void registerCompileTimeError(ErroneousElement error) {
-    worldImpact.registerFeature(Feature.COMPILE_TIME_ERROR);
-  }
-
-  void registerTypeVariableBoundCheck() {
-    worldImpact.registerFeature(Feature.TYPE_VARIABLE_BOUNDS_CHECK);
-  }
-
-  void registerThrowNoSuchMethod() {
-    worldImpact.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-  }
-
-  /// Register a checked mode check against [type].
-  void registerCheckedModeCheck(DartType type) {
-    worldImpact.registerCheckedModeCheckedType(type);
-    mapping.addRequiredType(type);
-  }
-
-  /// Register an is-test or is-not-test of [type].
-  void registerIsCheck(DartType type) {
-    worldImpact.registerIsCheck(type);
-    mapping.addRequiredType(type);
-  }
-
-  /// Register an as-cast of [type].
-  void registerAsCast(DartType type) {
-    worldImpact.registerAsCast(type);
-    mapping.addRequiredType(type);
-  }
-
-  void registerClosure(LocalFunctionElement element) {
-    worldImpact.registerClosure(element);
+  /// Register the use of a type.
+  void registerTypeUse(TypeUse typeUse) {
+    worldImpact.registerTypeUse(typeUse);
   }
 
   void registerSuperUse(Node node) {
     mapping.addSuperUse(node);
   }
 
-  void registerDynamicInvocation(UniverseSelector selector) {
-    worldImpact.registerDynamicInvocation(selector);
-  }
-
-  void registerSuperNoSuchMethod() {
-    worldImpact.registerFeature(Feature.SUPER_NO_SUCH_METHOD);
-  }
-
   void registerTypeLiteral(Send node, DartType type) {
     mapping.setType(node, type);
-    worldImpact.registerTypeLiteral(type);
+    worldImpact.registerTypeUse(new TypeUse.typeLiteral(type));
   }
 
   void registerLiteralList(Node node,
@@ -633,60 +350,20 @@
         new ForeignResolutionResolver(visitor, this));
   }
 
-  void registerGetOfStaticFunction(FunctionElement element) {
-    worldImpact.registerClosurizedFunction(element);
+  void registerDynamicUse(DynamicUse dynamicUse) {
+    worldImpact.registerDynamicUse(dynamicUse);
   }
 
-  void registerDynamicGetter(UniverseSelector selector) {
-    assert(selector.selector.isGetter);
-    worldImpact.registerDynamicGetter(selector);
-  }
-
-  void registerDynamicSetter(UniverseSelector selector) {
-    assert(selector.selector.isSetter);
-    worldImpact.registerDynamicSetter(selector);
+  void registerFeature(Feature feature) {
+    worldImpact.registerFeature(feature);
   }
 
   void registerConstSymbol(String name) {
     worldImpact.registerConstSymbolName(name);
   }
 
-  void registerSymbolConstructor() {
-    worldImpact.registerFeature(Feature.SYMBOL_CONSTRUCTOR);
-  }
-
-  void registerInstantiatedType(InterfaceType type) {
-    worldImpact.registerInstantiatedType(type);
-    mapping.addRequiredType(type);
-  }
-
-  void registerAbstractClassInstantiation() {
-    worldImpact.registerFeature(Feature.ABSTRACT_CLASS_INSTANTIATION);
-  }
-
-  void registerRequiredType(DartType type, Element enclosingElement) {
-    worldImpact.registerRequiredType(type);
-    mapping.addRequiredType(type);
-  }
-
-  void registerStringInterpolation() {
-    worldImpact.registerFeature(Feature.STRING_INTERPOLATION);
-  }
-
-  void registerFallThroughError() {
-    worldImpact.registerFeature(Feature.FALL_THROUGH_ERROR);
-  }
-
-  void registerCatchStatement() {
-    worldImpact.registerFeature(Feature.CATCH_STATEMENT);
-  }
-
-  void registerStackTraceInCatch() {
-    worldImpact.registerFeature(Feature.STACK_TRACE_IN_CATCH);
-  }
-
-  void registerSyncForIn(Node node) {
-    worldImpact.registerFeature(Feature.SYNC_FOR_IN);
+  void registerConstantLiteral(ConstantExpression constant) {
+    worldImpact.registerConstantLiteral(constant);
   }
 
   ClassElement defaultSuperclass(ClassElement element) {
@@ -698,60 +375,24 @@
     universe.registerMixinUse(mixinApplication, mixin);
   }
 
-  void registerThrowExpression() {
-    worldImpact.registerFeature(Feature.THROW_EXPRESSION);
-  }
-
-  void registerStaticInvocation(Element element) {
-    // TODO(johnniwinther): Increase precision of [registerStaticUse] and
-    // [registerDependency].
-    if (element == null) return;
-    registerStaticUse(element);
-  }
-
   void registerInstantiation(InterfaceType type) {
-    registerInstantiatedType(type);
-  }
-
-  void registerAssert(bool hasMessage) {
-    worldImpact.registerFeature(
-        hasMessage ? Feature.ASSERT_WITH_MESSAGE : Feature.ASSERT);
+    worldImpact.registerTypeUse(new TypeUse.instantiation(type));
   }
 
   void registerSendStructure(Send node, SendStructure sendStructure) {
     mapping.setSendStructure(node, sendStructure);
   }
 
+  void registerNewStructure(NewExpression node, NewStructure newStructure) {
+    mapping.setNewStructure(node, newStructure);
+  }
+
   // TODO(johnniwinther): Remove this when [SendStructure]s are part of the
   // [ResolutionResult].
   SendStructure getSendStructure(Send node) {
     return mapping.getSendStructure(node);
   }
 
-  void registerAsyncMarker(FunctionElement element) {
-    switch (element.asyncMarker) {
-      case AsyncMarker.SYNC:
-        break;
-      case AsyncMarker.SYNC_STAR:
-        worldImpact.registerFeature(Feature.SYNC_STAR);
-        break;
-      case AsyncMarker.ASYNC:
-        worldImpact.registerFeature(Feature.ASYNC);
-        break;
-      case AsyncMarker.ASYNC_STAR:
-        worldImpact.registerFeature(Feature.ASYNC_STAR);
-        break;
-    }
-  }
-
-  void registerAsyncForIn(AsyncForIn node) {
-    worldImpact.registerFeature(Feature.ASYNC_FOR_IN);
-  }
-
-  void registerIncDecOperation() {
-    worldImpact.registerFeature(Feature.INC_DEC_OPERATION);
-  }
-
   void registerTryStatement() {
     mapping.containsTryStatement = true;
   }
@@ -770,7 +411,7 @@
 
   @override
   void registerInstantiatedType(InterfaceType type) {
-    registry.registerInstantiatedType(type);
+    registry.registerInstantiation(type);
   }
 
   @override
diff --git a/pkg/compiler/lib/src/resolution/resolution.dart b/pkg/compiler/lib/src/resolution/resolution.dart
index d0bae84..4490b88 100644
--- a/pkg/compiler/lib/src/resolution/resolution.dart
+++ b/pkg/compiler/lib/src/resolution/resolution.dart
@@ -10,6 +10,7 @@
 import '../common/names.dart' show
     Identifiers;
 import '../common/resolution.dart' show
+    Feature,
     Parsing,
     Resolution,
     ResolutionImpact;
@@ -22,6 +23,9 @@
     ConstantCompiler;
 import '../constants/values.dart' show
     ConstantValue;
+import '../core_types.dart' show
+    CoreClasses,
+    CoreTypes;
 import '../dart_types.dart';
 import '../elements/elements.dart';
 import '../elements/modelx.dart' show
@@ -36,8 +40,6 @@
     ParameterMetadataAnnotation,
     SetterElementX,
     TypedefElementX;
-import '../enqueue.dart' show
-    WorldImpact;
 import '../tokens/token.dart' show
     isBinaryOperator,
     isMinusOperator,
@@ -45,6 +47,13 @@
     isUnaryOperator,
     isUserDefinableOperator;
 import '../tree/tree.dart';
+import '../universe/call_structure.dart' show
+    CallStructure;
+import '../universe/use.dart' show
+    StaticUse,
+    TypeUse;
+import '../universe/world_impact.dart' show
+    WorldImpact;
 import '../util/util.dart' show
     Link,
     LinkBuilder,
@@ -70,9 +79,13 @@
 
   Parsing get parsing => compiler.parsing;
 
+  CoreClasses get coreClasses => compiler.coreClasses;
+
+  CoreTypes get coreTypes => compiler.coreTypes;
+
   ResolutionImpact resolve(Element element) {
     return measure(() {
-      if (Elements.isErroneous(element)) {
+      if (Elements.isMalformed(element)) {
         // TODO(johnniwinther): Add a predicate for this.
         assert(invariant(element, element is! ErroneousElement,
             message: "Element $element expected to have parse errors."));
@@ -87,15 +100,14 @@
         return result;
       }
 
-      ElementKind kind = element.kind;
-      if (identical(kind, ElementKind.GENERATIVE_CONSTRUCTOR) ||
-          identical(kind, ElementKind.FUNCTION) ||
-          identical(kind, ElementKind.GETTER) ||
-          identical(kind, ElementKind.SETTER)) {
+      if (element.isConstructor ||
+          element.isFunction ||
+          element.isGetter ||
+          element.isSetter) {
         return processMetadata(resolveMethodElement(element));
       }
 
-      if (identical(kind, ElementKind.FIELD)) {
+      if (element.isField) {
         return processMetadata(resolveField(element));
       }
       if (element.isClass) {
@@ -123,6 +135,9 @@
     while (redirection != null) {
       // Ensure that we follow redirections through implementation elements.
       redirection = redirection.implementation;
+      if (redirection.isError) {
+        break;
+      }
       if (seen.contains(redirection)) {
         reporter.reportErrorMessage(
             node, MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE);
@@ -138,6 +153,7 @@
                                  ResolutionRegistry registry) {
     DiagnosticReporter reporter = compiler.reporter;
     Resolution resolution = compiler.resolution;
+    CoreClasses coreClasses = compiler.coreClasses;
     FunctionExpression functionExpression = element.node;
     AsyncModifier asyncModifier = functionExpression.asyncModifier;
     if (asyncModifier != null) {
@@ -174,16 +190,18 @@
               {'modifier': element.asyncMarker});
         }
       }
-      registry.registerAsyncMarker(element);
       switch (element.asyncMarker) {
       case AsyncMarker.ASYNC:
-        compiler.futureClass.ensureResolved(resolution);
+        registry.registerFeature(Feature.ASYNC);
+        coreClasses.futureClass.ensureResolved(resolution);
         break;
       case AsyncMarker.ASYNC_STAR:
-        compiler.streamClass.ensureResolved(resolution);
+        registry.registerFeature(Feature.ASYNC_STAR);
+        coreClasses.streamClass.ensureResolved(resolution);
         break;
       case AsyncMarker.SYNC_STAR:
-        compiler.iterableClass.ensureResolved(resolution);
+        registry.registerFeature(Feature.SYNC_STAR);
+        coreClasses.iterableClass.ensureResolved(resolution);
         break;
       }
     }
@@ -192,7 +210,7 @@
   bool _isNativeClassOrExtendsNativeClass(ClassElement classElement) {
     assert(classElement != null);
     while (classElement != null) {
-      if (classElement.isNative) return true;
+      if (compiler.backend.isNative(classElement)) return true;
       classElement = classElement.superclass;
     }
     return false;
@@ -264,7 +282,8 @@
       }
 
       // TODO(9631): support noSuchMethod on native classes.
-      if (Elements.isInstanceMethod(element) &&
+      if (element.isFunction &&
+          element.isInstanceMember &&
           element.name == Identifiers.noSuchMethod_ &&
           _isNativeClassOrExtendsNativeClass(enclosingClass)) {
         reporter.reportErrorMessage(
@@ -297,13 +316,14 @@
           // resolved. This is the only place where the resolver is
           // seeing this element.
           element.computeType(resolution);
-          if (!target.isErroneous) {
-            registry.registerStaticUse(target);
-            registry.registerImplicitSuperCall(target);
+          if (!target.isMalformed) {
+            registry.registerStaticUse(
+                new StaticUse.superConstructorInvoke(
+                    target, CallStructure.NO_ARGS));
           }
           return registry.worldImpact;
         } else {
-          assert(element.isDeferredLoaderGetter || element.isErroneous);
+          assert(element.isDeferredLoaderGetter || element.isMalformed);
           _ensureTreeElements(element);
           return const ResolutionImpact();
         }
@@ -365,7 +385,8 @@
       reporter.reportErrorMessage(
           element, MessageKind.FINAL_WITHOUT_INITIALIZER);
     } else {
-      registry.registerInstantiatedClass(compiler.nullClass);
+      // TODO(johnniwinther): Register a feature instead.
+      registry.registerTypeUse(new TypeUse.instantiation(coreTypes.nullType));
     }
 
     if (Elements.isStaticOrTopLevelField(element)) {
@@ -380,7 +401,7 @@
         if (!element.modifiers.isConst) {
           // TODO(johnniwinther): Determine the const-ness eagerly to avoid
           // unnecessary registrations.
-          registry.registerLazyField();
+          registry.registerFeature(Feature.LAZY_FIELD);
         }
       }
     }
@@ -415,15 +436,16 @@
     ConstructorElementX target = constructor;
     InterfaceType targetType;
     List<Element> seen = new List<Element>();
+    bool isMalformed = false;
     // Follow the chain of redirections and check for cycles.
     while (target.isRedirectingFactory || target.isPatched) {
-      if (target.internalEffectiveTarget != null) {
+      if (target.effectiveTargetInternal != null) {
         // We found a constructor that already has been processed.
         targetType = target.effectiveTargetType;
         assert(invariant(target, targetType != null,
             message: 'Redirection target type has not been computed for '
                      '$target'));
-        target = target.internalEffectiveTarget;
+        target = target.effectiveTargetInternal;
         break;
       }
 
@@ -438,12 +460,20 @@
         reporter.reportErrorMessage(
             node, MessageKind.CYCLIC_REDIRECTING_FACTORY);
         targetType = target.enclosingClass.thisType;
+        isMalformed = true;
         break;
       }
       seen.add(target);
       target = nextTarget;
     }
 
+    if (target.isGenerativeConstructor && target.enclosingClass.isAbstract) {
+      isMalformed = true;
+    }
+    if (target.isMalformed) {
+      isMalformed = true;
+    }
+
     if (targetType == null) {
       assert(!target.isRedirectingFactory);
       targetType = target.enclosingClass.thisType;
@@ -456,24 +486,18 @@
     // substitution of the target type with respect to the factory type.
     while (!seen.isEmpty) {
       ConstructorElementX factory = seen.removeLast();
-
-      // [factory] must already be analyzed but the [TreeElements] might not
-      // have been stored in the enqueuer cache yet.
-      // TODO(johnniwinther): Store [TreeElements] in the cache before
-      // resolution of the element.
       TreeElements treeElements = factory.treeElements;
       assert(invariant(node, treeElements != null,
           message: 'No TreeElements cached for $factory.'));
       if (!factory.isPatched) {
-        FunctionExpression functionNode = factory.parseNode(parsing);
+        FunctionExpression functionNode = factory.node;
         RedirectingFactoryBody redirectionNode = functionNode.body;
         DartType factoryType = treeElements.getType(redirectionNode);
         if (!factoryType.isDynamic) {
           targetType = targetType.substByContext(factoryType);
         }
       }
-      factory.effectiveTarget = target;
-      factory.effectiveTargetType = targetType;
+      factory.setEffectiveTarget(target, targetType, isMalformed: isMalformed);
     }
   }
 
@@ -494,7 +518,7 @@
         cls.supertypeLoadState = STATE_DONE;
         cls.hasIncompleteHierarchy = true;
         cls.allSupertypesAndSelf =
-            compiler.objectClass.allSupertypesAndSelf.extendClass(
+            coreClasses.objectClass.allSupertypesAndSelf.extendClass(
                 cls.computeType(resolution));
         cls.supertype = cls.allSupertypes.head;
         assert(invariant(from, cls.supertype != null,
@@ -539,7 +563,8 @@
         if (previousResolvedTypeDeclaration == null) {
           do {
             while (!pendingClassesToBeResolved.isEmpty) {
-              pendingClassesToBeResolved.removeFirst().ensureResolved(resolution);
+              pendingClassesToBeResolved.removeFirst()
+                  .ensureResolved(resolution);
             }
             while (!pendingClassesToBePostProcessed.isEmpty) {
               _postProcessClassElement(
@@ -832,7 +857,7 @@
       reporter.internalError(member,
           "No abstract field for accessor");
     } else if (!identical(lookupElement.kind, ElementKind.ABSTRACT_FIELD)) {
-      if (lookupElement.isErroneous || lookupElement.isAmbiguous) return;
+      if (lookupElement.isMalformed || lookupElement.isAmbiguous) return;
       reporter.internalError(member,
           "Inaccessible abstract field for accessor");
     }
diff --git a/pkg/compiler/lib/src/resolution/semantic_visitor.dart b/pkg/compiler/lib/src/resolution/semantic_visitor.dart
index 92db2c4..cb391a3 100644
--- a/pkg/compiler/lib/src/resolution/semantic_visitor.dart
+++ b/pkg/compiler/lib/src/resolution/semantic_visitor.dart
@@ -23,8 +23,10 @@
 
 /// Mixin that couples a [SendResolverMixin] to a [SemanticSendVisitor] in a
 /// [Visitor].
-abstract class SemanticSendResolvedMixin<R, A>
-    implements Visitor<R>, SendResolverMixin {
+abstract class SemanticSendResolvedMixin<R, A> implements Visitor<R> {
+  TreeElements get elements;
+
+  internalError(Spannable spannable, String message);
 
   SemanticSendVisitor<R, A> get sendVisitor;
 
@@ -63,7 +65,7 @@
     // TODO(johnniwinther): Support argument.
     A arg = null;
 
-    NewStructure structure = computeNewStructure(node);
+    NewStructure structure = elements.getNewStructure(node);
     if (structure == null) {
       return internalError(node, 'No structure for $node');
     } else {
@@ -127,7 +129,6 @@
 
 abstract class SemanticVisitor<R, A> extends Visitor<R>
     with SemanticSendResolvedMixin<R, A>,
-         SendResolverMixin,
          SemanticDeclarationResolvedMixin<R, A>,
          DeclarationResolverMixin {
   TreeElements elements;
diff --git a/pkg/compiler/lib/src/resolution/send_resolver.dart b/pkg/compiler/lib/src/resolution/send_resolver.dart
index 479dca0..d592cf4 100644
--- a/pkg/compiler/lib/src/resolution/send_resolver.dart
+++ b/pkg/compiler/lib/src/resolution/send_resolver.dart
@@ -9,137 +9,11 @@
 import '../dart_types.dart';
 import '../elements/elements.dart';
 import '../tree/tree.dart';
-import '../universe/call_structure.dart' show
-    CallStructure;
-import '../universe/selector.dart' show
-    Selector;
 
-import 'access_semantics.dart';
 import 'semantic_visitor.dart';
 import 'send_structure.dart';
 import 'tree_elements.dart';
 
-abstract class SendResolverMixin {
-  TreeElements get elements;
-
-  internalError(Spannable spannable, String message);
-
-  ConstructorAccessSemantics computeConstructorAccessSemantics(
-        ConstructorElement constructor,
-        CallStructure callStructure,
-        DartType type,
-        {bool mustBeConstant: false}) {
-    if (mustBeConstant && !constructor.isConst) {
-      return new ConstructorAccessSemantics(
-          ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR, constructor, type);
-    }
-    if (constructor.isErroneous) {
-      if (constructor is ErroneousElement) {
-        ErroneousElement error = constructor;
-        if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR) {
-          return new ConstructorAccessSemantics(
-              ConstructorAccessKind.UNRESOLVED_CONSTRUCTOR, constructor, type);
-        }
-      }
-      return new ConstructorAccessSemantics(
-          ConstructorAccessKind.UNRESOLVED_TYPE, constructor, type);
-    } else if (constructor.isRedirectingFactory) {
-      ConstructorElement effectiveTarget = constructor.effectiveTarget;
-      if (effectiveTarget == constructor ||
-          effectiveTarget.isErroneous ||
-          (mustBeConstant && !effectiveTarget.isConst)) {
-        return new ConstructorAccessSemantics(
-            ConstructorAccessKind.ERRONEOUS_REDIRECTING_FACTORY,
-            constructor,
-            type);
-      }
-      ConstructorAccessSemantics effectiveTargetSemantics =
-          computeConstructorAccessSemantics(
-              effectiveTarget,
-              callStructure,
-              constructor.computeEffectiveTargetType(type));
-      if (effectiveTargetSemantics.isErroneous) {
-        return new RedirectingFactoryConstructorAccessSemantics(
-            ConstructorAccessKind.ERRONEOUS_REDIRECTING_FACTORY,
-            constructor,
-            type,
-            effectiveTargetSemantics);
-      }
-      return new RedirectingFactoryConstructorAccessSemantics(
-          ConstructorAccessKind.REDIRECTING_FACTORY,
-          constructor,
-          type,
-          effectiveTargetSemantics);
-    } else {
-      if (!callStructure.signatureApplies(constructor.functionSignature)) {
-        return new ConstructorAccessSemantics(
-            ConstructorAccessKind.INCOMPATIBLE,
-            constructor,
-            type);
-      } else if (constructor.isFactoryConstructor) {
-        return new ConstructorAccessSemantics(
-            ConstructorAccessKind.FACTORY, constructor, type);
-      } else if (constructor.isRedirectingGenerative) {
-        if (constructor.enclosingClass.isAbstract) {
-            return new ConstructorAccessSemantics(
-                ConstructorAccessKind.ABSTRACT, constructor, type);
-        }
-        return new ConstructorAccessSemantics(
-            ConstructorAccessKind.REDIRECTING_GENERATIVE, constructor, type);
-      } else if (constructor.enclosingClass.isAbstract) {
-        return new ConstructorAccessSemantics(
-            ConstructorAccessKind.ABSTRACT, constructor, type);
-      } else {
-        return new ConstructorAccessSemantics(
-            ConstructorAccessKind.GENERATIVE, constructor, type);
-      }
-    }
-  }
-
-  NewStructure computeNewStructure(NewExpression node) {
-    Element element = elements[node.send];
-    Selector selector = elements.getSelector(node.send);
-    DartType type = elements.getType(node);
-
-    ConstructorAccessSemantics constructorAccessSemantics =
-        computeConstructorAccessSemantics(
-            element, selector.callStructure, type,
-            mustBeConstant: node.isConst);
-    if (node.isConst) {
-      ConstantExpression constant = elements.getConstant(node);
-      if (constructorAccessSemantics.isErroneous ||
-          constant == null ||
-          constant.kind == ConstantExpressionKind.ERRONEOUS) {
-        // This is a non-constant constant constructor invocation, like
-        // `const Const(method())`.
-        constructorAccessSemantics = new ConstructorAccessSemantics(
-            ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR, element, type);
-      } else {
-        ConstantInvokeKind kind;
-        switch (constant.kind) {
-          case ConstantExpressionKind.CONSTRUCTED:
-            kind = ConstantInvokeKind.CONSTRUCTED;
-            break;
-          case ConstantExpressionKind.BOOL_FROM_ENVIRONMENT:
-            kind = ConstantInvokeKind.BOOL_FROM_ENVIRONMENT;
-            break;
-          case ConstantExpressionKind.INT_FROM_ENVIRONMENT:
-            kind = ConstantInvokeKind.INT_FROM_ENVIRONMENT;
-            break;
-          case ConstantExpressionKind.STRING_FROM_ENVIRONMENT:
-            kind = ConstantInvokeKind.STRING_FROM_ENVIRONMENT;
-            break;
-          default:
-            return internalError(
-                node, "Unexpected constant kind $kind: ${constant.getText()}");
-        }
-        return new ConstInvokeStructure(kind, constant);
-      }
-    }
-    return new NewInvokeStructure(constructorAccessSemantics, selector);
-  }
-}
-
 abstract class DeclStructure<R, A> {
   final FunctionElement element;
 
diff --git a/pkg/compiler/lib/src/resolution/send_structure.dart b/pkg/compiler/lib/src/resolution/send_structure.dart
index 06c58de..5daa7bd 100644
--- a/pkg/compiler/lib/src/resolution/send_structure.dart
+++ b/pkg/compiler/lib/src/resolution/send_structure.dart
@@ -8,6 +8,8 @@
 import '../constants/expressions.dart';
 import '../dart_types.dart';
 import '../elements/elements.dart';
+import '../resolution/tree_elements.dart' show
+    TreeElements;
 import '../tree/tree.dart';
 import '../universe/call_structure.dart' show
     CallStructure;
@@ -2642,22 +2644,45 @@
   R dispatch(SemanticSendVisitor<R, A> visitor, NewExpression node, A arg) {
     switch (semantics.kind) {
       case ConstructorAccessKind.GENERATIVE:
+        ConstructorElement constructor = semantics.element;
+        if (constructor.isRedirectingGenerative) {
+          return visitor.visitRedirectingGenerativeConstructorInvoke(
+              node, constructor, semantics.type,
+              node.send.argumentsNode, callStructure, arg);
+        }
         return visitor.visitGenerativeConstructorInvoke(
-            node, semantics.element, semantics.type,
-            node.send.argumentsNode, callStructure, arg);
-      case ConstructorAccessKind.REDIRECTING_GENERATIVE:
-        return visitor.visitRedirectingGenerativeConstructorInvoke(
-            node, semantics.element, semantics.type,
+            node, constructor, semantics.type,
             node.send.argumentsNode, callStructure, arg);
       case ConstructorAccessKind.FACTORY:
-        return visitor.visitFactoryConstructorInvoke(
-            node, semantics.element, semantics.type,
-            node.send.argumentsNode, callStructure, arg);
-      case ConstructorAccessKind.REDIRECTING_FACTORY:
-        return visitor.visitRedirectingFactoryConstructorInvoke(
-            node, semantics.element, semantics.type,
-            semantics.effectiveTargetSemantics.element,
-            semantics.effectiveTargetSemantics.type,
+        ConstructorElement constructor = semantics.element;
+        if (constructor.isRedirectingFactory) {
+          if (constructor.isEffectiveTargetMalformed) {
+            return visitor.visitUnresolvedRedirectingFactoryConstructorInvoke(
+                node, semantics.element, semantics.type,
+                node.send.argumentsNode, callStructure, arg);
+          }
+          ConstructorElement effectiveTarget = constructor.effectiveTarget;
+          InterfaceType effectiveTargetType =
+              constructor.computeEffectiveTargetType(semantics.type);
+          if (callStructure.signatureApplies(
+                  effectiveTarget.functionSignature)) {
+            return visitor.visitRedirectingFactoryConstructorInvoke(
+                node, semantics.element, semantics.type,
+                effectiveTarget, effectiveTargetType,
+                node.send.argumentsNode, callStructure, arg);
+          } else {
+            return visitor.visitUnresolvedRedirectingFactoryConstructorInvoke(
+                            node, semantics.element, semantics.type,
+                            node.send.argumentsNode, callStructure, arg);
+          }
+        }
+        if (callStructure.signatureApplies(constructor.functionSignature)) {
+          return visitor.visitFactoryConstructorInvoke(
+              node, constructor, semantics.type,
+              node.send.argumentsNode, callStructure, arg);
+        }
+        return visitor.visitConstructorIncompatibleInvoke(
+            node, constructor, semantics.type,
             node.send.argumentsNode, callStructure, arg);
       case ConstructorAccessKind.ABSTRACT:
         return visitor.visitAbstractClassConstructorInvoke(
@@ -2675,10 +2700,6 @@
         return visitor.errorNonConstantConstructorInvoke(
             node, semantics.element, semantics.type,
             node.send.argumentsNode, callStructure, arg);
-      case ConstructorAccessKind.ERRONEOUS_REDIRECTING_FACTORY:
-        return visitor.visitUnresolvedRedirectingFactoryConstructorInvoke(
-            node, semantics.element, semantics.type,
-            node.send.argumentsNode, callStructure, arg);
       case ConstructorAccessKind.INCOMPATIBLE:
         return visitor.visitConstructorIncompatibleInvoke(
             node, semantics.element, semantics.type,
@@ -2723,6 +2744,50 @@
   }
 }
 
+/// A constant constructor invocation that couldn't be determined fully during
+/// resolution.
+// TODO(johnniwinther): Remove this when all constants are computed during
+// resolution.
+class LateConstInvokeStructure<R, A> extends NewStructure<R, A> {
+  final TreeElements elements;
+
+  LateConstInvokeStructure(this.elements);
+
+  R dispatch(SemanticSendVisitor<R, A> visitor, NewExpression node, A arg) {
+    Element element = elements[node.send];
+    Selector selector = elements.getSelector(node.send);
+    DartType type = elements.getType(node);
+    ConstantExpression constant = elements.getConstant(node);
+    if (element.isMalformed ||
+        constant == null ||
+        constant.kind == ConstantExpressionKind.ERRONEOUS) {
+      // This is a non-constant constant constructor invocation, like
+      // `const Const(method())`.
+      return visitor.errorNonConstantConstructorInvoke(
+          node, element, type,
+          node.send.argumentsNode, selector.callStructure, arg);
+    } else {
+      ConstantInvokeKind kind;
+      switch (constant.kind) {
+        case ConstantExpressionKind.CONSTRUCTED:
+          return visitor.visitConstConstructorInvoke(node, constant, arg);
+        case ConstantExpressionKind.BOOL_FROM_ENVIRONMENT:
+          return visitor.visitBoolFromEnvironmentConstructorInvoke(
+              node, constant, arg);
+        case ConstantExpressionKind.INT_FROM_ENVIRONMENT:
+          return visitor.visitIntFromEnvironmentConstructorInvoke(
+              node, constant, arg);
+        case ConstantExpressionKind.STRING_FROM_ENVIRONMENT:
+          return visitor.visitStringFromEnvironmentConstructorInvoke(
+              node, constant, arg);
+        default:
+          throw new SpannableAssertionFailure(
+              node, "Unexpected constant kind $kind: ${constant.getText()}");
+      }
+    }
+  }
+}
+
 /// The structure of a parameter declaration.
 abstract class ParameterStructure<R, A> {
   final VariableDefinitions definitions;
diff --git a/pkg/compiler/lib/src/resolution/signatures.dart b/pkg/compiler/lib/src/resolution/signatures.dart
index 41f3033..df165a6 100644
--- a/pkg/compiler/lib/src/resolution/signatures.dart
+++ b/pkg/compiler/lib/src/resolution/signatures.dart
@@ -18,6 +18,8 @@
     InitializingFormalElementX,
     LocalParameterElementX;
 import '../tree/tree.dart';
+import '../universe/use.dart' show
+    TypeUse;
 import '../util/util.dart' show
     Link,
     LinkBuilder;
@@ -310,7 +312,7 @@
     int requiredParameterCount = 0;
     if (formalParameters == null) {
       if (!element.isGetter) {
-        if (element.isErroneous) {
+        if (element.isMalformed) {
           // If the element is erroneous, an error should already have been
           // reported. In the case of parse errors, it is possible that there
           // are formal parameters, but something else in the method failed to
@@ -341,7 +343,7 @@
       // Because there is no type annotation for the return type of
       // this element, we explicitly add one.
       if (compiler.enableTypeAssertions) {
-        registry.registerIsCheck(returnType);
+        registry.registerTypeUse(new TypeUse.checkedModeCheck(returnType));
       }
     } else {
       AsyncMarker asyncMarker = AsyncMarker.SYNC;
diff --git a/pkg/compiler/lib/src/resolution/tree_elements.dart b/pkg/compiler/lib/src/resolution/tree_elements.dart
index 8d3071c..e04b537 100644
--- a/pkg/compiler/lib/src/resolution/tree_elements.dart
+++ b/pkg/compiler/lib/src/resolution/tree_elements.dart
@@ -24,17 +24,16 @@
   AnalyzableElement get analyzedElement;
   Iterable<Node> get superUses;
 
-  /// The set of types that this TreeElement depends on.
-  /// This includes instantiated types, types in is-checks and as-expressions
-  /// and in checked mode the types of all type-annotations.
-  Iterable<DartType> get requiredTypes;
-
   void forEachConstantNode(f(Node n, ConstantExpression c));
 
   Element operator[](Node node);
   Map<Node, DartType> get typesCache;
 
-  SendStructure getSendStructure(Send send);
+  /// Returns the [SendStructure] that describes the semantics of [node].
+  SendStructure getSendStructure(Send node);
+
+  /// Returns the [NewStructure] that describes the semantics of [node].
+  NewStructure getNewStructure(NewExpression node);
 
   // TODO(johnniwinther): Investigate whether [Node] could be a [Send].
   Selector getSelector(Node node);
@@ -50,9 +49,6 @@
 
   /// Returns the for-in loop variable for [node].
   Element getForInVariable(ForIn node);
-  Selector getIteratorSelector(ForIn node);
-  Selector getMoveNextSelector(ForIn node);
-  Selector getCurrentSelector(ForIn node);
   TypeMask getIteratorTypeMask(ForIn node);
   TypeMask getMoveNextTypeMask(ForIn node);
   TypeMask getCurrentTypeMask(ForIn node);
@@ -80,9 +76,6 @@
   /// Returns the type that the type literal [node] refers to.
   DartType getTypeLiteralType(Send node);
 
-  /// Register a dependency on [type].
-  void addRequiredType(DartType type);
-
   /// Returns a list of nodes that potentially mutate [element] anywhere in its
   /// scope.
   List<Node> getPotentialMutations(VariableElement element);
@@ -125,7 +118,7 @@
   Map<VariableElement, List<Node>> _potentiallyMutatedInClosure;
   Map<Node, Map<VariableElement, List<Node>>> _accessedByClosureIn;
   Maplet<Send, SendStructure> _sendStructureMap;
-  Setlet<DartType> _requiredTypes;
+  Maplet<NewExpression, NewStructure> _newStructureMap;
   bool containsTryStatement = false;
 
   /// Map from nodes to the targets they define.
@@ -149,7 +142,7 @@
     // TODO(johnniwinther): Simplify this invariant to use only declarations in
     // [TreeElements].
     assert(invariant(node, () {
-      if (!element.isErroneous && analyzedElement != null && element.isPatch) {
+      if (!element.isMalformed && analyzedElement != null && element.isPatch) {
         return analyzedElement.implementationLibrary.isPatch;
       }
       return true;
@@ -165,16 +158,28 @@
 
   operator [](Node node) => getTreeElement(node);
 
-  SendStructure getSendStructure(Send send) {
+  SendStructure getSendStructure(Send node) {
     if (_sendStructureMap == null) return null;
-    return _sendStructureMap[send];
+    return _sendStructureMap[node];
   }
 
-  void setSendStructure(Send send, SendStructure sendStructure) {
+  void setSendStructure(Send node, SendStructure sendStructure) {
     if (_sendStructureMap == null) {
       _sendStructureMap = new Maplet<Send, SendStructure>();
     }
-    _sendStructureMap[send] = sendStructure;
+    _sendStructureMap[node] = sendStructure;
+  }
+
+  NewStructure getNewStructure(NewExpression node) {
+    if (_newStructureMap == null) return null;
+    return _newStructureMap[node];
+  }
+
+  void setNewStructure(NewExpression node, NewStructure newStructure) {
+    if (_newStructureMap == null) {
+      _newStructureMap = new Maplet<NewExpression, NewStructure>();
+    }
+    _newStructureMap[node] = newStructure;
   }
 
   void setType(Node node, DartType type) {
@@ -186,19 +191,6 @@
 
   DartType getType(Node node) => _types != null ? _types[node] : null;
 
-  void addRequiredType(DartType type) {
-    if (_requiredTypes == null) _requiredTypes = new Setlet<DartType>();
-    _requiredTypes.add(type);
-  }
-
-  Iterable<DartType> get requiredTypes {
-    if (_requiredTypes == null) {
-      return const <DartType>[];
-    } else {
-      return _requiredTypes;
-    }
-  }
-
   Iterable<Node> get superUses {
     return _superUses != null ? _superUses : const <Node>[];
   }
@@ -245,34 +237,6 @@
     return _getSelector(node.assignmentOperator);
   }
 
-  // The following methods set selectors on the "for in" node. Since
-  // we're using three selectors, we need to use children of the node,
-  // and we arbitrarily choose which ones.
-
-  void setIteratorSelector(ForIn node, Selector selector) {
-    _setSelector(node, selector);
-  }
-
-  Selector getIteratorSelector(ForIn node) {
-    return _getSelector(node);
-  }
-
-  void setMoveNextSelector(ForIn node, Selector selector) {
-    _setSelector(node.forToken, selector);
-  }
-
-  Selector getMoveNextSelector(ForIn node) {
-    return _getSelector(node.forToken);
-  }
-
-  void setCurrentSelector(ForIn node, Selector selector) {
-    _setSelector(node.inToken, selector);
-  }
-
-  Selector getCurrentSelector(ForIn node) {
-    return _getSelector(node.inToken);
-  }
-
   Element getForInVariable(ForIn node) {
     return this[node];
   }
diff --git a/pkg/compiler/lib/src/resolution/type_resolver.dart b/pkg/compiler/lib/src/resolution/type_resolver.dart
index 3c6ab75..165790d 100644
--- a/pkg/compiler/lib/src/resolution/type_resolver.dart
+++ b/pkg/compiler/lib/src/resolution/type_resolver.dart
@@ -6,6 +6,7 @@
 
 import '../common.dart';
 import '../common/resolution.dart' show
+    Feature,
     Resolution;
 import '../compiler.dart' show
     Compiler;
@@ -136,13 +137,13 @@
             reporter.createMessage(node, messageKind, messageArguments),
             infos);
       } else {
-        registry.registerThrowRuntimeError();
+        registry.registerFeature(Feature.THROW_RUNTIME_ERROR);
         reporter.reportWarning(
             reporter.createMessage(node, messageKind, messageArguments),
             infos);
       }
       if (erroneousElement == null) {
-        registry.registerThrowRuntimeError();
+        registry.registerFeature(Feature.THROW_RUNTIME_ERROR);
         erroneousElement = new ErroneousElementX(
             messageKind, messageArguments, typeName.source,
             visitor.enclosingElement);
@@ -165,7 +166,7 @@
           infos: ambiguous.computeInfos(
               registry.mapping.analyzedElement, reporter));
       ;
-    } else if (element.isErroneous) {
+    } else if (element.isMalformed) {
       if (element is ErroneousElement) {
         type = reportFailureAndCreateType(
             element.messageKind, element.messageArguments,
@@ -226,7 +227,7 @@
         if (!outer.isClass &&
             !outer.isTypedef &&
             !Elements.hasAccessToTypeVariables(visitor.enclosingElement)) {
-          registry.registerThrowRuntimeError();
+          registry.registerFeature(Feature.THROW_RUNTIME_ERROR);
           type = reportFailureAndCreateType(
               MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
               {'typeVariableName': node},
@@ -240,7 +241,7 @@
             "Unexpected element kind ${element.kind}.");
       }
       if (addTypeVariableBoundsCheck) {
-        registry.registerTypeVariableBoundCheck();
+        registry.registerFeature(Feature.TYPE_VARIABLE_BOUNDS_CHECK);
         visitor.addDeferredAction(
             visitor.enclosingElement,
             () => checkTypeVariableBounds(node, type));
diff --git a/pkg/compiler/lib/src/resolution/variables.dart b/pkg/compiler/lib/src/resolution/variables.dart
index e9d6b94..6f22eed 100644
--- a/pkg/compiler/lib/src/resolution/variables.dart
+++ b/pkg/compiler/lib/src/resolution/variables.dart
@@ -11,6 +11,8 @@
     LocalVariableElementX,
     VariableList;
 import '../tree/tree.dart';
+import '../universe/use.dart' show
+    TypeUse;
 import '../util/util.dart' show
     Link;
 
@@ -54,7 +56,9 @@
 
   Identifier visitIdentifier(Identifier node) {
     // The variable is initialized to null.
-    registry.registerInstantiatedClass(compiler.nullClass);
+    // TODO(johnniwinther): Register a feature instead.
+    registry.registerTypeUse(
+        new TypeUse.instantiation(compiler.coreTypes.nullType));
     if (definitions.modifiers.isConst) {
       reporter.reportErrorMessage(
           node, MessageKind.CONST_WITHOUT_INITIALIZER);
diff --git a/pkg/compiler/lib/src/serialization/modelz.dart b/pkg/compiler/lib/src/serialization/modelz.dart
index 86d27901..07cf4e6 100644
--- a/pkg/compiler/lib/src/serialization/modelz.dart
+++ b/pkg/compiler/lib/src/serialization/modelz.dart
@@ -51,9 +51,6 @@
 }
 
 abstract class ElementZ extends Element with ElementCommon {
-  @override
-  bool get isFactoryConstructor => false;
-
   String toString() {
     if (enclosingElement == null || isTopLevel) return 'Z$kind($name)';
     return 'Z$kind(${enclosingElement.name}#$name)';
@@ -1006,10 +1003,7 @@
       : super(decoder);
 
   @override
-  ElementKind get kind => ElementKind.FUNCTION;
-
-  @override
-  bool get isFactoryConstructor => true;
+  ElementKind get kind => ElementKind.FACTORY_CONSTRUCTOR;
 }
 
 abstract class MemberElementMixin
diff --git a/pkg/compiler/lib/src/serialization/task.dart b/pkg/compiler/lib/src/serialization/task.dart
index 2b86c5e..551ba49 100644
--- a/pkg/compiler/lib/src/serialization/task.dart
+++ b/pkg/compiler/lib/src/serialization/task.dart
@@ -14,7 +14,8 @@
     Compiler;
 import '../elements/elements.dart';
 import '../enqueue.dart' show
-    ResolutionEnqueuer,
+    ResolutionEnqueuer;
+import '../universe/world_impact.dart' show
     WorldImpact;
 
 /// Task that supports deserialization of elements.
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index 0258d7d..0945568 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -353,7 +353,7 @@
     // Instead of allocating and initializing the object, the constructor
     // 'upgrades' the native subclass object by initializing the Dart fields.
     bool isNativeUpgradeFactory = element.isGenerativeConstructor
-        && Elements.isNativeOrExtendsNative(cls);
+        && backend.isNativeOrExtendsNative(cls);
     if (backend.isInterceptedMethod(element)) {
       bool isInterceptorClass = backend.isInterceptorClass(cls.declaration);
       String name = isInterceptorClass ? 'receiver' : '_';
@@ -973,7 +973,6 @@
 class SsaBuilder extends ast.Visitor
     with BaseImplementationOfCompoundsMixin,
          BaseImplementationOfSetIfNullsMixin,
-         SendResolverMixin,
          SemanticSendResolvedMixin,
          NewBulkMixin,
          ErrorBulkMixin
@@ -1118,6 +1117,8 @@
 
   DiagnosticReporter get reporter => compiler.reporter;
 
+  CoreClasses get coreClasses => compiler.coreClasses;
+
   @override
   SemanticSendVisitor get sendVisitor => this;
 
@@ -1145,18 +1146,18 @@
   HGraph build() {
     assert(invariant(target, target.isImplementation));
     HInstruction.idCounter = 0;
-    ElementKind kind = target.kind;
     // TODO(sigmund): remove `result` and return graph directly, need to ensure
     // that it can never be null (see result in buildFactory for instance).
     var result;
-    if (kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
+    if (target.isGenerativeConstructor) {
       result = buildFactory(target);
-    } else if (kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY ||
-               kind == ElementKind.FUNCTION ||
-               kind == ElementKind.GETTER ||
-               kind == ElementKind.SETTER) {
+    } else if (target.isGenerativeConstructorBody ||
+               target.isFactoryConstructor ||
+               target.isFunction ||
+               target.isGetter ||
+               target.isSetter) {
       result = buildMethod(target);
-    } else if (kind == ElementKind.FIELD) {
+    } else if (target.isField) {
       if (target.isInstanceMember) {
         assert(compiler.enableTypeAssertions);
         result = buildCheckedSetter(target);
@@ -1164,7 +1165,7 @@
         result = buildLazyInitializer(target);
       }
     } else {
-      reporter.internalError(target, 'Unexpected element kind $kind.');
+      reporter.internalError(target, 'Unexpected element kind $target.');
     }
     assert(result.isValid());
     return result;
@@ -1339,7 +1340,7 @@
     // enqueued.
     backend.registerStaticUse(element, compiler.enqueuer.codegen);
 
-    if (element.isJsInterop && !element.isFactoryConstructor) {
+    if (backend.isJsInterop(element) && !element.isFactoryConstructor) {
       // We only inline factory JavaScript interop constructors.
       return false;
     }
@@ -1374,11 +1375,11 @@
         }
       }
 
-      if (element.isJsInterop) return false;
+      if (backend.isJsInterop(element)) return false;
 
       // Don't inline operator== methods if the parameter can be null.
       if (element.name == '==') {
-        if (element.enclosingClass != compiler.objectClass
+        if (element.enclosingClass != coreClasses.objectClass
             && providedArguments[1].canBeNull()) {
           return false;
         }
@@ -1387,7 +1388,7 @@
       // Generative constructors of native classes should not be called directly
       // and have an extra argument that causes problems with inlining.
       if (element.isGenerativeConstructor
-          && Elements.isNativeOrExtendsNative(element.enclosingClass)) {
+          && backend.isNativeOrExtendsNative(element.enclosingClass)) {
         return false;
       }
 
@@ -1651,7 +1652,7 @@
     assert(elements.getFunctionDefinition(function) != null);
     openFunction(functionElement, function);
     String name = functionElement.name;
-    if (functionElement.isJsInterop) {
+    if (backend.isJsInterop(functionElement)) {
       push(invokeJsInteropFunction(functionElement, parameters.values.toList(),
           sourceInformationBuilder.buildGeneric(function)));
       var value = pop();
@@ -1689,7 +1690,7 @@
           p.instructionType.isEmpty && !p.instructionType.isNullable);
       if (emptyParameters.length > 0) {
         addComment('${emptyParameters} inferred as [empty]');
-        pushInvokeStatic(function.body, backend.assertUnreachableMethod, []);
+        pushInvokeStatic(function.body, helpers.assertUnreachableMethod, []);
         pop();
         return closeFunction();
       }
@@ -2022,7 +2023,7 @@
       }
 
       Element target = constructor.definingConstructor.implementation;
-      bool match = !target.isErroneous &&
+      bool match = !target.isMalformed &&
           CallStructure.addForwardingElementArgumentsToList(
               constructor,
               arguments,
@@ -2136,7 +2137,7 @@
             if (initializer == null) {
               // Unassigned fields of native classes are not initialized to
               // prevent overwriting pre-initialized native properties.
-              if (!Elements.isNativeOrExtendsNative(classElement)) {
+              if (!backend.isNativeOrExtendsNative(classElement)) {
                 fieldValues[member] = graph.addConstantNull(compiler);
               }
             } else {
@@ -2169,8 +2170,8 @@
     ClassElement classElement =
         functionElement.enclosingClass.implementation;
     bool isNativeUpgradeFactory =
-        Elements.isNativeOrExtendsNative(classElement)
-            && !classElement.isJsInterop;
+        backend.isNativeOrExtendsNative(classElement)
+            && !backend.isJsInterop(classElement);
     ast.FunctionExpression function = functionElement.node;
     // Note that constructors (like any other static function) do not need
     // to deal with optional arguments. It is the callers job to provide all
@@ -2559,7 +2560,7 @@
       pushInvokeDynamic(
           null,
           new Selector.call(
-              new Name(name, backend.jsHelperLibrary), CallStructure.ONE_ARG),
+              new Name(name, helpers.jsHelperLibrary), CallStructure.ONE_ARG),
           null,
           arguments);
 
@@ -2576,9 +2577,9 @@
     type = type.unaliased;
     if (type.isDynamic) return original;
     if (!type.isInterfaceType) return original;
+    if (type.isObject) return original;
     // The type element is either a class or the void element.
     Element element = type.element;
-    if (element == compiler.objectClass) return original;
     TypeMask mask = new TypeMask.subtype(element, compiler.world);
     return new HTypeKnown.pinned(mask, original);
   }
@@ -2588,7 +2589,7 @@
     assert(type != null);
     type = localsHandler.substInContext(type);
     HInstruction other = buildTypeConversion(original, type, kind);
-    registry?.registerIsCheck(type);
+    registry?.registerTypeUse(new TypeUse.isCheck(type));
     return other;
   }
 
@@ -2652,7 +2653,7 @@
     if (_checkOrTrustTypes) {
       return potentiallyCheckOrTrustType(
           value,
-          compiler.boolClass.rawType,
+          compiler.coreTypes.boolType,
           kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK);
     }
     HInstruction result = new HBoolify(value, backend.boolType);
@@ -3234,7 +3235,7 @@
     // TODO(ahe): This should be registered in codegen, not here.
     // TODO(johnniwinther): Is [registerStaticUse] equivalent to
     // [addToWorkList]?
-    registry?.registerStaticUse(callElement);
+    registry?.registerStaticUse(new StaticUse.foreignUse(callElement));
 
     List<HInstruction> capturedVariables = <HInstruction>[];
     closureClassElement.closureFields.forEach((ClosureFieldElement field) {
@@ -3245,7 +3246,7 @@
     });
 
     TypeMask type =
-        new TypeMask.nonNullExact(compiler.functionClass, compiler.world);
+        new TypeMask.nonNullExact(closureClassElement, compiler.world);
     push(new HForeignNew(closureClassElement, type, capturedVariables)
         ..sourceInformation = sourceInformationBuilder.buildCreate(node));
 
@@ -3475,7 +3476,7 @@
       handleInvalidStaticGet(node, element);
     } else {
       // This happens when [element] has parse errors.
-      assert(invariant(node, element == null || element.isErroneous));
+      assert(invariant(node, element == null || element.isMalformed));
       // TODO(ahe): Do something like the above, that is, emit a runtime
       // error.
       stack.add(graph.addConstantNull(compiler));
@@ -3764,13 +3765,11 @@
         addWithPosition(new HStaticStore(element, value), location);
       }
       stack.add(value);
-    } else if (Elements.isErroneous(element)) {
-      if (element is ErroneousElement) {
-        generateNoSuchSetter(location, element,  send == null ? null : value);
-      } else {
-        // TODO(ahe): Do something like [generateWrongArgumentCountError].
-        stack.add(graph.addConstantNull(compiler));
-      }
+    } else if (Elements.isError(element)) {
+      generateNoSuchSetter(location, element,  send == null ? null : value);
+    } else if (Elements.isMalformed(element)) {
+      // TODO(ahe): Do something like [generateWrongArgumentCountError].
+      stack.add(graph.addConstantNull(compiler));
     } else {
       stack.add(value);
       LocalElement local = element;
@@ -3875,7 +3874,7 @@
       pushInvokeDynamic(
           node,
           new Selector.call(
-              new PrivateName('_isTest', backend.jsHelperLibrary),
+              new PrivateName('_isTest', helpers.jsHelperLibrary),
               CallStructure.ONE_ARG),
           null,
           arguments);
@@ -3981,7 +3980,7 @@
         arguments,
         element,
         compileArgument,
-        element.isJsInterop ?
+        backend.isJsInterop(element) ?
             handleConstantForOptionalParameterJsInterop :
             handleConstantForOptionalParameter);
   }
@@ -4155,6 +4154,10 @@
       return;
     }
 
+    if (native.HasCapturedPlaceholders.check(nativeBehavior.codeTemplate.ast)) {
+      reporter.reportErrorMessage(node, MessageKind.JS_PLACEHOLDER_CAPTURE);
+    }
+
     TypeMask ssaType =
         TypeMaskFactory.fromNativeBehavior(nativeBehavior, compiler);
 
@@ -4202,7 +4205,7 @@
       // Call a helper method from the isolate library. The isolate
       // library uses its own isolate structure, that encapsulates
       // Leg's isolate.
-      Element element = backend.isolateHelperLibrary.find('_currentIsolate');
+      Element element = helpers.currentIsolate;
       if (element == null) {
         reporter.internalError(node,
             'Isolate library and compiler mismatch.');
@@ -4277,7 +4280,7 @@
     Element element = elements[argument];
     if (element == null ||
         element is! FieldElement ||
-        element.enclosingClass != backend.jsGetNameEnum) {
+        element.enclosingClass != helpers.jsGetNameEnum) {
       reporter.reportErrorMessage(
           argument, MessageKind.GENERIC,
           {'text': 'Error: Expected a JsGetName enum value.'});
@@ -4302,7 +4305,7 @@
     Element builtinElement = elements[arguments[1]];
     if (builtinElement == null ||
         (builtinElement is! FieldElement) ||
-        builtinElement.enclosingClass != backend.jsBuiltinEnum) {
+        builtinElement.enclosingClass != helpers.jsBuiltinEnum) {
       reporter.reportErrorMessage(
           argument, MessageKind.GENERIC,
           {'text': 'Error: Expected a JsBuiltin enum value.'});
@@ -4411,7 +4414,7 @@
                               backend.dynamicType));
     } else {
       // Call a helper method from the isolate library.
-      Element element = backend.isolateHelperLibrary.find('_callInIsolate');
+      Element element = helpers.callInIsolate;
       if (element == null) {
         reporter.internalError(node,
             'Isolate library and compiler mismatch.');
@@ -4444,10 +4447,11 @@
           '"$name" does not handle closure with optional parameters.');
     }
 
-    registry?.registerStaticUse(element);
+    registry?.registerStaticUse(
+        new StaticUse.foreignUse(function));
     push(new HForeignCode(
         js.js.expressionTemplateYielding(
-            backend.emitter.staticFunctionAccess(element)),
+            backend.emitter.staticFunctionAccess(function)),
         backend.dynamicType,
         <HInstruction>[],
         nativeBehavior: native.NativeBehavior.PURE));
@@ -4545,13 +4549,13 @@
 
     ClassElement cls = currentNonClosureClass;
     Element element = cls.lookupSuperMember(Identifiers.noSuchMethod_);
-    if (compiler.enabledInvokeOn
-        && element.enclosingElement.declaration != compiler.objectClass) {
+    if (compiler.enabledInvokeOn && !element.enclosingClass.isObject) {
       // Register the call as dynamic if [noSuchMethod] on the super
       // class is _not_ the default implementation from [Object], in
       // case the [noSuchMethod] implementation calls
       // [JSInvocationMirror._invokeOn].
-      registry?.registerSelectorUse(selector);
+      // TODO(johnniwinther): Register this more precisely.
+      registry?.registerDynamicUse(new DynamicUse(selector, null));
     }
     String publicName = name;
     if (selector.isSetter) publicName += '=';
@@ -4990,7 +4994,7 @@
       inputs.add(analyzeTypeArgument(argument));
     });
     // TODO(15489): Register at codegen.
-    registry?.registerInstantiatedType(type);
+    registry?.registerInstantiation(type);
     return callSetRuntimeTypeInfo(type.element, inputs, newObject);
   }
 
@@ -5067,13 +5071,19 @@
         TypeMask inferred =
             TypeMaskFactory.inferredForNode(sourceElement, send, compiler);
         ClassElement cls = element.enclosingClass;
-        assert(cls.thisType.element.isNative);
+        assert(backend.isNative(cls.thisType.element));
         return inferred.containsAll(compiler.world)
             ? new TypeMask.nonNullExact(cls.thisType.element, compiler.world)
             : inferred;
       } else if (element.isGenerativeConstructor) {
         ClassElement cls = element.enclosingClass;
-        return new TypeMask.nonNullExact(cls.thisType.element, compiler.world);
+        if (cls.isAbstract) {
+          // An error will be thrown.
+          return new TypeMask.nonNullEmpty();
+        } else {
+          return new TypeMask.nonNullExact(
+              cls.thisType.element, compiler.world);
+        }
       } else {
         return TypeMaskFactory.inferredReturnTypeForElement(
             originalElement, compiler);
@@ -5089,7 +5099,7 @@
     final bool isSymbolConstructor =
         constructorDeclaration == compiler.symbolConstructor;
     final bool isJSArrayTypedConstructor =
-        constructorDeclaration == backend.jsArrayTypedConstructor;
+        constructorDeclaration == helpers.jsArrayTypedConstructor;
 
     if (isSymbolConstructor) {
       constructor = compiler.symbolValidatedConstructor;
@@ -5128,15 +5138,15 @@
 
     var inputs = <HInstruction>[];
     if (constructor.isGenerativeConstructor &&
-        Elements.isNativeOrExtendsNative(constructor.enclosingClass) &&
-        !constructor.isJsInterop) {
+        backend.isNativeOrExtendsNative(constructor.enclosingClass) &&
+        !backend.isJsInterop(constructor)) {
       // Native class generative constructors take a pre-constructed object.
       inputs.add(graph.addConstantNull(compiler));
     }
     // TODO(5347): Try to avoid the need for calling [implementation] before
     // calling [makeStaticArgumentList].
     constructorImplementation = constructor.implementation;
-    if (constructorImplementation.isErroneous ||
+    if (constructorImplementation.isMalformed ||
         !callStructure.signatureApplies(
             constructorImplementation.functionSignature)) {
       generateWrongArgumentCountError(send, constructor, send.arguments);
@@ -5158,12 +5168,15 @@
       js.Template code = js.js.parseForeignJS('new Array(#)');
       var behavior = new native.NativeBehavior();
       behavior.typesReturned.add(expectedType);
-      // The allocation can throw only if the given length is a double
-      // or negative.
+      // The allocation can throw only if the given length is a double or
+      // outside the unsigned 32 bit range.
+      // TODO(sra): Array allocation should be an instruction so that canThrow
+      // can depend on a length type discovered in optimization.
       bool canThrow = true;
       if (inputs[0].isInteger(compiler) && inputs[0] is HConstant) {
         var constant = inputs[0];
-        if (constant.constant.primitiveValue >= 0) canThrow = false;
+        int value = constant.constant.primitiveValue;
+        if (0 <= value && value < 0x100000000) canThrow = false;
       }
       HForeignCode foreign = new HForeignCode(code, elementType, inputs,
           nativeBehavior: behavior,
@@ -5213,7 +5226,7 @@
     // not know about the type argument. Therefore we special case
     // this constructor to have the setRuntimeTypeInfo called where
     // the 'new' is done.
-    if (backend.classNeedsRti(compiler.listClass) &&
+    if (backend.classNeedsRti(coreClasses.listClass) &&
         (isFixedListConstructorCall || isGrowableListConstructorCall ||
          isJSArrayTypedConstructor)) {
       newInstance = handleListConstructor(type, send, pop());
@@ -5724,18 +5737,14 @@
   void bulkHandleNew(ast.NewExpression node, [_]) {
     Element element = elements[node.send];
     final bool isSymbolConstructor = element == compiler.symbolConstructor;
-    if (!Elements.isErroneous(element)) {
+    if (!Elements.isMalformed(element)) {
       ConstructorElement function = element;
       element = function.effectiveTarget;
     }
-    if (Elements.isErroneous(element)) {
-      if (element is !ErroneousElement) {
-        // TODO(ahe): Do something like [generateWrongArgumentCountError].
-        stack.add(graph.addConstantNull(compiler));
-        return;
-      }
+    if (Elements.isError(element)) {
       ErroneousElement error = element;
-      if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR) {
+      if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR ||
+          error.messageKind == MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR) {
         generateThrowNoSuchMethod(
             node.send,
             noSuchMethodTargetSymbolString(error, 'constructor'),
@@ -5745,6 +5754,9 @@
         Message message = template.message(error.messageArguments);
         generateRuntimeError(node.send, message.toString());
       }
+    } else if (Elements.isMalformed(element)) {
+      // TODO(ahe): Do something like [generateWrongArgumentCountError].
+      stack.add(graph.addConstantNull(compiler));
     } else if (node.isConst) {
       stack.add(addConstant(node));
       if (isSymbolConstructor) {
@@ -5785,11 +5797,11 @@
       if (isLength || selector.isIndex) {
         return compiler.world.isSubtypeOf(
             element.enclosingClass.declaration,
-            backend.jsIndexableClass);
+            helpers.jsIndexableClass);
       } else if (selector.isIndexSet) {
         return compiler.world.isSubtypeOf(
             element.enclosingClass.declaration,
-            backend.jsMutableIndexableClass);
+            helpers.jsMutableIndexableClass);
       } else {
         return false;
       }
@@ -5803,9 +5815,9 @@
       if (selector.isSetter) return true;
       if (selector.isIndex) return true;
       if (selector.isIndexSet) return true;
-      if (element == backend.jsArrayAdd
-          || element == backend.jsArrayRemoveLast
-          || element == backend.jsStringSplit) {
+      if (element == helpers.jsArrayAdd ||
+          element == helpers.jsArrayRemoveLast ||
+          element == helpers.jsStringSplit) {
         return true;
       }
       return false;
@@ -5855,7 +5867,7 @@
   HForeignCode invokeJsInteropFunction(Element element,
                                        List<HInstruction> arguments,
                                        SourceInformation sourceInformation) {
-    assert(element.isJsInterop);
+    assert(backend.isJsInterop(element));
     nativeEmitter.nativeMethods.add(element);
     String templateString;
 
@@ -5894,7 +5906,7 @@
     }
     var target = new HForeignCode(js.js.parseForeignJS(
             "${backend.namer.fixedBackendPath(element)}."
-            "${element.fixedBackendName}"),
+            "${backend.getFixedBackendName(element)}"),
         backend.dynamicType,
         <HInstruction>[]);
     add(target);
@@ -5929,9 +5941,9 @@
     var nativeBehavior = new native.NativeBehavior()
       ..codeTemplate = codeTemplate
       ..typesReturned.add(
-          backend.jsJavaScriptObjectClass.thisType)
+          helpers.jsJavaScriptObjectClass.thisType)
       ..typesInstantiated.add(
-          backend.jsJavaScriptObjectClass.thisType)
+          helpers.jsJavaScriptObjectClass.thisType)
       ..sideEffects.setAllSideEffects();
     return new HForeignCode(
         codeTemplate,
@@ -5959,7 +5971,7 @@
     bool targetCanThrow = !compiler.world.getCannotThrow(element);
     // TODO(5346): Try to avoid the need for calling [declaration] before
     var instruction;
-    if (element.isJsInterop) {
+    if (backend.isJsInterop(element)) {
       instruction = invokeJsInteropFunction(element, arguments,
           sourceInformation);
     } else {
@@ -6885,7 +6897,7 @@
       return;
     }
 
-    if (getter.isErroneous) {
+    if (getter.isMalformed) {
       generateStaticUnresolvedGet(node, getter);
     } else if (getter.isField) {
       generateStaticFieldGet(node, getter);
@@ -7162,7 +7174,7 @@
     return type.isDynamic ||
            type.isObject ||
            (type is InterfaceType &&
-               type.element == compiler.futureClass);
+               type.element == coreClasses.futureClass);
   }
 
   visitReturn(ast.Return node) {
@@ -7215,8 +7227,8 @@
     visit(node.expression);
     HInstruction awaited = pop();
     // TODO(herhut): Improve this type.
-    push(new HAwait(awaited, new TypeMask.subclass(compiler.objectClass,
-                                                   compiler.world)));
+    push(new HAwait(awaited, new TypeMask.subclass(
+        coreClasses.objectClass, compiler.world)));
   }
 
   visitTypeAnnotation(ast.TypeAnnotation node) {
@@ -7253,7 +7265,7 @@
       arguments.add(analyzeTypeArgument(argument));
     }
     // TODO(15489): Register at codegen.
-    registry?.registerInstantiatedType(type);
+    registry?.registerInstantiation(type);
     return callSetRuntimeTypeInfo(type.element, arguments, object);
   }
 
@@ -7375,16 +7387,16 @@
     void buildInitializer() {}
 
     HInstruction buildCondition() {
-      Selector selector = elements.getMoveNextSelector(node);
+      Selector selector = Selectors.moveNext;
       TypeMask mask = elements.getMoveNextTypeMask(node);
       pushInvokeDynamic(node, selector, mask, [streamIterator]);
       HInstruction future = pop();
-      push(new HAwait(future, new TypeMask.subclass(compiler.objectClass,
-                                                    compiler.world)));
+      push(new HAwait(future,
+          new TypeMask.subclass(coreClasses.objectClass, compiler.world)));
       return popBoolified();
     }
     void buildBody() {
-      Selector call = elements.getCurrentSelector(node);
+      Selector call = Selectors.current;
       TypeMask callMask = elements.getCurrentTypeMask(node);
       pushInvokeDynamic(node, call, callMask, [streamIterator]);
 
@@ -7427,8 +7439,8 @@
           Selectors.cancel,
           null,
           [streamIterator]);
-      push(new HAwait(pop(), new TypeMask.subclass(compiler.objectClass,
-          compiler.world)));
+      push(new HAwait(pop(), new TypeMask.subclass(
+          coreClasses.objectClass, compiler.world)));
       pop();
     });
   }
@@ -7444,11 +7456,11 @@
     // method is inlined.  We would require full scalar replacement in that
     // case.
 
-    Selector selector = elements.getIteratorSelector(node);
+    Selector selector = Selectors.iterator;
     TypeMask mask = elements.getIteratorTypeMask(node);
 
     ClassWorld classWorld = compiler.world;
-    if (mask != null && mask.satisfies(backend.jsIndexableClass, classWorld)) {
+    if (mask != null && mask.satisfies(helpers.jsIndexableClass, classWorld)) {
       return buildSyncForInIndexable(node, mask);
     }
     buildSyncForInIterator(node);
@@ -7466,7 +7478,7 @@
     HInstruction iterator;
 
     void buildInitializer() {
-      Selector selector = elements.getIteratorSelector(node);
+      Selector selector = Selectors.iterator;
       TypeMask mask = elements.getIteratorTypeMask(node);
       visit(node.expression);
       HInstruction receiver = pop();
@@ -7475,14 +7487,14 @@
     }
 
     HInstruction buildCondition() {
-      Selector selector = elements.getMoveNextSelector(node);
+      Selector selector = Selectors.moveNext;
       TypeMask mask = elements.getMoveNextTypeMask(node);
       pushInvokeDynamic(node, selector, mask, [iterator]);
       return popBoolified();
     }
 
     void buildBody() {
-      Selector call = elements.getCurrentSelector(node);
+      Selector call = Selectors.current;
       TypeMask mask = elements.getCurrentTypeMask(node);
       pushInvokeDynamic(node, call, mask, [iterator]);
       buildAssignLoopVariable(node, pop());
@@ -7535,7 +7547,7 @@
     HInstruction originalLength = null;  // Set for growable lists.
 
     HInstruction buildGetLength() {
-      Element lengthElement = backend.jsIndexableLength;
+      Element lengthElement = helpers.jsIndexableLength;
       HFieldGet result = new HFieldGet(
           lengthElement, array, backend.positiveIntType,
           isAssignable: !isFixed);
@@ -7681,9 +7693,9 @@
     List<HInstruction> inputs = <HInstruction>[];
 
     if (listInputs.isEmpty) {
-      constructor = backend.mapLiteralConstructorEmpty;
+      constructor = helpers.mapLiteralConstructorEmpty;
     } else {
-      constructor = backend.mapLiteralConstructor;
+      constructor = helpers.mapLiteralConstructor;
       HLiteralList keyValuePairs = buildLiteralList(listInputs);
       add(keyValuePairs);
       inputs.add(keyValuePairs);
@@ -7711,9 +7723,9 @@
       // in the output.
       if (typeInputs.every((HInstruction input) => input.isNull())) {
         if (listInputs.isEmpty) {
-          constructor = backend.mapLiteralUntypedEmptyMaker;
+          constructor = helpers.mapLiteralUntypedEmptyMaker;
         } else {
-          constructor = backend.mapLiteralUntypedMaker;
+          constructor = helpers.mapLiteralUntypedMaker;
         }
       } else {
         inputs.addAll(typeInputs);
@@ -7729,7 +7741,7 @@
     // type inference might discover a more specific type, or find nothing (in
     // dart2js unit tests).
     TypeMask mapType =
-        new TypeMask.nonNullSubtype(backend.mapLiteralClass, compiler.world);
+        new TypeMask.nonNullSubtype(helpers.mapLiteralClass, compiler.world);
     TypeMask returnTypeMask = TypeMaskFactory.inferredReturnTypeForElement(
         constructor, compiler);
     TypeMask instructionType =
@@ -9071,13 +9083,13 @@
   void visit(DartType type, SsaBuilder builder) => type.accept(this, builder);
 
   void visitVoidType(VoidType type, SsaBuilder builder) {
-    ClassElement cls = builder.backend.findHelper('VoidRuntimeType');
+    ClassElement cls = builder.backend.helpers.VoidRuntimeType;
     builder.push(new HVoidType(type, new TypeMask.exact(cls, classWorld)));
   }
 
   void visitTypeVariableType(TypeVariableType type,
                              SsaBuilder builder) {
-    ClassElement cls = builder.backend.findHelper('RuntimeType');
+    ClassElement cls = builder.backend.helpers.RuntimeType;
     TypeMask instructionType = new TypeMask.subclass(cls, classWorld);
     if (!builder.sourceElement.enclosingElement.isClosure &&
         builder.sourceElement.isInstanceMember) {
@@ -9115,7 +9127,7 @@
       inputs.add(builder.pop());
     }
 
-    ClassElement cls = builder.backend.findHelper('RuntimeFunctionType');
+    ClassElement cls = builder.backend.helpers.RuntimeFunctionType;
     builder.push(new HFunctionType(inputs, type,
         new TypeMask.exact(cls, classWorld)));
   }
@@ -9136,9 +9148,9 @@
     }
     ClassElement cls;
     if (type.typeArguments.isEmpty) {
-      cls = builder.backend.findHelper('RuntimeTypePlain');
+      cls = builder.backend.helpers.RuntimeTypePlain;
     } else {
-      cls = builder.backend.findHelper('RuntimeTypeGeneric');
+      cls = builder.backend.helpers.RuntimeTypeGeneric;
     }
     builder.push(new HInterfaceType(inputs, type,
         new TypeMask.exact(cls, classWorld)));
@@ -9152,7 +9164,7 @@
 
   void visitDynamicType(DynamicType type, SsaBuilder builder) {
     JavaScriptBackend backend = builder.compiler.backend;
-    ClassElement cls = backend.findHelper('DynamicRuntimeType');
+    ClassElement cls = backend.helpers.DynamicRuntimeType;
     builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld)));
   }
 }
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index 1edaf6e..69ee9c8 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -157,12 +157,16 @@
 
   CodegenRegistry get registry => work.registry;
 
+  BackendHelpers get helpers => backend.helpers;
+
   native.NativeEnqueuer get nativeEnqueuer {
     return compiler.enqueuer.codegen.nativeEnqueuer;
   }
 
   DiagnosticReporter get reporter => compiler.reporter;
 
+  CoreClasses get coreClasses => compiler.coreClasses;
+
   bool isGenerateAtUseSite(HInstruction instruction) {
     return generateAtUseSite.contains(instruction);
   }
@@ -704,8 +708,8 @@
           registry.registerInstantiatedClass(classElement);
         }
       }
-      register(backend.jsPlainJavaScriptObjectClass);
-      register(backend.jsUnknownJavaScriptObjectClass);
+      register(helpers.jsPlainJavaScriptObjectClass);
+      register(helpers.jsUnknownJavaScriptObjectClass);
 
       HLocalValue exception = info.catchVariable;
       String name = variableNames.getName(exception);
@@ -1521,7 +1525,7 @@
       js.Name name =
           backend.namer.nameForGetInterceptor(node.interceptedClasses);
       var isolate = new js.VariableUse(
-          backend.namer.globalObjectFor(backend.interceptorsLibrary));
+          backend.namer.globalObjectFor(helpers.interceptorsLibrary));
       use(node.receiver);
       List<js.Expression> arguments = <js.Expression>[pop()];
       push(js.propertyCall(isolate, name, arguments)
@@ -1539,21 +1543,21 @@
 
     // TODO(herhut): The namer should return the appropriate backendname here.
     if (target != null && !node.isInterceptedCall) {
-      if (target == backend.jsArrayAdd) {
+      if (target == helpers.jsArrayAdd) {
         methodName = 'push';
-      } else if (target == backend.jsArrayRemoveLast) {
+      } else if (target == helpers.jsArrayRemoveLast) {
         methodName = 'pop';
-      } else if (target == backend.jsStringSplit) {
+      } else if (target == helpers.jsStringSplit) {
         methodName = 'split';
         // Split returns a List, so we make sure the backend knows the
         // list class is instantiated.
-        registry.registerInstantiatedClass(compiler.listClass);
-      } else if (target.isNative && target.isFunction
+        registry.registerInstantiatedClass(coreClasses.listClass);
+      } else if (backend.isNative(target) && target.isFunction
                  && !node.isInterceptedCall) {
         // A direct (i.e. non-interceptor) native call is the result of
         // optimization.  The optimization ensures any type checks or
         // conversions have been satisified.
-        methodName = target.fixedBackendName;
+        methodName = backend.getFixedBackendName(target);
       }
     }
 
@@ -1575,13 +1579,15 @@
     List<js.Expression> arguments = visitArguments(node.inputs);
     push(js.propertyCall(object, methodName, arguments)
          .withSourceInformation(node.sourceInformation));
-    registry.registerStaticUse(node.element);
+    registry.registerStaticUse(
+        new StaticUse.constructorBodyInvoke(
+            node.element, new CallStructure.unnamed(arguments.length)));
   }
 
   void visitOneShotInterceptor(HOneShotInterceptor node) {
     List<js.Expression> arguments = visitArguments(node.inputs);
     var isolate = new js.VariableUse(
-        backend.namer.globalObjectFor(backend.interceptorsLibrary));
+        backend.namer.globalObjectFor(helpers.interceptorsLibrary));
     Selector selector = node.selector;
     TypeMask mask = getOptimizedSelectorFor(node, selector, node.mask);
     js.Name methodName = backend.registerOneShotInterceptor(selector);
@@ -1637,25 +1643,25 @@
       // may know something about the types of closures that need
       // the specific closure call method.
       Selector call = new Selector.callClosureFrom(selector);
-      registry.registerDynamicInvocation(
-          new UniverseSelector(call, null));
+      registry.registerDynamicUse(
+          new DynamicUse(call, null));
     }
-    registry.registerDynamicInvocation(
-        new UniverseSelector(selector, mask));
+    registry.registerDynamicUse(
+        new DynamicUse(selector, mask));
   }
 
   void registerSetter(HInvokeDynamic node) {
     Selector selector = node.selector;
     TypeMask mask = getOptimizedSelectorFor(node, selector, node.mask);
-    registry.registerDynamicSetter(
-        new UniverseSelector(selector, mask));
+    registry.registerDynamicUse(
+        new DynamicUse(selector, mask));
   }
 
   void registerGetter(HInvokeDynamic node) {
     Selector selector = node.selector;
     TypeMask mask = getOptimizedSelectorFor(node, selector, node.mask);
-    registry.registerDynamicGetter(
-        new UniverseSelector(selector, mask));
+    registry.registerDynamicUse(
+        new DynamicUse(selector, mask));
   }
 
   visitInvokeDynamicSetter(HInvokeDynamicSetter node) {
@@ -1681,8 +1687,8 @@
                          backend.namer.invocationName(call),
                          visitArguments(node.inputs))
             .withSourceInformation(node.sourceInformation));
-    registry.registerDynamicInvocation(
-        new UniverseSelector(call, null));
+    registry.registerDynamicUse(
+        new DynamicUse(call, null));
   }
 
   visitInvokeStatic(HInvokeStatic node) {
@@ -1691,7 +1697,7 @@
 
     if (instantiatedTypes != null && !instantiatedTypes.isEmpty) {
       instantiatedTypes.forEach((type) {
-        registry.registerInstantiatedType(type);
+        registry.registerInstantiation(type);
       });
     }
 
@@ -1706,7 +1712,8 @@
 
       assert(arguments.length == 2);
       Element throwFunction = backend.helpers.throwConcurrentModificationError;
-      registry.registerStaticInvocation(throwFunction);
+      registry.registerStaticUse(
+          new StaticUse.staticInvoke(throwFunction, CallStructure.ONE_ARG));
 
       // Calling using `(0, #)(#)` instead of `#(#)` separates the property load
       // of the static function access from the call.  For some reason this
@@ -1720,7 +1727,11 @@
           backend.emitter.staticFunctionAccess(throwFunction),
           arguments[1]]));
     } else {
-      registry.registerStaticInvocation(element);
+      CallStructure callStructure = new CallStructure.unnamed(arguments.length);
+      registry.registerStaticUse(
+          element.isConstructor
+            ? new StaticUse.constructorInvoke(element, callStructure)
+            : new StaticUse.staticInvoke(element, callStructure));
       push(backend.emitter.staticFunctionAccess(element));
       push(new js.Call(pop(), arguments,
           sourceInformation: node.sourceInformation));
@@ -1729,47 +1740,45 @@
   }
 
   visitInvokeSuper(HInvokeSuper node) {
-    Element superMethod = node.element;
-    registry.registerSuperInvocation(superMethod);
-    ClassElement superClass = superMethod.enclosingClass;
-    if (superMethod.kind == ElementKind.FIELD) {
+    Element superElement = node.element;
+    ClassElement superClass = superElement.enclosingClass;
+    if (superElement.isField) {
       js.Name fieldName =
-          backend.namer.instanceFieldPropertyName(superMethod);
+          backend.namer.instanceFieldPropertyName(superElement);
       use(node.inputs[0]);
       js.PropertyAccess access =
           new js.PropertyAccess(pop(), fieldName)
               .withSourceInformation(node.sourceInformation);
       if (node.isSetter) {
+        registry.registerStaticUse(
+            new StaticUse.superSet(superElement));
         use(node.value);
         push(new js.Assignment(access, pop())
             .withSourceInformation(node.sourceInformation));
       } else {
+        registry.registerStaticUse(new StaticUse.superGet(superElement));
         push(access);
       }
     } else {
       Selector selector = node.selector;
-
-      if (!backend.maybeRegisterAliasedSuperMember(superMethod, selector)) {
+      if (!backend.maybeRegisterAliasedSuperMember(superElement, selector)) {
         js.Name methodName;
-        if (selector.isGetter) {
-          // If the selector we need to register a typed getter to the
-          // [world]. The emitter needs to know if it needs to emit a
-          // bound closure for a method.
-
-          // If [superMethod] is mixed in, [superClass] might not be live.
-          // We use the superclass of the access instead.
-          TypeMask receiverType =
-              new TypeMask.nonNullExact(node.caller.superclass, compiler.world);
-          // TODO(floitsch): we know the target. We shouldn't register a
-          // dynamic getter.
-          registry.registerDynamicGetter(
-              new UniverseSelector(selector, receiverType));
-          registry.registerGetterForSuperMethod(node.element);
+        if (selector.isGetter && !superElement.isGetter) {
+          // If this is a tear-off, register the fact that a tear-off closure
+          // will be created, and that this tear-off must bypass ordinary
+          // dispatch to ensure the super method is invoked.
+          FunctionElement helper = backend.helpers.closureFromTearOff;
+          registry.registerStaticUse(new StaticUse.staticInvoke(helper,
+                new CallStructure.unnamed(helper.parameters.length)));
+          registry.registerStaticUse(new StaticUse.superTearOff(node.element));
           methodName = backend.namer.invocationName(selector);
         } else {
-          assert(invariant(node, compiler.hasIncrementalSupport));
-          methodName = backend.namer.instanceMethodName(superMethod);
+          methodName = backend.namer.instanceMethodName(superElement);
         }
+        registry.registerStaticUse(
+            new StaticUse.superInvoke(
+                superElement,
+                new CallStructure.unnamed(node.inputs.length)));
         push(js.js('#.#.call(#)',
                    [backend.emitter.prototypeAccess(superClass,
                                                     hasBeenInstantiated: true),
@@ -1777,9 +1786,13 @@
                 .withSourceInformation(node.sourceInformation));
       } else {
         use(node.receiver);
+        registry.registerStaticUse(
+            new StaticUse.superInvoke(
+                superElement,
+                new CallStructure.unnamed(node.inputs.length - 1)));
         push(
           js.js('#.#(#)', [
-            pop(), backend.namer.aliasedSuperMemberPropertyName(superMethod),
+            pop(), backend.namer.aliasedSuperMemberPropertyName(superElement),
             visitArguments(node.inputs, start: 1)]) // Skip receiver argument.
               .withSourceInformation(node.sourceInformation));
       }
@@ -1795,7 +1808,7 @@
       // that does not exist.
       push(new js.PropertyAccess.field(pop(), 'toString')
           .withSourceInformation(node.sourceInformation));
-    } else if (element == backend.jsIndexableLength) {
+    } else if (element == helpers.jsIndexableLength) {
       // We're accessing a native JavaScript property called 'length'
       // on a JS String or a JS array. Therefore, the name of that
       // property should not be mangled.
@@ -1805,13 +1818,13 @@
       js.Name name = backend.namer.instanceFieldPropertyName(element);
       push(new js.PropertyAccess(pop(), name)
           .withSourceInformation(node.sourceInformation));
-      registry.registerFieldGetter(element);
+      registry.registerStaticUse(new StaticUse.fieldGet(element));
     }
   }
 
   visitFieldSet(HFieldSet node) {
     Element element = node.element;
-    registry.registerFieldSetter(element);
+    registry.registerStaticUse(new StaticUse.fieldSet(element));
     js.Name name = backend.namer.instanceFieldPropertyName(element);
     use(node.receiver);
     js.Expression receiver = pop();
@@ -1822,7 +1835,8 @@
 
   visitReadModifyWrite(HReadModifyWrite node) {
     Element element = node.element;
-    registry.registerFieldSetter(element);
+    registry.registerStaticUse(new StaticUse.fieldGet(element));
+    registry.registerStaticUse(new StaticUse.fieldSet(element));
     js.Name name = backend.namer.instanceFieldPropertyName(element);
     use(node.receiver);
     js.Expression fieldReference = new js.PropertyAccess(pop(), name);
@@ -1897,7 +1911,7 @@
       return;
     }
     node.instantiatedTypes.forEach((type) {
-      registry.registerInstantiatedType(type);
+      registry.registerInstantiation(type);
     });
   }
 
@@ -1917,7 +1931,8 @@
                         SourceInformation sourceInformation) {
     if (constant.isFunction) {
       FunctionConstantValue function = constant;
-      registry.registerStaticUse(function.element);
+      registry.registerStaticUse(
+          new StaticUse.staticTearOff(function.element));
     }
     if (constant.isType) {
       // If the type is a web component, we need to ensure the constructors are
@@ -2078,7 +2093,7 @@
       pushStatement(new js.Throw(pop())
           .withSourceInformation(node.sourceInformation));
     } else {
-      generateThrowWithHelper('wrapException', node.inputs[0],
+      generateThrowWithHelper(helpers.wrapExceptionHelper, node.inputs[0],
           sourceInformation: node.sourceInformation);
     }
   }
@@ -2139,20 +2154,20 @@
       js.Statement thenBody = new js.Block.empty();
       js.Block oldContainer = currentContainer;
       currentContainer = thenBody;
-      generateThrowWithHelper('ioore', [node.array, node.reportedIndex]);
+      generateThrowWithHelper(helpers.throwIndexOutOfRangeException,
+          [node.array, node.reportedIndex]);
       currentContainer = oldContainer;
       thenBody = unwrapStatement(thenBody);
       pushStatement(new js.If.noElse(underOver, thenBody)
           .withSourceInformation(node.sourceInformation));
     } else {
-      generateThrowWithHelper('ioore', [node.array, node.index]);
+      generateThrowWithHelper(helpers.throwIndexOutOfRangeException,
+          [node.array, node.index]);
     }
   }
 
-  void generateThrowWithHelper(String helperName, argument,
+  void generateThrowWithHelper(Element helper, argument,
                                {SourceInformation sourceInformation}) {
-    Element helper = backend.findHelper(helperName);
-    registry.registerStaticUse(helper);
     js.Expression jsHelper = backend.emitter.staticFunctionAccess(helper);
     List arguments = [];
     var location;
@@ -2167,12 +2182,15 @@
       use(argument);
       arguments.add(pop());
     }
+    registry.registerStaticUse(
+        new StaticUse.staticInvoke(
+            helper, new CallStructure.unnamed(arguments.length)));
     js.Call value = new js.Call(jsHelper, arguments.toList(growable: false),
         sourceInformation: sourceInformation);
     // BUG(4906): Using throw/return here adds to the size of the generated code
     // but it has the advantage of explicitly telling the JS engine that
     // this code path will terminate abruptly. Needs more work.
-    if (helperName == 'wrapException') {
+    if (helper == helpers.wrapExceptionHelper) {
       pushStatement(new js.Throw(value)
           .withSourceInformation(sourceInformation));
     } else {
@@ -2194,8 +2212,9 @@
     HInstruction argument = node.inputs[0];
     use(argument);
 
-    Element helper = backend.findHelper("throwExpression");
-    registry.registerStaticUse(helper);
+    Element helper = helpers.throwExpressionHelper;
+    registry.registerStaticUse(
+        new StaticUse.staticInvoke(helper, CallStructure.ONE_ARG));
 
     js.Expression jsHelper = backend.emitter.staticFunctionAccess(helper);
     js.Call value = new js.Call(jsHelper, [pop()])
@@ -2213,17 +2232,20 @@
     if (element.isFunction) {
       push(backend.emitter.isolateStaticClosureAccess(element)
            .withSourceInformation(node.sourceInformation));
-      registry.registerGetOfStaticFunction(element);
+      registry.registerStaticUse(
+          new StaticUse.staticTearOff(element));
     } else {
       push(backend.emitter.staticFieldAccess(element)
            .withSourceInformation(node.sourceInformation));
+      registry.registerStaticUse(
+          new StaticUse.staticGet(element));
     }
-    registry.registerStaticUse(element);
   }
 
   void visitLazyStatic(HLazyStatic node) {
     Element element = node.element;
-    registry.registerStaticUse(element);
+    registry.registerStaticUse(
+        new StaticUse.staticInit(element));
     js.Expression lazyGetter =
         backend.emitter.isolateLazyInitializerAccess(element);
     js.Call call = new js.Call(lazyGetter, <js.Expression>[],
@@ -2232,7 +2254,8 @@
   }
 
   void visitStaticStore(HStaticStore node) {
-    registry.registerStaticUse(node.element);
+    registry.registerStaticUse(
+        new StaticUse.staticSet(node.element));
     js.Node variable = backend.emitter.staticFieldAccess(node.element);
     use(node.inputs[0]);
     push(new js.Assignment(variable, pop())
@@ -2266,7 +2289,8 @@
       }
     } else {
       Element convertToString = backend.helpers.stringInterpolationHelper;
-      registry.registerStaticUse(convertToString);
+      registry.registerStaticUse(
+          new StaticUse.staticInvoke(convertToString, CallStructure.ONE_ARG));
       js.Expression jsHelper =
           backend.emitter.staticFunctionAccess(convertToString);
       use(input);
@@ -2276,7 +2300,7 @@
   }
 
   void visitLiteralList(HLiteralList node) {
-    registry.registerInstantiatedClass(compiler.listClass);
+    registry.registerInstantiatedClass(coreClasses.listClass);
     generateArrayLiteral(node);
   }
 
@@ -2425,31 +2449,31 @@
                  SourceInformation sourceInformation,
                  {bool negative: false}) {
     Element element = type.element;
-    if (element == backend.jsArrayClass) {
+    if (element == helpers.jsArrayClass) {
       checkArray(input, negative ? '!==': '===');
       return;
-    } else if (element == backend.jsMutableArrayClass) {
+    } else if (element == helpers.jsMutableArrayClass) {
       if (negative) {
         checkImmutableArray(input);
       } else {
         checkMutableArray(input);
       }
       return;
-    } else if (element == backend.jsExtendableArrayClass) {
+    } else if (element == helpers.jsExtendableArrayClass) {
       if (negative) {
         checkFixedArray(input);
       } else {
         checkExtendableArray(input);
       }
       return;
-    } else if (element == backend.jsFixedArrayClass) {
+    } else if (element == helpers.jsFixedArrayClass) {
       if (negative) {
         checkExtendableArray(input);
       } else {
         checkFixedArray(input);
       }
       return;
-    } else if (element == backend.jsUnmodifiableArrayClass) {
+    } else if (element == helpers.jsUnmodifiableArrayClass) {
       if (negative) {
         checkMutableArray(input);
       } else {
@@ -2468,7 +2492,7 @@
   void checkTypeViaProperty(HInstruction input, DartType type,
                             SourceInformation sourceInformation,
                             {bool negative: false}) {
-    registry.registerIsCheck(type);
+    registry.registerTypeUse(new TypeUse.isCheck(type));
 
     use(input);
 
@@ -2489,7 +2513,7 @@
       HInstruction input, DartType type,
       SourceInformation sourceInformation,
       {bool negative: false}) {
-    registry.registerIsCheck(type);
+    registry.registerTypeUse(new TypeUse.isCheck(type));
 
     use(input);
 
@@ -2501,7 +2525,7 @@
       push(new js.Prefix('!', pop())
           .withSourceInformation(sourceInformation));
     }
-    registry.registerInstantiatedType(type);
+    registry.registerInstantiation(type);
   }
 
   void handleNumberOrStringSupertypeCheck(HInstruction input,
@@ -2509,7 +2533,7 @@
                                           DartType type,
                                           SourceInformation sourceInformation,
                                           {bool negative: false}) {
-    assert(!identical(type.element, compiler.listClass) &&
+    assert(!identical(type.element, coreClasses.listClass) &&
            !Elements.isListSupertype(type.element, compiler) &&
            !Elements.isStringOnlySupertype(type.element, compiler));
     String relation = negative ? '!==' : '===';
@@ -2535,7 +2559,7 @@
                                   DartType type,
                                   SourceInformation sourceInformation,
                                   {bool negative: false}) {
-    assert(!identical(type.element, compiler.listClass)
+    assert(!identical(type.element, coreClasses.listClass)
            && !Elements.isListSupertype(type.element, compiler)
            && !Elements.isNumberOrStringSupertype(type.element, compiler));
     String relation = negative ? '!==' : '===';
@@ -2555,7 +2579,7 @@
                                   DartType type,
                                   SourceInformation sourceInformation,
                                   { bool negative: false }) {
-    assert(!identical(type.element, compiler.stringClass)
+    assert(!identical(type.element, coreClasses.stringClass)
            && !Elements.isStringOnlySupertype(type.element, compiler)
            && !Elements.isNumberOrStringSupertype(type.element, compiler));
     String relation = negative ? '!==' : '===';
@@ -2581,7 +2605,7 @@
 
   void emitIs(HIs node, String relation, SourceInformation sourceInformation)  {
     DartType type = node.typeExpression;
-    registry.registerIsCheck(type);
+    registry.registerTypeUse(new TypeUse.isCheck(type));
     HInstruction input = node.expression;
 
     // If this is changed to single == there are several places below that must
@@ -2595,9 +2619,9 @@
     } else {
       assert(node.isRawCheck);
       HInstruction interceptor = node.interceptor;
-      ClassElement objectClass = compiler.objectClass;
+      ClassElement objectClass = coreClasses.objectClass;
       Element element = type.element;
-      if (element == compiler.nullClass) {
+      if (element == coreClasses.nullClass) {
         if (negative) {
           checkNonNull(input);
         } else {
@@ -2607,15 +2631,15 @@
         // The constant folder also does this optimization, but we make
         // it safe by assuming it may have not run.
         push(newLiteralBool(!negative, sourceInformation));
-      } else if (element == compiler.stringClass) {
+      } else if (element == coreClasses.stringClass) {
         checkString(input, relation, sourceInformation);
-      } else if (element == compiler.doubleClass) {
+      } else if (element == coreClasses.doubleClass) {
         checkDouble(input, relation, sourceInformation);
-      } else if (element == compiler.numClass) {
+      } else if (element == coreClasses.numClass) {
         checkNum(input, relation, sourceInformation);
-      } else if (element == compiler.boolClass) {
+      } else if (element == coreClasses.boolClass) {
         checkBool(input, relation, sourceInformation);
-      } else if (element == compiler.intClass) {
+      } else if (element == coreClasses.intClass) {
         // The is check in the code tells us that it might not be an
         // int. So we do a typeof first to avoid possible
         // deoptimizations on the JS engine due to the Math.floor check.
@@ -2639,7 +2663,7 @@
             input, interceptor, type,
             sourceInformation,
             negative: negative);
-      } else if (identical(element, compiler.listClass) ||
+      } else if (identical(element, coreClasses.listClass) ||
                  Elements.isListSupertype(element, compiler)) {
         handleListOrSupertypeCheck(
             input, interceptor, type,
@@ -2688,7 +2712,7 @@
     bool turnIntoNullCheck = !turnIntoNumCheck
         && (checkedType.nullable() == inputType)
         && (isIntCheck
-            || checkedType.satisfies(backend.jsIndexableClass, classWorld));
+            || checkedType.satisfies(helpers.jsIndexableClass, classWorld));
 
     if (turnIntoNullCheck) {
       use(input);
@@ -2729,7 +2753,8 @@
       js.Statement body = new js.Block.empty();
       currentContainer = body;
       if (node.isArgumentTypeCheck) {
-        generateThrowWithHelper('iae',
+        generateThrowWithHelper(
+            helpers.throwIllegalArgumentException,
             node.checkedInput,
             sourceInformation: node.sourceInformation);
       } else if (node.isReceiverTypeCheck) {
@@ -2752,9 +2777,10 @@
     if (type.isFunctionType) {
       // TODO(5022): We currently generate $isFunction checks for
       // function types.
-      registry.registerIsCheck(compiler.functionClass.rawType);
+      registry.registerTypeUse(
+          new TypeUse.isCheck(compiler.coreTypes.functionType));
     }
-    registry.registerIsCheck(type);
+    registry.registerTypeUse(new TypeUse.isCheck(type));
 
     CheckedModeHelper helper;
     if (node.isBooleanConversionCheck) {
@@ -2824,8 +2850,9 @@
 
   void visitReadTypeVariable(HReadTypeVariable node) {
     TypeVariableElement element = node.dartType.element;
-    Element helperElement = backend.findHelper('convertRtiToRuntimeType');
-    registry.registerStaticUse(helperElement);
+    Element helperElement = helpers.convertRtiToRuntimeType;
+    registry.registerStaticUse(
+        new StaticUse.staticInvoke(helperElement, CallStructure.ONE_ARG));
 
     use(node.inputs[0]);
     if (node.hasReceiver) {
@@ -2843,8 +2870,7 @@
       }
     } else {
       push(js.js('#(#)', [
-          backend.emitter.staticFunctionAccess(
-              backend.findHelper('convertRtiToRuntimeType')),
+          backend.emitter.staticFunctionAccess(helperElement),
           pop()]));
     }
   }
@@ -2861,7 +2887,8 @@
     if (!typeArguments.isEmpty) {
       arguments.add(new js.ArrayInitializer(typeArguments));
     }
-    push(js.js('#(#)', [accessHelper('buildInterfaceType'), arguments]));
+    push(js.js('#(#)',
+        [accessHelper('buildInterfaceType', arguments.length), arguments]));
   }
 
   void visitVoidType(HVoidType node) {
@@ -2872,13 +2899,15 @@
     push(js.js('#()', accessHelper('getDynamicRuntimeType')));
   }
 
-  js.PropertyAccess accessHelper(String name) {
-    Element helper = backend.findHelper(name);
+  js.PropertyAccess accessHelper(String name, [int argumentCount = 0]) {
+    Element helper = helpers.findHelper(name);
     if (helper == null) {
       // For mocked-up tests.
       return js.js('(void 0).$name');
     }
-    registry.registerStaticUse(helper);
+    registry.registerStaticUse(
+        new StaticUse.staticInvoke(helper,
+            new CallStructure.unnamed(argumentCount)));
     return backend.emitter.staticFunctionAccess(helper);
   }
 
diff --git a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
index 97b4b17..9cfb66b 100644
--- a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
+++ b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
@@ -34,6 +34,12 @@
 
   SsaSimplifyInterceptors(this.compiler, this.constantSystem, this.work);
 
+  JavaScriptBackend get backend => compiler.backend;
+
+  BackendHelpers get helpers => backend.helpers;
+
+  ClassWorld get classWorld => compiler.world;
+
   void visitGraph(HGraph graph) {
     this.graph = graph;
     visitDominatorTree(graph);
@@ -80,22 +86,20 @@
 
   bool canUseSelfForInterceptor(HInstruction receiver,
                                 Set<ClassElement> interceptedClasses) {
-    JavaScriptBackend backend = compiler.backend;
-    ClassWorld classWorld = compiler.world;
 
     if (receiver.canBePrimitive(compiler)) {
       // Primitives always need interceptors.
       return false;
     }
     if (receiver.canBeNull() &&
-        interceptedClasses.contains(backend.jsNullClass)) {
+        interceptedClasses.contains(helpers.jsNullClass)) {
       // Need the JSNull interceptor.
       return false;
     }
 
     // All intercepted classes extend `Interceptor`, so if the receiver can't be
     // a class extending `Interceptor` then it can be called directly.
-    return new TypeMask.nonNullSubclass(backend.jsInterceptorClass, classWorld)
+    return new TypeMask.nonNullSubclass(helpers.jsInterceptorClass, classWorld)
         .intersection(receiver.instructionType, classWorld)
         .isEmpty;
   }
@@ -131,29 +135,27 @@
       TypeMask type,
       Set<ClassElement> interceptedClasses) {
 
-    ClassWorld classWorld = compiler.world;
-    JavaScriptBackend backend = compiler.backend;
     if (type.isNullable) {
       if (type.isEmpty) {
-        return backend.jsNullClass;
+        return helpers.jsNullClass;
       }
     } else if (type.containsOnlyInt(classWorld)) {
-      return backend.jsIntClass;
+      return helpers.jsIntClass;
     } else if (type.containsOnlyDouble(classWorld)) {
-      return backend.jsDoubleClass;
+      return helpers.jsDoubleClass;
     } else if (type.containsOnlyBool(classWorld)) {
-      return backend.jsBoolClass;
+      return helpers.jsBoolClass;
     } else if (type.containsOnlyString(classWorld)) {
-      return backend.jsStringClass;
-    } else if (type.satisfies(backend.jsArrayClass, classWorld)) {
-      return backend.jsArrayClass;
+      return helpers.jsStringClass;
+    } else if (type.satisfies(helpers.jsArrayClass, classWorld)) {
+      return helpers.jsArrayClass;
     } else if (type.containsOnlyNum(classWorld) &&
-        !interceptedClasses.contains(backend.jsIntClass) &&
-        !interceptedClasses.contains(backend.jsDoubleClass)) {
+        !interceptedClasses.contains(helpers.jsIntClass) &&
+        !interceptedClasses.contains(helpers.jsDoubleClass)) {
       // If the method being intercepted is not defined in [int] or [double] we
       // can safely use the number interceptor.  This is because none of the
       // [int] or [double] methods are called from a method defined on [num].
-      return backend.jsNumberClass;
+      return helpers.jsNumberClass;
     } else {
       // Try to find constant interceptor for a native class.  If the receiver
       // is constrained to a leaf native class, we can use the class's
@@ -167,7 +169,7 @@
       // code is completely insensitive to the specific instance subclasses, we
       // can use the non-leaf class directly.
       ClassElement element = type.singleClass(classWorld);
-      if (element != null && element.isNative) {
+      if (element != null && backend.isNative(element)) {
         return element;
       }
     }
@@ -209,7 +211,6 @@
         user.inputs.where((input) => input == used).length;
 
     Set<ClassElement> interceptedClasses;
-    JavaScriptBackend backend = compiler.backend;
     HInstruction dominator = findDominator(node.usedBy);
     // If there is a call that dominates all other uses, we can use just the
     // selector of that instruction.
@@ -222,18 +223,18 @@
 
       // If we found that we need number, we must still go through all
       // uses to check if they require int, or double.
-      if (interceptedClasses.contains(backend.jsNumberClass) &&
-          !(interceptedClasses.contains(backend.jsDoubleClass) ||
-            interceptedClasses.contains(backend.jsIntClass))) {
+      if (interceptedClasses.contains(helpers.jsNumberClass) &&
+          !(interceptedClasses.contains(helpers.jsDoubleClass) ||
+            interceptedClasses.contains(helpers.jsIntClass))) {
         for (HInstruction user in node.usedBy) {
           if (user is! HInvoke) continue;
           Set<ClassElement> intercepted =
               backend.getInterceptedClassesOn(user.selector.name);
-          if (intercepted.contains(backend.jsIntClass)) {
-            interceptedClasses.add(backend.jsIntClass);
+          if (intercepted.contains(helpers.jsIntClass)) {
+            interceptedClasses.add(helpers.jsIntClass);
           }
-          if (intercepted.contains(backend.jsDoubleClass)) {
-            interceptedClasses.add(backend.jsDoubleClass);
+          if (intercepted.contains(helpers.jsDoubleClass)) {
+            interceptedClasses.add(helpers.jsDoubleClass);
           }
         }
       }
@@ -291,7 +292,7 @@
     // constant interceptor `C`.  Then we can use `(receiver && C)` for the
     // interceptor.
     if (receiver.canBeNull() && !node.isConditionalConstantInterceptor) {
-      if (!interceptedClasses.contains(backend.jsNullClass)) {
+      if (!interceptedClasses.contains(helpers.jsNullClass)) {
         // Can use `(receiver && C)` only if receiver is either null or truthy.
         if (!(receiver.canBePrimitiveNumber(compiler) ||
             receiver.canBePrimitiveBoolean(compiler) ||
@@ -331,7 +332,6 @@
       // See if we can rewrite the is-check to use 'instanceof', i.e. rewrite
       // "getInterceptor(x).$isT" to "x instanceof T".
       if (node == user.interceptor) {
-        JavaScriptBackend backend = compiler.backend;
         if (backend.mayGenerateInstanceofCheck(user.typeExpression)) {
           HInstruction instanceofCheck = new HIs.instanceOf(
               user.typeExpression, user.expression, user.instructionType);
diff --git a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
index e0c5611..754ed27 100644
--- a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
+++ b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
@@ -238,7 +238,8 @@
                                      Compiler compiler) {
     if (selector.name == name) return selector;
     JavaScriptBackend backend = compiler.backend;
-    return new Selector.call(new Name(name, backend.interceptorsLibrary),
+    return new Selector.call(
+        new Name(name, backend.helpers.interceptorsLibrary),
         new CallStructure(selector.argumentCount));
   }
 }
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index 08f6987..0e1788b 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -922,75 +922,84 @@
   bool canBePrimitiveNumber(Compiler compiler) {
     ClassWorld classWorld = compiler.world;
     JavaScriptBackend backend = compiler.backend;
+    BackendHelpers helpers = backend.helpers;
     // TODO(sra): It should be possible to test only jsDoubleClass and
     // jsUInt31Class, since all others are superclasses of these two.
-    return containsType(instructionType, backend.jsNumberClass, classWorld)
-        || containsType(instructionType, backend.jsIntClass, classWorld)
-        || containsType(instructionType, backend.jsPositiveIntClass, classWorld)
-        || containsType(instructionType, backend.jsUInt32Class, classWorld)
-        || containsType(instructionType, backend.jsUInt31Class, classWorld)
-        || containsType(instructionType, backend.jsDoubleClass, classWorld);
+    return containsType(instructionType, helpers.jsNumberClass, classWorld)
+        || containsType(instructionType, helpers.jsIntClass, classWorld)
+        || containsType(instructionType, helpers.jsPositiveIntClass, classWorld)
+        || containsType(instructionType, helpers.jsUInt32Class, classWorld)
+        || containsType(instructionType, helpers.jsUInt31Class, classWorld)
+        || containsType(instructionType, helpers.jsDoubleClass, classWorld);
   }
 
   bool canBePrimitiveBoolean(Compiler compiler) {
     ClassWorld classWorld = compiler.world;
     JavaScriptBackend backend = compiler.backend;
-    return containsType(instructionType, backend.jsBoolClass, classWorld);
+    BackendHelpers helpers = backend.helpers;
+    return containsType(instructionType, helpers.jsBoolClass, classWorld);
   }
 
   bool canBePrimitiveArray(Compiler compiler) {
     ClassWorld classWorld = compiler.world;
     JavaScriptBackend backend = compiler.backend;
-    return containsType(instructionType, backend.jsArrayClass, classWorld)
-        || containsType(instructionType, backend.jsFixedArrayClass, classWorld)
+    BackendHelpers helpers = backend.helpers;
+    return containsType(instructionType, helpers.jsArrayClass, classWorld)
+        || containsType(instructionType, helpers.jsFixedArrayClass, classWorld)
         || containsType(
-            instructionType, backend.jsExtendableArrayClass, classWorld)
+            instructionType, helpers.jsExtendableArrayClass, classWorld)
         || containsType(instructionType,
-            backend.jsUnmodifiableArrayClass, classWorld);
+            helpers.jsUnmodifiableArrayClass, classWorld);
   }
 
   bool isIndexablePrimitive(Compiler compiler) {
     ClassWorld classWorld = compiler.world;
     JavaScriptBackend backend = compiler.backend;
+    BackendHelpers helpers = backend.helpers;
     return instructionType.containsOnlyString(classWorld)
-        || isInstanceOf(instructionType, backend.jsIndexableClass, classWorld);
+        || isInstanceOf(instructionType, helpers.jsIndexableClass, classWorld);
   }
 
   bool isFixedArray(Compiler compiler) {
     ClassWorld classWorld = compiler.world;
     JavaScriptBackend backend = compiler.backend;
+    BackendHelpers helpers = backend.helpers;
     // TODO(sra): Recognize the union of these types as well.
     return containsOnlyType(
-            instructionType, backend.jsFixedArrayClass, classWorld)
+            instructionType, helpers.jsFixedArrayClass, classWorld)
         || containsOnlyType(
-            instructionType, backend.jsUnmodifiableArrayClass, classWorld);
+            instructionType, helpers.jsUnmodifiableArrayClass, classWorld);
   }
 
   bool isExtendableArray(Compiler compiler) {
     ClassWorld classWorld = compiler.world;
     JavaScriptBackend backend = compiler.backend;
+    BackendHelpers helpers = backend.helpers;
     return containsOnlyType(
-        instructionType, backend.jsExtendableArrayClass, classWorld);
+        instructionType, helpers.jsExtendableArrayClass, classWorld);
   }
 
   bool isMutableArray(Compiler compiler) {
     ClassWorld classWorld = compiler.world;
     JavaScriptBackend backend = compiler.backend;
+    BackendHelpers helpers = backend.helpers;
     return isInstanceOf(
-        instructionType, backend.jsMutableArrayClass, classWorld);
+        instructionType, helpers.jsMutableArrayClass, classWorld);
   }
 
   bool isReadableArray(Compiler compiler) {
     ClassWorld classWorld = compiler.world;
     JavaScriptBackend backend = compiler.backend;
-    return isInstanceOf(instructionType, backend.jsArrayClass, classWorld);
+    BackendHelpers helpers = backend.helpers;
+    return isInstanceOf(instructionType, helpers.jsArrayClass, classWorld);
   }
 
   bool isMutableIndexable(Compiler compiler) {
     ClassWorld classWorld = compiler.world;
     JavaScriptBackend backend = compiler.backend;
+    BackendHelpers helpers = backend.helpers;
     return isInstanceOf(instructionType,
-        backend.jsMutableIndexableClass, classWorld);
+        helpers.jsMutableIndexableClass, classWorld);
   }
 
   bool isArray(Compiler compiler) => isReadableArray(compiler);
@@ -998,7 +1007,8 @@
   bool canBePrimitiveString(Compiler compiler) {
     ClassWorld classWorld = compiler.world;
     JavaScriptBackend backend = compiler.backend;
-    return containsType(instructionType, backend.jsStringClass, classWorld);
+    BackendHelpers helpers = backend.helpers;
+    return containsType(instructionType, helpers.jsStringClass, classWorld);
   }
 
   bool isInteger(Compiler compiler) {
@@ -1010,29 +1020,33 @@
   bool isUInt32(Compiler compiler) {
     ClassWorld classWorld = compiler.world;
     JavaScriptBackend backend = compiler.backend;
+    BackendHelpers helpers = backend.helpers;
     return !instructionType.isNullable
-        && isInstanceOf(instructionType, backend.jsUInt32Class, classWorld);
+        && isInstanceOf(instructionType, helpers.jsUInt32Class, classWorld);
   }
 
   bool isUInt31(Compiler compiler) {
     ClassWorld classWorld = compiler.world;
     JavaScriptBackend backend = compiler.backend;
+    BackendHelpers helpers = backend.helpers;
     return !instructionType.isNullable
-        && isInstanceOf(instructionType, backend.jsUInt31Class, classWorld);
+        && isInstanceOf(instructionType, helpers.jsUInt31Class, classWorld);
   }
 
   bool isPositiveInteger(Compiler compiler) {
     ClassWorld classWorld = compiler.world;
     JavaScriptBackend backend = compiler.backend;
+    BackendHelpers helpers = backend.helpers;
     return !instructionType.isNullable &&
-        isInstanceOf(instructionType, backend.jsPositiveIntClass, classWorld);
+        isInstanceOf(instructionType, helpers.jsPositiveIntClass, classWorld);
   }
 
   bool isPositiveIntegerOrNull(Compiler compiler) {
     ClassWorld classWorld = compiler.world;
     JavaScriptBackend backend = compiler.backend;
+    BackendHelpers helpers = backend.helpers;
     return isInstanceOf(
-        instructionType, backend.jsPositiveIntClass, classWorld);
+        instructionType, helpers.jsPositiveIntClass, classWorld);
   }
 
   bool isIntegerOrNull(Compiler compiler) {
@@ -1319,9 +1333,9 @@
     assert(type.kind != TypeKind.TYPE_VARIABLE);
     assert(type.treatAsRaw || type.isFunctionType);
     if (type.isDynamic) return this;
+    if (type.isObject) return this;
     // The type element is either a class or the void element.
     Element element = type.element;
-    if (identical(element, compiler.objectClass)) return this;
     JavaScriptBackend backend = compiler.backend;
     if (type.kind != TypeKind.INTERFACE) {
       return new HTypeConversion(type, kind, backend.dynamicType, this);
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 563b503..c98ceb1 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -111,8 +111,8 @@
     return true;
   }
   // TODO(sra): Recognize any combination of fixed length indexables.
-  if (mask.containsOnly(backend.jsFixedArrayClass) ||
-      mask.containsOnly(backend.jsUnmodifiableArrayClass) ||
+  if (mask.containsOnly(backend.helpers.jsFixedArrayClass) ||
+      mask.containsOnly(backend.helpers.jsUnmodifiableArrayClass) ||
       mask.containsOnlyString(classWorld) ||
       backend.isTypedArray(mask)) {
     return true;
@@ -145,6 +145,10 @@
                            this.optimizer,
                            this.work);
 
+  CoreClasses get coreClasses => compiler.coreClasses;
+
+  BackendHelpers get helpers => backend.helpers;
+
   void visitGraph(HGraph visitee) {
     graph = visitee;
     visitDominatorTree(visitee);
@@ -250,7 +254,7 @@
 
     // All values that cannot be 'true' are boolified to false.
     TypeMask mask = input.instructionType;
-    if (!mask.contains(backend.jsBoolClass, compiler.world)) {
+    if (!mask.contains(helpers.jsBoolClass, compiler.world)) {
       return graph.addConstantBool(false, compiler);
     }
     return node;
@@ -297,17 +301,17 @@
         ListConstantValue constant = constantInput.constant;
         return graph.addConstantInt(constant.length, compiler);
       }
-      Element element = backend.jsIndexableLength;
+      Element element = helpers.jsIndexableLength;
       bool isFixed = isFixedLength(actualReceiver.instructionType, compiler);
       TypeMask actualType = node.instructionType;
       ClassWorld classWorld = compiler.world;
       TypeMask resultType = backend.positiveIntType;
       // If we already have computed a more specific type, keep that type.
       if (HInstruction.isInstanceOf(
-              actualType, backend.jsUInt31Class, classWorld)) {
+              actualType, helpers.jsUInt31Class, classWorld)) {
         resultType = backend.uint31Type;
       } else if (HInstruction.isInstanceOf(
-              actualType, backend.jsUInt32Class, classWorld)) {
+              actualType, helpers.jsUInt32Class, classWorld)) {
         resultType = backend.uint32Type;
       }
       HFieldGet result = new HFieldGet(
@@ -351,22 +355,22 @@
     if (selector.isCall || selector.isOperator) {
       Element target;
       if (input.isExtendableArray(compiler)) {
-        if (applies(backend.jsArrayRemoveLast)) {
-          target = backend.jsArrayRemoveLast;
-        } else if (applies(backend.jsArrayAdd)) {
+        if (applies(helpers.jsArrayRemoveLast)) {
+          target = helpers.jsArrayRemoveLast;
+        } else if (applies(helpers.jsArrayAdd)) {
           // The codegen special cases array calls, but does not
           // inline argument type checks.
           if (!compiler.enableTypeAssertions) {
-            target = backend.jsArrayAdd;
+            target = helpers.jsArrayAdd;
           }
         }
       } else if (input.isStringOrNull(compiler)) {
-        if (applies(backend.jsStringSplit)) {
+        if (applies(helpers.jsStringSplit)) {
           HInstruction argument = node.inputs[2];
           if (argument.isString(compiler)) {
-            target = backend.jsStringSplit;
+            target = helpers.jsStringSplit;
           }
-        } else if (applies(backend.jsStringOperatorAdd)) {
+        } else if (applies(helpers.jsStringOperatorAdd)) {
           // `operator+` is turned into a JavaScript '+' so we need to
           // make sure the receiver and the argument are not null.
           // TODO(sra): Do this via [node.specializer].
@@ -376,7 +380,7 @@
             return new HStringConcat(input, argument, null,
                                      node.instructionType);
           }
-        } else if (applies(backend.jsStringToString)
+        } else if (applies(helpers.jsStringToString)
                    && !input.canBeNull()) {
           return input;
         }
@@ -397,7 +401,7 @@
         return result;
       }
     } else if (selector.isGetter) {
-      if (selector.applies(backend.jsIndexableLength, world)) {
+      if (selector.applies(helpers.jsIndexableLength, world)) {
         HInstruction optimized = tryOptimizeLengthInterceptedGetter(node);
         if (optimized != null) return optimized;
       }
@@ -424,7 +428,7 @@
         && element.name == node.selector.name) {
       FunctionElement method = element;
 
-      if (method.isNative) {
+      if (backend.isNative(method)) {
         HInstruction folded = tryInlineNativeMethod(node, method);
         if (folded != null) return folded;
       } else {
@@ -675,22 +679,22 @@
       return node;
     } else if (type.isTypedef) {
       return node;
-    } else if (element == compiler.functionClass) {
+    } else if (element == coreClasses.functionClass) {
       return node;
     }
 
-    if (element == compiler.objectClass || type.treatAsDynamic) {
+    if (type.isObject || type.treatAsDynamic) {
       return graph.addConstantBool(true, compiler);
     }
 
     ClassWorld classWorld = compiler.world;
     HInstruction expression = node.expression;
     if (expression.isInteger(compiler)) {
-      if (identical(element, compiler.intClass)
-          || identical(element, compiler.numClass)
-          || Elements.isNumberOrStringSupertype(element, compiler)) {
+      if (element == coreClasses.intClass ||
+          element == coreClasses.numClass ||
+          Elements.isNumberOrStringSupertype(element, compiler)) {
         return graph.addConstantBool(true, compiler);
-      } else if (identical(element, compiler.doubleClass)) {
+      } else if (element == coreClasses.doubleClass) {
         // We let the JS semantics decide for that check. Currently
         // the code we emit will always return true.
         return node;
@@ -698,11 +702,11 @@
         return graph.addConstantBool(false, compiler);
       }
     } else if (expression.isDouble(compiler)) {
-      if (identical(element, compiler.doubleClass)
-          || identical(element, compiler.numClass)
-          || Elements.isNumberOrStringSupertype(element, compiler)) {
+      if (element == coreClasses.doubleClass ||
+          element == coreClasses.numClass ||
+          Elements.isNumberOrStringSupertype(element, compiler)) {
         return graph.addConstantBool(true, compiler);
-      } else if (identical(element, compiler.intClass)) {
+      } else if (element == coreClasses.intClass) {
         // We let the JS semantics decide for that check. Currently
         // the code we emit will return true for a double that can be
         // represented as a 31-bit integer and for -0.0.
@@ -711,14 +715,14 @@
         return graph.addConstantBool(false, compiler);
       }
     } else if (expression.isNumber(compiler)) {
-      if (identical(element, compiler.numClass)) {
+      if (element == coreClasses.numClass) {
         return graph.addConstantBool(true, compiler);
       } else {
         // We cannot just return false, because the expression may be of
         // type int or double.
       }
-    } else if (expression.canBePrimitiveNumber(compiler)
-               && identical(element, compiler.intClass)) {
+    } else if (expression.canBePrimitiveNumber(compiler) &&
+               element == coreClasses.intClass) {
       // We let the JS semantics decide for that check.
       return node;
     // We need the [:hasTypeArguments:] check because we don't have
@@ -728,7 +732,7 @@
     } else if (!RuntimeTypes.hasTypeArguments(type)) {
       TypeMask expressionMask = expression.instructionType;
       assert(TypeMask.assertIsNormalized(expressionMask, classWorld));
-      TypeMask typeMask = (element == compiler.nullClass)
+      TypeMask typeMask = (element == coreClasses.nullClass)
           ? new TypeMask.subtype(element, classWorld)
           : new TypeMask.nonNullSubtype(element, classWorld);
       if (expressionMask.union(typeMask, classWorld) == typeMask) {
@@ -781,7 +785,7 @@
   HInstruction visitFieldGet(HFieldGet node) {
     if (node.isNullCheck) return node;
     var receiver = node.receiver;
-    if (node.element == backend.jsIndexableLength) {
+    if (node.element == helpers.jsIndexableLength) {
       JavaScriptItemCompilationContext context = work.compilationContext;
       if (context.allocatedFixedLists.contains(receiver)) {
         // TODO(ngeoffray): checking if the second input is an integer
@@ -858,7 +862,7 @@
     bool isAssignable = !compiler.world.fieldNeverChanges(field);
 
     TypeMask type;
-    if (field.enclosingClass.isNative) {
+    if (backend.isNative(field.enclosingClass)) {
       type = TypeMaskFactory.fromNativeBehavior(
           native.NativeBehavior.ofFieldLoad(field, compiler),
           compiler);
@@ -1003,6 +1007,8 @@
                    this.work,
                    this.boundsChecked);
 
+  BackendHelpers get helpers => backend.helpers;
+
   void visitGraph(HGraph graph) {
     this.graph = graph;
 
@@ -1028,7 +1034,7 @@
                                  HInstruction indexArgument) {
     Compiler compiler = backend.compiler;
     HFieldGet length = new HFieldGet(
-        backend.jsIndexableLength, array, backend.positiveIntType,
+        helpers.jsIndexableLength, array, backend.positiveIntType,
         isAssignable: !isFixedLength(array.instructionType, compiler));
     indexNode.block.addBefore(indexNode, length);
 
@@ -1067,7 +1073,7 @@
   void visitInvokeDynamicMethod(HInvokeDynamicMethod node) {
     Element element = node.element;
     if (node.isInterceptedCall) return;
-    if (element != backend.jsArrayRemoveLast) return;
+    if (element != helpers.jsArrayRemoveLast) return;
     if (boundsChecked.contains(node)) return;
     // `0` is the index we want to check, but we want to report `-1`, as if we
     // executed `a[a.length-1]`
@@ -2129,6 +2135,8 @@
 
   MemorySet(this.compiler);
 
+  JavaScriptBackend get backend => compiler.backend;
+
   /**
    * Returns whether [first] and [second] always alias to the same object.
    */
@@ -2185,7 +2193,9 @@
   void registerFieldValueUpdate(Element element,
                                 HInstruction receiver,
                                 HInstruction value) {
-    if (element.isNative) return; // TODO(14955): Remove this restriction?
+    if (backend.isNative(element)) {
+      return; // TODO(14955): Remove this restriction?
+    }
     // [value] is being set in some place in memory, we remove it from
     // the non-escaping set.
     nonEscapingReceivers.remove(value);
@@ -2203,7 +2213,9 @@
   void registerFieldValue(Element element,
                           HInstruction receiver,
                           HInstruction value) {
-    if (element.isNative) return; // TODO(14955): Remove this restriction?
+    if (backend.isNative(element)) {
+      return; // TODO(14955): Remove this restriction?
+    }
     Map<HInstruction, HInstruction> map = fieldValues.putIfAbsent(
         element, () => <HInstruction, HInstruction> {});
     map[receiver] = value;
diff --git a/pkg/compiler/lib/src/ssa/ssa.dart b/pkg/compiler/lib/src/ssa/ssa.dart
index 5d56ba3..5139e5e 100644
--- a/pkg/compiler/lib/src/ssa/ssa.dart
+++ b/pkg/compiler/lib/src/ssa/ssa.dart
@@ -24,6 +24,8 @@
 import '../constants/constant_system.dart';
 import '../constants/expressions.dart';
 import '../constants/values.dart';
+import '../core_types.dart' show
+    CoreClasses;
 import '../dart_types.dart';
 import '../diagnostics/messages.dart' show
     Message,
@@ -44,8 +46,6 @@
 import '../native/native.dart' as native;
 import '../resolution/operators.dart';
 import '../resolution/semantic_visitor.dart';
-import '../resolution/send_resolver.dart' show
-    SendResolverMixin;
 import '../resolution/tree_elements.dart' show
     TreeElements;
 import '../tree/tree.dart' as ast;
@@ -58,8 +58,10 @@
     Selector;
 import '../universe/side_effects.dart' show
     SideEffects;
-import '../universe/universe.dart' show
-    UniverseSelector;
+import '../universe/use.dart' show
+    DynamicUse,
+    StaticUse,
+    TypeUse;
 import '../util/util.dart';
 import '../world.dart' show
     ClassWorld,
diff --git a/pkg/compiler/lib/src/ssa/types.dart b/pkg/compiler/lib/src/ssa/types.dart
index c8a39fa..a34e60b 100644
--- a/pkg/compiler/lib/src/ssa/types.dart
+++ b/pkg/compiler/lib/src/ssa/types.dart
@@ -57,11 +57,12 @@
   static TypeMask fromNativeType(type, Compiler compiler) {
     ClassWorld classWorld = compiler.world;
     JavaScriptBackend backend = compiler.backend;
+    CoreClasses coreClasses = compiler.coreClasses;
     if (type == native.SpecialType.JsObject) {
-      return new TypeMask.nonNullExact(compiler.objectClass, classWorld);
+      return new TypeMask.nonNullExact(coreClasses.objectClass, classWorld);
     } else if (type.isVoid) {
       return backend.nullType;
-    } else if (type.element == compiler.nullClass) {
+    } else if (type.element == coreClasses.nullClass) {
       return backend.nullType;
     } else if (type.treatAsDynamic) {
       return backend.dynamicType;
diff --git a/pkg/compiler/lib/src/ssa/types_propagation.dart b/pkg/compiler/lib/src/ssa/types_propagation.dart
index 2fb2d11..adda76e 100644
--- a/pkg/compiler/lib/src/ssa/types_propagation.dart
+++ b/pkg/compiler/lib/src/ssa/types_propagation.dart
@@ -262,7 +262,7 @@
             cls.declaration, classWorld);
         // TODO(ngeoffray): We currently only optimize on primitive
         // types.
-        if (!type.satisfies(backend.jsIndexableClass, classWorld) &&
+        if (!type.satisfies(backend.helpers.jsIndexableClass, classWorld) &&
             !type.containsOnlyNum(classWorld) &&
             !type.containsOnlyBool(classWorld)) {
           return false;
diff --git a/pkg/compiler/lib/src/ssa/value_range_analyzer.dart b/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
index 3d05dc8..a940e71 100644
--- a/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
+++ b/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
@@ -693,7 +693,7 @@
       return visitInstruction(fieldGet);
     }
     JavaScriptBackend backend = compiler.backend;
-    assert(fieldGet.element == backend.jsIndexableLength);
+    assert(fieldGet.element == backend.helpers.jsIndexableLength);
     PositiveValue value = info.newPositiveValue(fieldGet);
     // We know this range is above zero. To simplify the analysis, we
     // put the zero value as the lower bound of this range. This
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 0091ef9..1da49af 100644
--- a/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
+++ b/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
@@ -7,6 +7,7 @@
 import 'optimization.dart' show Pass;
 import '../tree_ir_nodes.dart';
 import '../../io/source_information.dart';
+import '../../elements/elements.dart';
 
 /**
  * Translates to direct-style.
@@ -277,6 +278,11 @@
     // it means we are looking at the first use.
     assert(unseenUses[node.variable] < node.variable.readCount);
     assert(unseenUses[node.variable] >= 0);
+
+    // We cannot reliably find the first dynamic use of a variable that is
+    // accessed from a JS function in a foreign code fragment.
+    if (node.variable.isCaptured) return node;
+
     bool isFirstUse = unseenUses[node.variable] == 0;
 
     // Propagate constant to use site.
@@ -513,7 +519,19 @@
 
   Expression visitInvokeMethodDirectly(InvokeMethodDirectly node) {
     _rewriteList(node.arguments);
-    node.receiver = visitExpression(node.receiver);
+    // The target function might not exist before the enclosing class has been
+    // instantitated for the first time.  If the receiver might be the first
+    // instantiation of its class, we cannot propgate it into the receiver
+    // expression, because the target function is evaluated before the receiver.
+    // Calls to constructor bodies are compiled so that the receiver is
+    // evaluated first, so they are safe.
+    if (node.target is! ConstructorBodyElement) {
+      inEmptyEnvironment(() {
+        node.receiver = visitExpression(node.receiver);
+      });
+    } else {
+      node.receiver = visitExpression(node.receiver);
+    }
     return node;
   }
 
@@ -1126,15 +1144,25 @@
     return polarity ? node.thenStatement : node.elseStatement;
   }
 
+  void handleForeignCode(ForeignCode node) {
+    // Arguments will get inserted in a JS code template.  The arguments will
+    // not always be evaluated (e.g. if the template is '# && #').
+    // TODO(asgerf): We could analyze the JS AST to see if arguments are
+    //               definitely evaluated left-to-right.
+    inEmptyEnvironment(() {
+      _rewriteList(node.arguments);
+    });
+  }
+
   @override
   Expression visitForeignExpression(ForeignExpression node) {
-    _rewriteList(node.arguments);
+    handleForeignCode(node);
     return node;
   }
 
   @override
   Statement visitForeignStatement(ForeignStatement node) {
-    _rewriteList(node.arguments);
+    handleForeignCode(node);
     return node;
   }
 
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 5eddb37..c42cab8 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 '../constants/values.dart';
 import '../cps_ir/cps_ir_nodes.dart' as cps_ir;
 import '../elements/elements.dart';
+import 'package:js_ast/js_ast.dart' as js;
 
 import 'tree_ir_nodes.dart';
 
@@ -406,11 +407,22 @@
   }
 
   NodeCallback visitForeignCode(cps_ir.ForeignCode node) {
+    List<Expression> arguments =
+        node.arguments.map(getVariableUse).toList(growable: false);
+    if (HasCapturedArguments.check(node.codeTemplate.ast)) {
+      for (Expression arg in arguments) {
+        if (arg is VariableUse) {
+          arg.variable.isCaptured = true;
+        } else {
+          // TODO(asgerf): Avoid capture of 'this'.
+        }
+      }
+    }
     if (node.codeTemplate.isExpression) {
       Expression foreignCode = new ForeignExpression(
           node.codeTemplate,
           node.type,
-          node.arguments.map(getVariableUse).toList(growable: false),
+          arguments,
           node.nativeBehavior,
           node.dependency);
       return makeCallExpression(node, foreignCode);
@@ -420,7 +432,7 @@
         return new ForeignStatement(
             node.codeTemplate,
             node.type,
-            node.arguments.map(getVariableUse).toList(growable: false),
+            arguments,
             node.nativeBehavior,
             node.dependency);
       };
@@ -704,3 +716,28 @@
   visitContinuation(cps_ir.Continuation node) => unexpectedNode(node);
   visitMutableVariable(cps_ir.MutableVariable node) => unexpectedNode(node);
 }
+
+class HasCapturedArguments extends js.BaseVisitor {
+  static bool check(js.Node node) {
+    HasCapturedArguments visitor = new HasCapturedArguments();
+    node.accept(visitor);
+    return visitor.found;
+  }
+
+  int enclosingFunctions = 0;
+  bool found = false;
+
+  @override
+  visitFun(js.Fun node) {
+    ++enclosingFunctions;
+    node.visitChildren(this);
+    --enclosingFunctions;
+  }
+
+  @override
+  visitInterpolatedNode(js.InterpolatedNode node) {
+    if (enclosingFunctions > 0) {
+      found = true;
+    }
+  }
+}
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 4693bad..bd4baab 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
@@ -119,10 +119,8 @@
   /// - catch parameter in a [Try]
   int writeCount = 0;
 
-  /// True if a nested function reads or writes this variable.
-  ///
-  /// Always false in JS-mode because closure conversion eliminated nested
-  /// functions.
+  /// True if an inner JS function might access this variable through a
+  /// [ForeignCode] node.
   bool isCaptured = false;
 
   Variable(this.host, this.element) {
@@ -236,6 +234,8 @@
   InvokeMethodDirectly(this.receiver, this.target, this.selector,
       this.arguments, this.sourceInformation);
 
+  bool get isTearOff => selector.isGetter && !target.isGetter;
+
   accept(ExpressionVisitor visitor) => visitor.visitInvokeMethodDirectly(this);
   accept1(ExpressionVisitor1 visitor, arg) {
     return visitor.visitInvokeMethodDirectly(this, arg);
diff --git a/pkg/compiler/lib/src/typechecker.dart b/pkg/compiler/lib/src/typechecker.dart
index 90a85fb..71a0fc1 100644
--- a/pkg/compiler/lib/src/typechecker.dart
+++ b/pkg/compiler/lib/src/typechecker.dart
@@ -756,7 +756,7 @@
           // This is an access the implicit 'call' method of a function type.
           return new FunctionCallAccess(receiverElement, unaliasedBound);
         }
-        if (types.isSubtype(interface, compiler.functionClass.rawType)) {
+        if (types.isSubtype(interface, coreTypes.functionType)) {
           // This is an access of the special 'call' method implicitly defined
           // on 'Function'. This method can be called with any arguments, which
           // we ensure by giving it the type 'dynamic'.
@@ -1023,8 +1023,7 @@
   ElementAccess computeAccess(Send node, String name, Element element,
                               MemberKind memberKind,
                               {bool lookupClassMember: false}) {
-    if (element != null && element.isErroneous) {
-      // An error has already been reported for this node.
+    if (Elements.isMalformed(element)) {
       return const DynamicAccess();
     }
     if (node.receiver != null) {
@@ -1063,7 +1062,7 @@
     if (element == null) {
       // foo() where foo is unresolved.
       return lookupMember(node, thisType, name, memberKind, null);
-    } else if (element.isErroneous) {
+    } else if (element.isMalformed) {
       // foo() where foo is erroneous.
       return const DynamicAccess();
     } else if (element.impliesType) {
@@ -1199,14 +1198,21 @@
     Identifier selector = node.selector.asIdentifier();
     if (Elements.isClosureSend(node, element)) {
       if (element != null) {
-        // foo() where foo is a local or a parameter.
-        return analyzeInvocation(node, createPromotedAccess(element));
+        if (element.isError) {
+          // foo() where foo is erroneous
+          return analyzeInvocation(node, const DynamicAccess());
+        } else {
+          assert(invariant(node, element.isLocal,
+              message: "Unexpected element $element in closure send."));
+          // foo() where foo is a local or a parameter.
+          return analyzeInvocation(node, createPromotedAccess(element));
+        }
       } else {
         // exp() where exp is some complex expression like (o) or foo().
         DartType type = analyze(node.selector);
         return analyzeInvocation(node, new TypeAccess(type));
       }
-    } else if (Elements.isErroneous(element) && selector == null) {
+    } else if (Elements.isMalformed(element) && selector == null) {
       // exp() where exp is an erroneous construct like `new Unresolved()`.
       DartType type = analyze(node.selector);
       return analyzeInvocation(node, new TypeAccess(type));
@@ -1335,15 +1341,15 @@
       LinkBuilder<DartType> argumentTypesBuilder = new LinkBuilder<DartType>();
       DartType resultType =
           analyzeInvocation(node, access, argumentTypesBuilder);
-      if (identical(receiverType.element, compiler.intClass)) {
+      if (receiverType == intType) {
         if (identical(name, '+') ||
             identical(operatorName, '-') ||
             identical(name, '*') ||
             identical(name, '%')) {
           DartType argumentType = argumentTypesBuilder.toLink().head;
-          if (identical(argumentType.element, compiler.intClass)) {
+          if (argumentType == intType) {
             return intType;
-          } else if (identical(argumentType.element, compiler.doubleClass)) {
+          } else if (argumentType == doubleType) {
             return doubleType;
           }
         }
@@ -1590,7 +1596,7 @@
   }
 
   DartType visitLiteralSymbol(LiteralSymbol node) {
-    return compiler.symbolClass.rawType;
+    return coreTypes.symbolType;
   }
 
   DartType computeConstructorType(ConstructorElement constructor,
@@ -1829,8 +1835,6 @@
   visitAsyncForIn(AsyncForIn node) {
     DartType elementType = computeForInElementType(node);
     DartType expressionType = analyze(node.expression);
-    // TODO(johnniwinther): Move this to _CompilerCoreTypes.
-    compiler.streamClass.ensureResolved(resolution);
     DartType streamOfDynamic = coreTypes.streamType();
     if (!types.isAssignable(expressionType, streamOfDynamic)) {
       reportMessage(node.expression,
@@ -1842,7 +1846,7 @@
           Types.computeInterfaceType(resolution, expressionType);
       if (interfaceType != null) {
         InterfaceType streamType =
-            interfaceType.asInstanceOf(compiler.streamClass);
+            interfaceType.asInstanceOf(streamOfDynamic.element);
         if (streamType != null) {
           DartType streamElementType = streamType.typeArguments.first;
           if (!types.isAssignable(streamElementType, elementType)) {
diff --git a/pkg/compiler/lib/src/types/flat_type_mask.dart b/pkg/compiler/lib/src/types/flat_type_mask.dart
index ce19f17..6516d96 100644
--- a/pkg/compiler/lib/src/types/flat_type_mask.dart
+++ b/pkg/compiler/lib/src/types/flat_type_mask.dart
@@ -546,9 +546,8 @@
    */
   static bool hasConcreteMatch(ClassElement cls,
                                Selector selector,
-                               World world) {
-    assert(invariant(cls,
-        world.compiler.resolverWorld.isInstantiated(cls),
+                               ClassWorld world) {
+    assert(invariant(cls, world.isInstantiated(cls),
         message: '$cls has not been instantiated.'));
     Element element = findMatchIn(cls, selector);
     if (element == null) return false;
diff --git a/pkg/compiler/lib/src/types/type_mask.dart b/pkg/compiler/lib/src/types/type_mask.dart
index 2f5754f..c255b60 100644
--- a/pkg/compiler/lib/src/types/type_mask.dart
+++ b/pkg/compiler/lib/src/types/type_mask.dart
@@ -89,7 +89,7 @@
   factory TypeMask.exact(ClassElement base, ClassWorld classWorld) {
     assert(invariant(base, classWorld.isInstantiated(base),
         message: () => "Cannot create exact type mask for uninstantiated "
-                       "class $base.\n${classWorld.dump()}"));
+                       "class $base.\n${classWorld.dump(base)}"));
     return new FlatTypeMask.exact(base);
   }
 
@@ -99,21 +99,31 @@
   }
 
   factory TypeMask.subclass(ClassElement base, ClassWorld classWorld) {
-    if (classWorld.hasAnyStrictSubclass(base)) {
-      return new FlatTypeMask.subclass(base);
+    assert(invariant(base, classWorld.isInstantiated(base),
+        message: () => "Cannot create subclass type mask for uninstantiated "
+                       "class $base.\n${classWorld.dump(base)}"));
+    ClassElement topmost = classWorld.getLubOfInstantiatedSubclasses(base);
+    if (topmost == null) {
+      return new TypeMask.empty();
+    } else if (classWorld.hasAnyStrictSubclass(topmost)) {
+      return new FlatTypeMask.subclass(topmost);
     } else {
-      return new TypeMask.exactOrEmpty(base, classWorld);
+      return new TypeMask.exact(topmost, classWorld);
     }
   }
 
   factory TypeMask.subtype(ClassElement base, ClassWorld classWorld) {
-    if (classWorld.hasOnlySubclasses(base)) {
-      return new TypeMask.subclass(base, classWorld);
+    ClassElement topmost = classWorld.getLubOfInstantiatedSubtypes(base);
+    if (topmost == null) {
+      return new TypeMask.empty();
     }
-    if (classWorld.hasAnyStrictSubtype(base)) {
-      return new FlatTypeMask.subtype(base);
+    if (classWorld.hasOnlySubclasses(topmost)) {
+      return new TypeMask.subclass(topmost, classWorld);
+    }
+    if (classWorld.hasAnyStrictSubtype(topmost)) {
+      return new FlatTypeMask.subtype(topmost);
     } else {
-      return new TypeMask.exactOrEmpty(base, classWorld);
+      return new TypeMask.exact(topmost, classWorld);
     }
   }
 
@@ -121,8 +131,8 @@
 
   factory TypeMask.nonNullExact(ClassElement base, ClassWorld classWorld) {
     assert(invariant(base, classWorld.isInstantiated(base),
-        message: () => "Cannot create exact type mask for "
-                 "uninstantiated class $base.\n${classWorld.dump(base)}"));
+        message: () => "Cannot create exact type mask for uninstantiated "
+                       "class $base.\n${classWorld.dump(base)}"));
     return new FlatTypeMask.nonNullExact(base);
   }
 
@@ -135,21 +145,31 @@
   }
 
   factory TypeMask.nonNullSubclass(ClassElement base, ClassWorld classWorld) {
-    if (classWorld.hasAnyStrictSubclass(base)) {
-      return new FlatTypeMask.nonNullSubclass(base);
+    assert(invariant(base, classWorld.isInstantiated(base),
+        message: () => "Cannot create subclass type mask for uninstantiated "
+                       "class $base.\n${classWorld.dump(base)}"));
+    ClassElement topmost = classWorld.getLubOfInstantiatedSubclasses(base);
+    if (topmost == null) {
+      return new TypeMask.nonNullEmpty();
+    } else if (classWorld.hasAnyStrictSubclass(topmost)) {
+      return new FlatTypeMask.nonNullSubclass(topmost);
     } else {
-      return new TypeMask.nonNullExactOrEmpty(base, classWorld);
+      return new TypeMask.nonNullExact(topmost, classWorld);
     }
   }
 
   factory TypeMask.nonNullSubtype(ClassElement base, ClassWorld classWorld) {
-    if (classWorld.hasOnlySubclasses(base)) {
-      return new TypeMask.nonNullSubclass(base, classWorld);
+    ClassElement topmost = classWorld.getLubOfInstantiatedSubtypes(base);
+    if (topmost == null) {
+      return new TypeMask.nonNullEmpty();
     }
-    if (classWorld.hasAnyStrictSubtype(base)) {
-      return new FlatTypeMask.nonNullSubtype(base);
+    if (classWorld.hasOnlySubclasses(topmost)) {
+      return new TypeMask.nonNullSubclass(topmost, classWorld);
+    }
+    if (classWorld.hasAnyStrictSubtype(topmost)) {
+      return new FlatTypeMask.nonNullSubtype(topmost);
     } else {
-      return new TypeMask.nonNullExactOrEmpty(base, classWorld);
+      return new TypeMask.nonNullExact(topmost, classWorld);
     }
   }
 
@@ -315,12 +335,6 @@
   TypeMask intersection(TypeMask other, ClassWorld classWorld);
 
   /**
-   * Returns whether this [TypeMask] applied to [selector] can hit a
-   * [noSuchMethod].
-   */
-  bool needsNoSuchMethodHandling(Selector selector, ClassWorld classWorld);
-
-  /**
    * Returns whether [element] is a potential target when being
    * invoked on this type mask. [selector] is used to ensure library
    * privacy is taken into account.
diff --git a/pkg/compiler/lib/src/types/types.dart b/pkg/compiler/lib/src/types/types.dart
index 9d91f99..b8591aa 100644
--- a/pkg/compiler/lib/src/types/types.dart
+++ b/pkg/compiler/lib/src/types/types.dart
@@ -87,6 +87,9 @@
   TypeMask constMapTypeCache;
   TypeMask stringTypeCache;
   TypeMask typeTypeCache;
+  TypeMask syncStarIterableTypeCache;
+  TypeMask asyncFutureTypeCache;
+  TypeMask asyncStarStreamTypeCache;
 
   TypeMask get dynamicType {
     if (dynamicTypeCache == null) {
@@ -232,6 +235,30 @@
     return typeTypeCache;
   }
 
+  TypeMask get syncStarIterableType {
+    if (syncStarIterableTypeCache == null) {
+      syncStarIterableTypeCache = new TypeMask.nonNullExact(
+          compiler.backend.syncStarIterableImplementation, compiler.world);
+    }
+    return syncStarIterableTypeCache;
+  }
+
+  TypeMask get asyncFutureType {
+    if (asyncFutureTypeCache == null) {
+      asyncFutureTypeCache = new TypeMask.nonNullExact(
+          compiler.backend.asyncFutureImplementation, compiler.world);
+    }
+    return asyncFutureTypeCache;
+  }
+
+  TypeMask get asyncStarStreamType {
+    if (asyncStarStreamTypeCache == null) {
+      asyncStarStreamTypeCache = new TypeMask.nonNullExact(
+          compiler.backend.asyncStarStreamImplementation, compiler.world);
+    }
+    return asyncStarStreamTypeCache;
+  }
+
   TypeMask get nullType {
     if (nullTypeCache == null) {
       // TODO(johnniwinther): Assert that the null type has been resolved.
@@ -287,7 +314,7 @@
   TypeMask getGuaranteedTypeOfElement(Element element) {
     return measure(() {
       // TODO(24489): trust some JsInterop types.
-      if (element.isJsInterop) {
+      if (compiler.backend.isJsInterop(element)) {
         return dynamicType;
       }
       TypeMask guaranteedType = typesInferrer.getTypeOfElement(element);
@@ -298,7 +325,7 @@
   TypeMask getGuaranteedReturnTypeOfElement(Element element) {
     return measure(() {
       // TODO(24489): trust some JsInterop types.
-      if (element.isJsInterop) {
+      if (compiler.backend.isJsInterop(element)) {
         return dynamicType;
       }
 
diff --git a/pkg/compiler/lib/src/universe/call_structure.dart b/pkg/compiler/lib/src/universe/call_structure.dart
index 461950f..727390a 100644
--- a/pkg/compiler/lib/src/universe/call_structure.dart
+++ b/pkg/compiler/lib/src/universe/call_structure.dart
@@ -186,8 +186,8 @@
       ConstructorElement callee,
       /*T*/ compileArgument(ParameterElement element),
       /*T*/ compileConstant(ParameterElement element)) {
-    assert(invariant(caller, !callee.isErroneous,
-        message: "Cannot compute arguments to erroneous constructor: "
+    assert(invariant(caller, !callee.isMalformed,
+        message: "Cannot compute arguments to malformed constructor: "
                  "$caller calling $callee."));
 
     FunctionSignature signature = caller.functionSignature;
diff --git a/pkg/compiler/lib/src/universe/class_set.dart b/pkg/compiler/lib/src/universe/class_set.dart
index b418976..ac856a2 100644
--- a/pkg/compiler/lib/src/universe/class_set.dart
+++ b/pkg/compiler/lib/src/universe/class_set.dart
@@ -35,6 +35,7 @@
 ///
 class ClassHierarchyNode {
   final ClassElement cls;
+  ClassElement _leastUpperInstantiatedSubclass;
 
   /// `true` if [cls] has been directly instantiated.
   ///
@@ -101,15 +102,55 @@
         includeUninstantiated: includeUninstantiated);
   }
 
+  /// Returns the most specific subclass of [cls] (including [cls]) that is
+  /// directly instantiated or a superclass of all directly instantiated
+  /// subclasses. If [cls] is not instantiated, `null` is returned.
+  ClassElement getLubOfInstantiatedSubclasses() {
+    if (!isInstantiated) return null;
+    if (_leastUpperInstantiatedSubclass == null) {
+      _leastUpperInstantiatedSubclass =
+          _computeLeastUpperInstantiatedSubclass();
+    }
+    return _leastUpperInstantiatedSubclass;
+  }
+
+  ClassElement _computeLeastUpperInstantiatedSubclass() {
+    if (isDirectlyInstantiated) {
+      return cls;
+    }
+    ClassHierarchyNode subclass;
+    for (Link<ClassHierarchyNode> link = _directSubclasses;
+         !link.isEmpty;
+         link = link.tail) {
+      if (link.head.isInstantiated) {
+        if (subclass == null) {
+          subclass = link.head;
+        } else {
+          return cls;
+        }
+      }
+    }
+    if (subclass != null) {
+      return subclass.getLubOfInstantiatedSubclasses();
+    }
+    return cls;
+  }
+
   void printOn(StringBuffer sb, String indentation,
                {bool instantiatedOnly: false,
+                bool sorted: true,
                 ClassElement withRespectTo}) {
 
     bool isRelatedTo(ClassElement subclass) {
-      return subclass.implementsInterface(withRespectTo);
+      return subclass == withRespectTo ||
+          subclass.implementsInterface(withRespectTo);
     }
 
-    sb.write('$indentation$cls');
+    sb.write(indentation);
+    if (cls.isAbstract) {
+      sb.write('abstract ');
+    }
+    sb.write('class ${cls.name}:');
     if (isDirectlyInstantiated) {
       sb.write(' directly');
     }
@@ -120,11 +161,14 @@
     if (_directSubclasses.isEmpty) {
       sb.write(']');
     } else {
+      var subclasses = _directSubclasses;
+      if (sorted) {
+        subclasses = _directSubclasses.toList()..sort((a, b) {
+          return a.cls.name.compareTo(b.cls.name);
+        });
+      }
       bool needsComma = false;
-      for (Link<ClassHierarchyNode> link = _directSubclasses;
-           !link.isEmpty;
-           link = link.tail) {
-        ClassHierarchyNode child = link.head;
+      for (ClassHierarchyNode child in subclasses) {
         if (instantiatedOnly && !child.isInstantiated) {
           continue;
         }
@@ -140,6 +184,7 @@
             sb,
             '$indentation  ',
             instantiatedOnly: instantiatedOnly,
+            sorted: sorted,
             withRespectTo: withRespectTo);
         needsComma = true;
       }
@@ -211,6 +256,7 @@
 ///
 class ClassSet {
   final ClassHierarchyNode node;
+  ClassElement _leastUpperInstantiatedSubtype;
 
   List<ClassHierarchyNode> _directSubtypes;
 
@@ -311,6 +357,42 @@
     }
   }
 
+  /// Returns the most specific subtype of [cls] (including [cls]) that is
+  /// directly instantiated or a superclass of all directly instantiated
+  /// subtypes. If no subtypes of [cls] are instantiated, `null` is returned.
+  ClassElement getLubOfInstantiatedSubtypes() {
+    if (_leastUpperInstantiatedSubtype == null) {
+      _leastUpperInstantiatedSubtype = _computeLeastUpperInstantiatedSubtype();
+    }
+    return _leastUpperInstantiatedSubtype;
+  }
+
+  ClassElement _computeLeastUpperInstantiatedSubtype() {
+    if (node.isDirectlyInstantiated) {
+      return cls;
+    }
+    if (_directSubtypes == null) {
+      return node.getLubOfInstantiatedSubclasses();
+    }
+    ClassHierarchyNode subtype;
+    if (node.isInstantiated) {
+      subtype = node;
+    }
+    for (ClassHierarchyNode subnode in _directSubtypes) {
+      if (subnode.isInstantiated) {
+        if (subtype == null) {
+          subtype = subnode;
+        } else {
+          return cls;
+        }
+      }
+    }
+    if (subtype != null) {
+      return subtype.getLubOfInstantiatedSubclasses();
+    }
+    return null;
+  }
+
   String toString() {
     StringBuffer sb = new StringBuffer();
     sb.write('[\n');
diff --git a/pkg/compiler/lib/src/universe/function_set.dart b/pkg/compiler/lib/src/universe/function_set.dart
index 72a1813..27273341 100644
--- a/pkg/compiler/lib/src/universe/function_set.dart
+++ b/pkg/compiler/lib/src/universe/function_set.dart
@@ -19,6 +19,8 @@
 
 import 'selector.dart' show
     Selector;
+import 'universe.dart' show
+    ReceiverConstraint;
 
 // TODO(kasperl): This actually holds getters and setters just fine
 // too and stricly they aren't functions. Maybe this needs a better
@@ -64,36 +66,37 @@
 
   /// Returns an object that allows iterating over all the functions
   /// that may be invoked with the given [selector].
-  Iterable<Element> filter(Selector selector, TypeMask mask) {
-    return query(selector, mask).functions;
+  Iterable<Element> filter(Selector selector, ReceiverConstraint constraint) {
+    return query(selector, constraint).functions;
   }
 
   /// Returns the mask for the potential receivers of a dynamic call to
-  /// [selector] on [mask].
+  /// [selector] on [constraint].
   ///
-  /// This will reduce the set of classes in [mask] to a [TypeMask] of the set
-  /// of classes that actually implement the selected member or implement the
-  /// handling 'noSuchMethod' where the selected member is unimplemented.
-  TypeMask receiverType(Selector selector, TypeMask mask) {
-    return query(selector, mask).computeMask(classWorld);
+  /// This will narrow the constraints of [constraint] to a [TypeMask] of the
+  /// set of classes that actually implement the selected member or implement
+  /// the handling 'noSuchMethod' where the selected member is unimplemented.
+  TypeMask receiverType(Selector selector, ReceiverConstraint constraint) {
+    return query(selector, constraint).computeMask(classWorld);
   }
 
   SelectorMask _createSelectorMask(
-      Selector selector, TypeMask mask, ClassWorld classWorld) {
-    return mask != null
-        ? new SelectorMask(selector, mask)
+      Selector selector, ReceiverConstraint constraint, ClassWorld classWorld) {
+    return constraint != null
+        ? new SelectorMask(selector, constraint)
         : new SelectorMask(selector,
             new TypeMask.subclass(classWorld.objectClass, classWorld));
   }
 
   /// Returns the set of functions that can be the target of a call to
-  /// [selector] on a receiver of type [mask] including 'noSuchMethod' methods
-  /// where applicable.
-  FunctionSetQuery query(Selector selector, TypeMask mask) {
+  /// [selector] on a receiver constrained by [constraint] including
+  /// 'noSuchMethod' methods where applicable.
+  FunctionSetQuery query(Selector selector, ReceiverConstraint constraint) {
     String name = selector.name;
-    SelectorMask selectorMask = _createSelectorMask(selector, mask, classWorld);
+    SelectorMask selectorMask =
+        _createSelectorMask(selector, constraint, classWorld);
     SelectorMask noSuchMethodMask =
-        new SelectorMask(Selectors.noSuchMethod_, selectorMask.mask);
+        new SelectorMask(Selectors.noSuchMethod_, selectorMask.constraint);
     FunctionSetNode node = nodes[name];
     FunctionSetNode noSuchMethods = nodes[Identifiers.noSuchMethod_];
     if (node != null) {
@@ -115,38 +118,38 @@
   }
 }
 
-/// A selector/mask pair representing the dynamic invocation of [selector] on
-/// a receiver of type [mask].
+/// A selector/constraint pair representing the dynamic invocation of [selector]
+/// on a receiver constrained by [constraint].
 class SelectorMask {
   final Selector selector;
-  final TypeMask mask;
+  final ReceiverConstraint constraint;
   final int hashCode;
 
-  SelectorMask(Selector selector, TypeMask mask)
+  SelectorMask(Selector selector, ReceiverConstraint constraint)
       : this.selector = selector,
-        this.mask = mask,
+        this.constraint = constraint,
         this.hashCode =
-            Hashing.mixHashCodeBits(selector.hashCode, mask.hashCode) {
-    assert(mask != null);
+            Hashing.mixHashCodeBits(selector.hashCode, constraint.hashCode) {
+    assert(constraint != null);
   }
 
   String get name => selector.name;
 
   bool applies(Element element, ClassWorld classWorld) {
     if (!selector.appliesUnnamed(element, classWorld)) return false;
-    return mask.canHit(element, selector, classWorld);
+    return constraint.canHit(element, selector, classWorld);
   }
 
   bool needsNoSuchMethodHandling(ClassWorld classWorld) {
-    return mask.needsNoSuchMethodHandling(selector, classWorld);
+    return constraint.needsNoSuchMethodHandling(selector, classWorld);
   }
 
   bool operator ==(other) {
     if (identical(this, other)) return true;
-    return selector == other.selector && mask == other.mask;
+    return selector == other.selector && constraint == other.constraint;
   }
 
-  String toString() => '($selector,$mask)';
+  String toString() => '($selector,$constraint)';
 }
 
 /// A node in the [FunctionSet] caching all [FunctionSetQuery] object for
@@ -298,8 +301,11 @@
         .map((cls) {
           if (classWorld.backend.isNullImplementation(cls)) {
             return const TypeMask.empty();
-          } else {
+          } else if (classWorld.isInstantiated(cls.declaration)) {
             return new TypeMask.nonNullSubclass(cls.declaration, classWorld);
+          } else {
+            // TODO(johnniwinther): Avoid the need for this case.
+            return const TypeMask.empty();
           }
         }),
         classWorld);
diff --git a/pkg/compiler/lib/src/universe/universe.dart b/pkg/compiler/lib/src/universe/universe.dart
index 78e586f..5a7ba20 100644
--- a/pkg/compiler/lib/src/universe/universe.dart
+++ b/pkg/compiler/lib/src/universe/universe.dart
@@ -18,28 +18,11 @@
 
 import 'selector.dart' show
     Selector;
-
-class UniverseSelector {
-  final Selector selector;
-  final ReceiverConstraint mask;
-
-  UniverseSelector(this.selector, this.mask);
-
-  bool appliesUnnamed(Element element, ClassWorld world) {
-    return selector.appliesUnnamed(element, world) &&
-        (mask == null || mask.canHit(element, selector, world));
-  }
-
-  int get hashCode => selector.hashCode * 13 + mask.hashCode * 17;
-
-  bool operator ==(other) {
-    if (identical(this, other)) return true;
-    if (other is! UniverseSelector) return false;
-    return selector == other.selector && mask == other.mask;
-  }
-
-  String toString() => '$selector,$mask';
-}
+import 'use.dart' show
+    DynamicUse,
+    DynamicUseKind,
+    StaticUse,
+    StaticUseKind;
 
 /// The known constraint on receiver for a dynamic call site.
 ///
@@ -56,6 +39,10 @@
   /// invoked on a receiver with this constraint. [selector] is used to ensure
   /// library privacy is taken into account.
   bool canHit(Element element, Selector selector, ClassWorld classWorld);
+
+  /// Returns whether this [TypeMask] applied to [selector] can hit a
+  /// [noSuchMethod].
+  bool needsNoSuchMethodHandling(Selector selector, ClassWorld classWorld);
 }
 
 /// The combined constraints on receivers all the dynamic call sites of the same
@@ -75,7 +62,7 @@
 ///     new A().foo(a, b);
 ///     new B().foo(0, 42);
 ///
-/// the selector constaints for dynamic calls to 'foo' with two positional
+/// the selector constraints for dynamic calls to 'foo' with two positional
 /// arguments could be 'receiver of exact instance `A` or `B`'.
 abstract class SelectorConstraints {
   /// Returns `true` if [selector] applies to [element] under these constraints
@@ -141,12 +128,6 @@
   /// See [_directlyInstantiatedClasses].
   final Set<DartType> _instantiatedTypes = new Set<DartType>();
 
-  /// The set of all instantiated classes, either directly, as superclasses or
-  /// as supertypes.
-  ///
-  /// Invariant: Elements are declaration elements.
-  final Set<ClassElement> _allInstantiatedClasses = new Set<ClassElement>();
-
   /// Classes implemented by directly instantiated classes.
   final Set<ClassElement> _implementedClasses = new Set<ClassElement>();
 
@@ -223,13 +204,6 @@
     return _directlyInstantiatedClasses;
   }
 
-  /// All instantiated classes, either directly, as superclasses or as
-  /// supertypes.
-  // TODO(johnniwinther): Improve semantic precision.
-  Iterable<ClassElement> get allInstantiatedClasses {
-    return _allInstantiatedClasses;
-  }
-
   /// All directly instantiated types, that is, the types of the directly
   /// instantiated classes.
   ///
@@ -237,13 +211,6 @@
   // TODO(johnniwinther): Improve semantic precision.
   Iterable<DartType> get instantiatedTypes => _instantiatedTypes;
 
-  /// Returns `true` if [cls] is considered to be instantiated, either directly,
-  /// through subclasses.
-  // TODO(johnniwinther): Improve semantic precision.
-  bool isInstantiated(ClassElement cls) {
-    return _allInstantiatedClasses.contains(cls.declaration);
-  }
-
   /// Returns `true` if [cls] is considered to be implemented by an
   /// instantiated class, either directly, through subclasses or through
   /// subtypes. The latter case only contains spurious information from
@@ -261,6 +228,7 @@
   // TODO(johnniwinther): Support unknown type arguments for generic types.
   void registerTypeInstantiation(InterfaceType type,
                                  {bool byMirrors: false,
+                                  bool isNative: false,
                                   void onImplemented(ClassElement cls)}) {
     _instantiatedTypes.add(type);
     ClassElement cls = type.element;
@@ -269,7 +237,7 @@
         // classes; a native abstract class may have non-abstract subclasses
         // not declared to the program.  Instances of these classes are
         // indistinguishable from the abstract class.
-        || cls.isNative
+        || isNative
         // Likewise, if this registration comes from the mirror system,
         // all bets are off.
         // TODO(herhut): Track classes required by mirrors seperately.
@@ -287,12 +255,6 @@
         }
       });
     }
-    while (cls != null) {
-      if (!_allInstantiatedClasses.add(cls)) {
-        return;
-      }
-      cls = cls.superclass;
-    }
   }
 
   bool _hasMatchingSelector(Map<Selector, SelectorConstraints> selectors,
@@ -315,31 +277,31 @@
   }
 
   bool hasInvokedGetter(Element member, World world) {
-    return _hasMatchingSelector(_invokedGetters[member.name], member, world);
+    return _hasMatchingSelector(_invokedGetters[member.name], member, world) ||
+        member.isFunction && methodsNeedingSuperGetter.contains(member);
   }
 
   bool hasInvokedSetter(Element member, World world) {
     return _hasMatchingSelector(_invokedSetters[member.name], member, world);
   }
 
-  bool registerInvocation(UniverseSelector selector) {
-    return _registerNewSelector(selector, _invokedNames);
-  }
-
-  bool registerInvokedGetter(UniverseSelector selector) {
-    return _registerNewSelector(selector, _invokedGetters);
-  }
-
-  bool registerInvokedSetter(UniverseSelector selector) {
-    return _registerNewSelector(selector, _invokedSetters);
+  bool registerDynamicUse(DynamicUse dynamicUse) {
+    switch (dynamicUse.kind) {
+      case DynamicUseKind.INVOKE:
+        return _registerNewSelector(dynamicUse, _invokedNames);
+      case DynamicUseKind.GET:
+        return _registerNewSelector(dynamicUse, _invokedGetters);
+      case DynamicUseKind.SET:
+        return _registerNewSelector(dynamicUse, _invokedSetters);
+    }
   }
 
   bool _registerNewSelector(
-      UniverseSelector universeSelector,
+      DynamicUse dynamicUse,
       Map<String, Map<Selector, SelectorConstraints>> selectorMap) {
-    Selector selector = universeSelector.selector;
+    Selector selector = dynamicUse.selector;
     String name = selector.name;
-    ReceiverConstraint mask = universeSelector.mask;
+    ReceiverConstraint mask = dynamicUse.mask;
     Map<Selector, SelectorConstraints> selectors = selectorMap.putIfAbsent(
         name, () => new Maplet<Selector, SelectorConstraints>());
     UniverseSelectorConstraints constraints = selectors.putIfAbsent(
@@ -390,11 +352,30 @@
     return type;
   }
 
-  void registerStaticFieldUse(FieldElement staticField) {
-    assert(Elements.isStaticOrTopLevel(staticField) && staticField.isField);
-    assert(staticField.isDeclaration);
-
-    allReferencedStaticFields.add(staticField);
+  void registerStaticUse(StaticUse staticUse) {
+    Element element = staticUse.element;
+    if (Elements.isStaticOrTopLevel(element) && element.isField) {
+      allReferencedStaticFields.add(element);
+    }
+    switch (staticUse.kind) {
+      case StaticUseKind.STATIC_TEAR_OFF:
+        staticFunctionsNeedingGetter.add(element);
+        break;
+      case StaticUseKind.FIELD_GET:
+        fieldGetters.add(element);
+        break;
+      case StaticUseKind.FIELD_SET:
+        fieldSetters.add(element);
+        break;
+      case StaticUseKind.SUPER_TEAR_OFF:
+        methodsNeedingSuperGetter.add(element);
+        break;
+      case StaticUseKind.GENERAL:
+        break;
+      case StaticUseKind.CLOSURE:
+        allClosures.add(element);
+        break;
+    }
   }
 
   void forgetElement(Element element, Compiler compiler) {
@@ -404,7 +385,6 @@
     fieldSetters.remove(element);
     fieldGetters.remove(element);
     _directlyInstantiatedClasses.remove(element);
-    _allInstantiatedClasses.remove(element);
     if (element is ClassElement) {
       assert(invariant(
           element, element.thisType.isRaw,
diff --git a/pkg/compiler/lib/src/universe/use.dart b/pkg/compiler/lib/src/universe/use.dart
new file mode 100644
index 0000000..b619d5a
--- /dev/null
+++ b/pkg/compiler/lib/src/universe/use.dart
@@ -0,0 +1,315 @@
+// 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.
+
+/// This library defined `uses`. A `use` is a single impact of the world, for
+/// instance an invocation of a top level function or a call to the `foo()`
+/// method on an unknown class.
+library dart2js.universe.use;
+
+import '../closure.dart' show
+  BoxFieldElement;
+import '../common.dart';
+import '../dart_types.dart';
+import '../elements/elements.dart';
+import '../world.dart' show
+    ClassWorld;
+import '../util/util.dart' show
+    Hashing;
+
+import 'call_structure.dart' show
+    CallStructure;
+import 'selector.dart' show
+    Selector;
+import 'universe.dart' show
+    ReceiverConstraint;
+
+
+enum DynamicUseKind {
+  INVOKE,
+  GET,
+  SET,
+}
+
+/// The use of a dynamic property. [selector] defined the name and kind of the
+/// property and [mask] defines the known constraint for the object on which
+/// the property is accessed.
+class DynamicUse {
+  final Selector selector;
+  final ReceiverConstraint mask;
+
+  DynamicUse(this.selector, this.mask);
+
+  bool appliesUnnamed(Element element, ClassWorld world) {
+    return selector.appliesUnnamed(element, world) &&
+        (mask == null || mask.canHit(element, selector, world));
+  }
+
+  DynamicUseKind get kind {
+    if (selector.isGetter) {
+      return DynamicUseKind.GET;
+    } else if (selector.isSetter) {
+      return DynamicUseKind.SET;
+    } else {
+      return DynamicUseKind.INVOKE;
+    }
+  }
+
+  int get hashCode => selector.hashCode * 13 + mask.hashCode * 17;
+
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    if (other is! DynamicUse) return false;
+    return selector == other.selector && mask == other.mask;
+  }
+
+  String toString() => '$selector,$mask';
+}
+
+enum StaticUseKind {
+  GENERAL,
+  STATIC_TEAR_OFF,
+  SUPER_TEAR_OFF,
+  FIELD_GET,
+  FIELD_SET,
+  CLOSURE,
+}
+
+/// Statically known use of an [Element].
+// TODO(johnniwinther): Create backend-specific implementations with better
+// invariants.
+class StaticUse {
+  final Element element;
+  final StaticUseKind kind;
+  final int hashCode;
+
+  StaticUse._(Element element, StaticUseKind kind)
+      : this.element = element,
+        this.kind = kind,
+        this.hashCode = Hashing.objectHash(element, Hashing.objectHash(kind)) {
+    assert(invariant(element, element.isDeclaration,
+        message: "Static use element $element must be "
+                 "the declaration element."));
+  }
+
+  /// Invocation of a static or top-level [element] with the given
+  /// [callStructure].
+  factory StaticUse.staticInvoke(MethodElement element,
+                                 CallStructure callStructure) {
+    // TODO(johnniwinther): Use the [callStructure].
+    assert(invariant(element, element.isStatic || element.isTopLevel,
+        message: "Static invoke element $element must be a top-level "
+                 "or static method."));
+    return new StaticUse._(element, StaticUseKind.GENERAL);
+  }
+
+  /// Closurization of a static or top-level function [element].
+  factory StaticUse.staticTearOff(MethodElement element) {
+    assert(invariant(element, element.isStatic || element.isTopLevel,
+        message: "Static tear-off element $element must be a top-level "
+                 "or static method."));
+    return new StaticUse._(element, StaticUseKind.STATIC_TEAR_OFF);
+  }
+
+  /// Read access of a static or top-level field or getter [element].
+  factory StaticUse.staticGet(MemberElement element) {
+    assert(invariant(element, element.isStatic || element.isTopLevel,
+        message: "Static get element $element must be a top-level "
+                 "or static method."));
+    assert(invariant(element, element.isField || element.isGetter,
+        message: "Static get element $element must be a field or a getter."));
+    return new StaticUse._(element, StaticUseKind.GENERAL);
+  }
+
+  /// Write access of a static or top-level field or setter [element].
+  factory StaticUse.staticSet(MemberElement element) {
+    assert(invariant(element, element.isStatic || element.isTopLevel,
+        message: "Static set element $element must be a top-level "
+                 "or static method."));
+    assert(invariant(element, element.isField || element.isSetter,
+        message: "Static set element $element must be a field or a setter."));
+    return new StaticUse._(element, StaticUseKind.GENERAL);
+  }
+
+  /// Invocation of the lazy initializer for a static or top-level field
+  /// [element].
+  factory StaticUse.staticInit(FieldElement element) {
+    assert(invariant(element, element.isStatic || element.isTopLevel,
+        message: "Static init element $element must be a top-level "
+                 "or static method."));
+    assert(invariant(element, element.isField,
+        message: "Static init element $element must be a field."));
+    return new StaticUse._(element, StaticUseKind.GENERAL);
+  }
+
+  /// Invocation of a super method [element] with the given [callStructure].
+  factory StaticUse.superInvoke(MethodElement element,
+                                CallStructure callStructure) {
+    // TODO(johnniwinther): Use the [callStructure].
+    assert(invariant(element, element.isInstanceMember,
+        message: "Super invoke element $element must be an instance method."));
+    return new StaticUse._(element, StaticUseKind.GENERAL);
+  }
+
+  /// Read access of a super field or getter [element].
+  factory StaticUse.superGet(MemberElement element) {
+    assert(invariant(element, element.isInstanceMember,
+        message: "Super get element $element must be an instance method."));
+    assert(invariant(element, element.isField || element.isGetter,
+        message: "Super get element $element must be a field or a getter."));
+    return new StaticUse._(element, StaticUseKind.GENERAL);
+  }
+
+  /// Write access of a super field or setter [element].
+  factory StaticUse.superSet(Element element) {
+    assert(invariant(element, element.isInstanceMember,
+        message: "Super set element $element must be an instance method."));
+    assert(invariant(element, element.isField || element.isSetter,
+        message: "Super set element $element must be a field or a setter."));
+    return new StaticUse._(element, StaticUseKind.GENERAL);
+  }
+
+  /// Closurization of a super method [element].
+  factory StaticUse.superTearOff(MethodElement element) {
+    assert(invariant(element, element.isInstanceMember && element.isFunction,
+        message: "Super invoke element $element must be an instance method."));
+    return new StaticUse._(element, StaticUseKind.SUPER_TEAR_OFF);
+  }
+
+  /// Invocation of a constructor [element] through a this or super
+  /// constructor call with the given [callStructure].
+  factory StaticUse.superConstructorInvoke(Element element,
+                                           CallStructure callStructure) {
+    // TODO(johnniwinther): Use the [callStructure].
+    assert(invariant(element,
+        element.isGenerativeConstructor,
+        message: "Constructor invoke element $element must be a "
+                 "generative constructor."));
+    return new StaticUse._(element, StaticUseKind.GENERAL);
+  }
+
+  /// Invocation of a constructor (body) [element] through a this or super
+  /// constructor call with the given [callStructure].
+  factory StaticUse.constructorBodyInvoke(ConstructorBodyElement element,
+                                          CallStructure callStructure) {
+    // TODO(johnniwinther): Use the [callStructure].
+    return new StaticUse._(element, StaticUseKind.GENERAL);
+  }
+
+  /// Constructor invocation of [element] with the given [callStructure].
+  factory StaticUse.constructorInvoke(ConstructorElement element,
+                                      CallStructure callStructure) {
+    // TODO(johnniwinther): Use the [callStructure].
+    return new StaticUse._(element, StaticUseKind.GENERAL);
+  }
+
+  /// Constructor redirection to [element].
+  factory StaticUse.constructorRedirect(ConstructorElement element) {
+    return new StaticUse._(element, StaticUseKind.GENERAL);
+  }
+
+  /// Initialization of an instance field [element].
+  factory StaticUse.fieldInit(FieldElement element) {
+    assert(invariant(element, element.isInstanceMember,
+        message: "Field init element $element must be an instance field."));
+    return new StaticUse._(element, StaticUseKind.GENERAL);
+  }
+
+  /// Read access of an instance field or boxed field [element].
+  factory StaticUse.fieldGet(Element element) {
+    assert(invariant(element,
+        element.isInstanceMember || element is BoxFieldElement,
+        message: "Field init element $element must be an instance "
+                 "or boxed field."));
+    return new StaticUse._(element, StaticUseKind.FIELD_GET);
+  }
+
+  /// Write access of an instance field or boxed field [element].
+  factory StaticUse.fieldSet(Element element) {
+    assert(invariant(element,
+        element.isInstanceMember || element is BoxFieldElement,
+        message: "Field init element $element must be an instance "
+                 "or boxed field."));
+    return new StaticUse._(element, StaticUseKind.FIELD_SET);
+  }
+
+  /// Read of a local function [element].
+  factory StaticUse.closure(LocalFunctionElement element) {
+    return new StaticUse._(element, StaticUseKind.CLOSURE);
+  }
+
+  /// Unknown use of [element].
+  @deprecated
+  factory StaticUse.foreignUse(Element element) {
+    return new StaticUse._(element, StaticUseKind.GENERAL);
+  }
+
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    if (other is! StaticUse) return false;
+    return element == other.element &&
+           kind == other.kind;
+  }
+
+  String toString() => 'StaticUse($element,$kind)';
+}
+
+enum TypeUseKind {
+  IS_CHECK,
+  AS_CAST,
+  CHECKED_MODE_CHECK,
+  CATCH_TYPE,
+  TYPE_LITERAL,
+  INSTANTIATION,
+}
+
+/// Use of a [DartType].
+class TypeUse {
+  final DartType type;
+  final TypeUseKind kind;
+  final int hashCode;
+
+  TypeUse._(DartType type, TypeUseKind kind)
+      : this.type = type,
+        this.kind = kind,
+        this.hashCode = Hashing.objectHash(type, Hashing.objectHash(kind));
+
+  /// [type] used in an is check, like `e is T` or `e is! T`.
+  factory TypeUse.isCheck(DartType type) {
+    return new TypeUse._(type, TypeUseKind.IS_CHECK);
+  }
+
+  /// [type] used in an as cast, like `e as T`.
+  factory TypeUse.asCast(DartType type) {
+    return new TypeUse._(type, TypeUseKind.AS_CAST);
+  }
+
+  /// [type] used as a type annotation, like `T foo;`.
+  factory TypeUse.checkedModeCheck(DartType type) {
+    return new TypeUse._(type, TypeUseKind.CHECKED_MODE_CHECK);
+  }
+
+  /// [type] used in a on type catch clause, like `try {} on T catch (e) {}`.
+  factory TypeUse.catchType(DartType type) {
+    return new TypeUse._(type, TypeUseKind.CATCH_TYPE);
+  }
+
+  /// [type] used as a type literal, like `foo() => T;`.
+  factory TypeUse.typeLiteral(DartType type) {
+    return new TypeUse._(type, TypeUseKind.TYPE_LITERAL);
+  }
+
+  /// [type] used in an instantiation, like `new T();`.
+  factory TypeUse.instantiation(InterfaceType type) {
+    return new TypeUse._(type, TypeUseKind.INSTANTIATION);
+  }
+
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    if (other is! TypeUse) return false;
+    return type == other.type &&
+           kind == other.kind;
+  }
+
+  String toString() => 'TypeUse($type,$kind)';
+}
\ No newline at end of file
diff --git a/pkg/compiler/lib/src/universe/world_impact.dart b/pkg/compiler/lib/src/universe/world_impact.dart
new file mode 100644
index 0000000..fe7822d
--- /dev/null
+++ b/pkg/compiler/lib/src/universe/world_impact.dart
@@ -0,0 +1,163 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.universe.world_impact;
+
+import '../dart_types.dart' show
+    DartType,
+    InterfaceType;
+import '../elements/elements.dart' show
+    Element,
+    LocalFunctionElement,
+    MethodElement;
+import '../util/util.dart' show
+    Setlet;
+
+import 'use.dart' show
+    DynamicUse,
+    StaticUse,
+    TypeUse;
+
+class WorldImpact {
+  const WorldImpact();
+
+  Iterable<DynamicUse> get dynamicUses =>
+      const <DynamicUse>[];
+
+  Iterable<StaticUse> get staticUses => const <StaticUse>[];
+
+  // TODO(johnniwinther): Replace this by called constructors with type
+  // arguments.
+  // TODO(johnniwinther): Collect all checked types for checked mode separately
+  // to support serialization.
+
+  Iterable<TypeUse> get typeUses => const <TypeUse>[];
+
+  String toString() => dump(this);
+
+  static String dump(WorldImpact worldImpact) {
+    StringBuffer sb = new StringBuffer();
+    printOn(sb, worldImpact);
+    return sb.toString();
+  }
+
+  static void printOn(StringBuffer sb, WorldImpact worldImpact) {
+    void add(String title, Iterable iterable) {
+      if (iterable.isNotEmpty) {
+        sb.write('\n $title:');
+        iterable.forEach((e) => sb.write('\n  $e'));
+      }
+    }
+
+    add('dynamic uses', worldImpact.dynamicUses);
+    add('static uses', worldImpact.staticUses);
+    add('type uses', worldImpact.typeUses);
+  }
+}
+
+class WorldImpactBuilder {
+  // TODO(johnniwinther): Do we benefit from lazy initialization of the
+  // [Setlet]s?
+  Setlet<DynamicUse> _dynamicUses;
+  Setlet<StaticUse> _staticUses;
+  Setlet<TypeUse> _typeUses;
+
+  void registerDynamicUse(DynamicUse dynamicUse) {
+    assert(dynamicUse != null);
+    if (_dynamicUses == null) {
+      _dynamicUses = new Setlet<DynamicUse>();
+    }
+    _dynamicUses.add(dynamicUse);
+  }
+
+  Iterable<DynamicUse> get dynamicUses {
+    return _dynamicUses != null
+        ? _dynamicUses : const <DynamicUse>[];
+  }
+
+  void registerTypeUse(TypeUse typeUse) {
+    assert(typeUse != null);
+    if (_typeUses == null) {
+      _typeUses = new Setlet<TypeUse>();
+    }
+    _typeUses.add(typeUse);
+  }
+
+  Iterable<TypeUse> get typeUses {
+    return _typeUses != null
+        ? _typeUses : const <TypeUse>[];
+  }
+
+  void registerStaticUse(StaticUse staticUse) {
+    assert(staticUse != null);
+    if (_staticUses == null) {
+      _staticUses = new Setlet<StaticUse>();
+    }
+    _staticUses.add(staticUse);
+  }
+
+  Iterable<StaticUse> get staticUses {
+    return _staticUses != null ? _staticUses : const <StaticUse>[];
+  }
+}
+
+/// Mutable implementation of [WorldImpact] used to transform
+/// [ResolutionImpact] or [CodegenImpact] to [WorldImpact].
+class TransformedWorldImpact implements WorldImpact {
+  final WorldImpact worldImpact;
+
+  Setlet<StaticUse> _staticUses;
+  Setlet<TypeUse> _typeUses;
+  Setlet<DynamicUse> _dynamicUses;
+
+  TransformedWorldImpact(this.worldImpact);
+
+  @override
+  Iterable<DynamicUse> get dynamicUses {
+    return _dynamicUses != null
+        ? _dynamicUses : worldImpact.dynamicUses;
+  }
+
+  void registerDynamicUse(DynamicUse dynamicUse) {
+    if (_dynamicUses == null) {
+      _dynamicUses = new Setlet<DynamicUse>();
+      _dynamicUses.addAll(worldImpact.dynamicUses);
+    }
+    _dynamicUses.add(dynamicUse);
+  }
+
+  void registerTypeUse(TypeUse typeUse) {
+    if (_typeUses == null) {
+      _typeUses = new Setlet<TypeUse>();
+      _typeUses.addAll(worldImpact.typeUses);
+    }
+    _typeUses.add(typeUse);
+  }
+
+  @override
+  Iterable<TypeUse> get typeUses {
+    return _typeUses != null
+        ? _typeUses : worldImpact.typeUses;
+  }
+
+  void registerStaticUse(StaticUse staticUse) {
+    if (_staticUses == null) {
+      _staticUses = new Setlet<StaticUse>();
+      _staticUses.addAll(worldImpact.staticUses);
+    }
+    _staticUses.add(staticUse);
+  }
+
+  @override
+  Iterable<StaticUse> get staticUses {
+    return _staticUses != null ? _staticUses : worldImpact.staticUses;
+  }
+
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.write('TransformedWorldImpact($worldImpact)');
+    WorldImpact.printOn(sb, this);
+    return sb.toString();
+  }
+}
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index b8c6387..b4860b8 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -11,6 +11,8 @@
     Backend;
 import 'compiler.dart' show
     Compiler;
+import 'core_types.dart' show
+    CoreClasses;
 import 'dart_types.dart';
 import 'elements/elements.dart' show
     ClassElement,
@@ -60,9 +62,16 @@
   /// The [ClassElement] for the [String] class defined in 'dart:core'.
   ClassElement get stringClass;
 
-  /// Returns `true` if [cls] is instantiated.
+  /// Returns `true` if [cls] is either directly or indirectly instantiated.
   bool isInstantiated(ClassElement cls);
 
+  /// Returns `true` if [cls] is directly instantiated.
+  bool isDirectlyInstantiated(ClassElement cls);
+
+  /// Returns `true` if [cls] is indirectly instantiated, that is through a
+  /// subclass.
+  bool isIndirectlyInstantiated(ClassElement cls);
+
   /// Returns `true` if [cls] is implemented by an instantiated class.
   bool isImplemented(ClassElement cls);
 
@@ -104,6 +113,16 @@
   /// Returns `true` if all live classes that implement [cls] extend it.
   bool hasOnlySubclasses(ClassElement cls);
 
+  /// Returns the most specific subclass of [cls] (including [cls]) that is
+  /// directly instantiated or a superclass of all directly instantiated
+  /// subclasses. If [cls] is not instantiated, `null` is returned.
+  ClassElement getLubOfInstantiatedSubclasses(ClassElement cls);
+
+  /// Returns the most specific subtype of [cls] (including [cls]) that is
+  /// directly instantiated or a superclass of all directly instantiated
+  /// subtypes. If no subtypes of [cls] are instantiated, `null` is returned.
+  ClassElement getLubOfInstantiatedSubtypes(ClassElement cls);
+
   /// Returns an iterable over the common supertypes of the [classes].
   Iterable<ClassElement> commonSupertypesOf(Iterable<ClassElement> classes);
 
@@ -135,14 +154,14 @@
 }
 
 class World implements ClassWorld {
-  ClassElement get objectClass => compiler.objectClass;
-  ClassElement get functionClass => compiler.functionClass;
-  ClassElement get boolClass => compiler.boolClass;
-  ClassElement get numClass => compiler.numClass;
-  ClassElement get intClass => compiler.intClass;
-  ClassElement get doubleClass => compiler.doubleClass;
-  ClassElement get stringClass => compiler.stringClass;
-  ClassElement get nullClass => compiler.nullClass;
+  ClassElement get objectClass => coreClasses.objectClass;
+  ClassElement get functionClass => coreClasses.functionClass;
+  ClassElement get boolClass => coreClasses.boolClass;
+  ClassElement get numClass => coreClasses.numClass;
+  ClassElement get intClass => coreClasses.intClass;
+  ClassElement get doubleClass => coreClasses.doubleClass;
+  ClassElement get stringClass => coreClasses.stringClass;
+  ClassElement get nullClass => coreClasses.nullClass;
 
   /// Cache of [ti.FlatTypeMask]s grouped by the 8 possible values of the
   /// [ti.FlatTypeMask.flags] property.
@@ -188,10 +207,22 @@
     return false;
   }
 
-  /// Returns `true` if [cls] is instantiated either directly or through a
-  /// subclass.
+  @override
   bool isInstantiated(ClassElement cls) {
-    return compiler.resolverWorld.isInstantiated(cls);
+    ClassHierarchyNode node = _classHierarchyNodes[cls.declaration];
+    return node != null && node.isInstantiated;
+  }
+
+  @override
+  bool isDirectlyInstantiated(ClassElement cls) {
+    ClassHierarchyNode node = _classHierarchyNodes[cls.declaration];
+    return node != null && node.isDirectlyInstantiated;
+  }
+
+  @override
+  bool isIndirectlyInstantiated(ClassElement cls) {
+    ClassHierarchyNode node = _classHierarchyNodes[cls.declaration];
+    return node != null && node.isIndirectlyInstantiated;
   }
 
   /// Returns `true` if [cls] is implemented by an instantiated class.
@@ -285,6 +316,20 @@
     return subclasses != null && (subclasses.length == subtypes.length);
   }
 
+  @override
+  ClassElement getLubOfInstantiatedSubclasses(ClassElement cls) {
+    ClassHierarchyNode hierarchy = _classHierarchyNodes[cls.declaration];
+    return hierarchy != null
+        ? hierarchy.getLubOfInstantiatedSubclasses() : null;
+  }
+
+  @override
+  ClassElement getLubOfInstantiatedSubtypes(ClassElement cls) {
+    ClassSet classSet = _classSets[cls.declaration];
+    return classSet != null
+        ? classSet.getLubOfInstantiatedSubtypes() : null;
+  }
+
   /// Returns an iterable over the common supertypes of the [classes].
   Iterable<ClassElement> commonSupertypesOf(Iterable<ClassElement> classes) {
     Iterator<ClassElement> iterator = classes.iterator;
@@ -433,14 +478,19 @@
         this.compiler = compiler,
         alreadyPopulated = compiler.cacheStrategy.newSet();
 
+  CoreClasses get coreClasses => compiler.coreClasses;
+
   DiagnosticReporter get reporter => compiler.reporter;
 
   /// Called to add [cls] to the set of known classes.
   ///
   /// This ensures that class hierarchy queries can be performed on [cls] and
   /// classes that extend or implement it.
-  void registerClass(ClassElement cls) {
+  void registerClass(ClassElement cls, {bool isDirectlyInstantiated: false}) {
     _ensureClassSet(cls);
+    if (isDirectlyInstantiated) {
+      _updateClassHierarchyNodeForClass(cls, directlyInstantiated: true);
+    }
   }
 
   /// Returns [ClassHierarchyNode] for [cls] used to model the class hierarchies
@@ -488,29 +538,36 @@
     });
   }
 
+  void _updateClassHierarchyNodeForClass(
+      ClassElement cls,
+      {bool directlyInstantiated: false,
+       bool indirectlyInstantiated: false}) {
+    ClassHierarchyNode node = getClassHierarchyNode(cls);
+    bool changed = false;
+    if (directlyInstantiated && !node.isDirectlyInstantiated) {
+      node.isDirectlyInstantiated = true;
+      changed = true;
+    }
+    if (indirectlyInstantiated && !node.isIndirectlyInstantiated) {
+      node.isIndirectlyInstantiated = true;
+      changed = true;
+    }
+    if (changed && cls.superclass != null) {
+      _updateClassHierarchyNodeForClass(
+          cls.superclass, indirectlyInstantiated: true);
+    }
+    // Ensure that classes implicitly implementing `Function` are in its
+    // subtype set.
+    if (cls != coreClasses.functionClass &&
+        cls.implementsFunction(compiler)) {
+      ClassSet subtypeSet = _ensureClassSet(coreClasses.functionClass);
+      subtypeSet.addSubtype(node);
+    }
+  }
+
   void populate() {
     /// Updates the `isDirectlyInstantiated` and `isIndirectlyInstantiated`
     /// properties of the [ClassHierarchyNode] for [cls].
-    void updateClassHierarchyNodeForClass(
-        ClassElement cls,
-        {bool directlyInstantiated: false,
-         bool indirectlyInstantiated: false}) {
-      assert(!directlyInstantiated || isInstantiated(cls));
-      ClassHierarchyNode node = getClassHierarchyNode(cls);
-      bool changed = false;
-      if (directlyInstantiated && !node.isDirectlyInstantiated) {
-        node.isDirectlyInstantiated = true;
-        changed = true;
-      }
-      if (indirectlyInstantiated && !node.isIndirectlyInstantiated) {
-        node.isIndirectlyInstantiated = true;
-        changed = true;
-      }
-      if (changed && cls.superclass != null) {
-        updateClassHierarchyNodeForClass(
-            cls.superclass, indirectlyInstantiated: true);
-      }
-    }
 
     void addSubtypes(ClassElement cls) {
       if (compiler.hasIncrementalSupport && !alreadyPopulated.add(cls)) {
@@ -521,7 +578,7 @@
         reporter.internalError(cls, 'Class "${cls.name}" is not resolved.');
       }
 
-      updateClassHierarchyNodeForClass(cls, directlyInstantiated: true);
+      _updateClassHierarchyNodeForClass(cls, directlyInstantiated: true);
 
       // Walk through the superclasses, and record the types
       // implemented by that type on the superclasses.
@@ -552,7 +609,7 @@
     } else {
       sb.write("Instantiated classes in the closed world:\n");
     }
-    getClassHierarchyNode(compiler.objectClass)
+    getClassHierarchyNode(coreClasses.objectClass)
         .printOn(sb, ' ', instantiatedOnly: cls == null, withRespectTo: cls);
     return sb.toString();
   }
@@ -610,7 +667,7 @@
 
   bool fieldNeverChanges(Element element) {
     if (!element.isField) return false;
-    if (element.isNative) {
+    if (backend.isNative(element)) {
       // Some native fields are views of data that may be changed by operations.
       // E.g. node.firstChild depends on parentNode.removeBefore(n1, n2).
       // TODO(sra): Refine the effect classification so that native effects are
diff --git a/pkg/compiler/samples/darttags/darttags.dart b/pkg/compiler/samples/darttags/darttags.dart
index 2000b9b..84b7562 100644
--- a/pkg/compiler/samples/darttags/darttags.dart
+++ b/pkg/compiler/samples/darttags/darttags.dart
@@ -87,10 +87,11 @@
   // Prepend "dart:" to the names.
   uris.addAll(names.map((String name) => Uri.parse('dart:$name')));
 
-  Uri libraryRoot = myLocation.resolve(SDK_ROOT);
+  Uri platformConfigUri = myLocation.resolve(SDK_ROOT)
+      .resolve("lib/dart2js_shared_sdk");
   Uri packageRoot = Uri.base.resolve(Platform.packageRoot);
 
-  analyze(uris, libraryRoot, packageRoot, handler.provider, handler)
+  analyze(uris, platformConfigUri, packageRoot, handler.provider, handler)
       .then(processMirrors);
 }
 
diff --git a/pkg/compiler/samples/jsonify/jsonify.dart b/pkg/compiler/samples/jsonify/jsonify.dart
index 7638ca5..152f39e 100644
--- a/pkg/compiler/samples/jsonify/jsonify.dart
+++ b/pkg/compiler/samples/jsonify/jsonify.dart
@@ -2,6 +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.
 
+import 'dart:async';
 import 'dart:io';
 import 'dart:convert';
 
@@ -65,30 +66,39 @@
 
 jsonify(MirrorSystem mirrors) {
   var map = <String, String>{};
+  List<Future> futures = <Future>[];
+
+  Future mapUri(Uri uri) {
+    String filename = relativize(sdkRoot, uri, false);
+    return handler.provider.readStringFromUri(uri).then((contents) {
+      map['sdk:/$filename'] = contents;
+    });
+  }
 
   mirrors.libraries.forEach((_, LibraryMirror library) {
     BackDoor.compilationUnitsOf(library).forEach((compilationUnit) {
-      Uri uri = compilationUnit.uri;
-      String filename = relativize(sdkRoot, uri, false);
-      SourceFile file = handler.provider.sourceFiles[uri];
-      map['sdk:/$filename'] = file.slowText();
+      futures.add(mapUri(compilationUnit.uri));
     });
   });
 
   libraries.forEach((name, info) {
     var patch = info.dart2jsPatchPath;
     if (patch != null) {
-      Uri uri = sdkRoot.resolve('sdk/lib/$patch');
-      String filename = relativize(sdkRoot, uri, false);
-      SourceFile file = handler.provider.sourceFiles[uri];
-      map['sdk:/$filename'] = file.slowText();
+      futures.add(mapUri(sdkRoot.resolve('sdk/lib/$patch')));
     }
   });
 
-  if (outputJson) {
-    output.writeStringSync(JSON.encode(map));
-  } else {
-    output.writeStringSync('''
+  for (String filename in ["dart_client.platform",
+                           "dart_server.platform",
+                           "dart_shared.platform"]) {
+    futures.add(mapUri(sdkRoot.resolve('sdk/lib/$filename')));
+  }
+
+  Future.wait(futures).then((_) {
+    if (outputJson) {
+      output.writeStringSync(JSON.encode(map));
+    } else {
+      output.writeStringSync('''
 // 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.
@@ -99,8 +109,9 @@
 library dart.sdk_sources;
 
 const Map<String, String> SDK_SOURCES = const <String, String>''');
-    output.writeStringSync(JSON.encode(map).replaceAll(r'$', r'\$'));
-    output.writeStringSync(';\n');
-  }
-  output.closeSync();
+      output.writeStringSync(JSON.encode(map).replaceAll(r'$', r'\$'));
+      output.writeStringSync(';\n');
+    }
+    output.closeSync();
+  });
 }
diff --git a/pkg/dart2js_incremental/lib/caching_compiler.dart b/pkg/dart2js_incremental/lib/caching_compiler.dart
index 2bc2047..4185df1 100644
--- a/pkg/dart2js_incremental/lib/caching_compiler.dart
+++ b/pkg/dart2js_incremental/lib/caching_compiler.dart
@@ -6,12 +6,12 @@
 
 /// Do not call this method directly. It will be made private.
 // TODO(ahe): Make this method private.
-Future<Compiler> reuseCompiler(
+Future<CompilerImpl> reuseCompiler(
     {CompilerDiagnostics diagnosticHandler,
      CompilerInput inputProvider,
      CompilerOutput outputProvider,
      List<String> options: const [],
-     Compiler cachedCompiler,
+     CompilerImpl cachedCompiler,
      Uri libraryRoot,
      Uri packageRoot,
      bool packagesAreImmutable: false,
@@ -33,7 +33,7 @@
   if (environment == null) {
     environment = {};
   }
-  Compiler compiler = cachedCompiler;
+  CompilerImpl compiler = cachedCompiler;
   if (compiler == null ||
       compiler.libraryRoot != libraryRoot ||
       !compiler.hasIncrementalSupport ||
@@ -53,7 +53,7 @@
       }
     }
     oldTag.makeCurrent();
-    compiler = new Compiler(
+    compiler = new CompilerImpl(
         inputProvider,
         outputProvider,
         diagnosticHandler,
@@ -76,13 +76,16 @@
         ..needsStructuredMemberInfo = true;
 
     Uri core = Uri.parse("dart:core");
-    return compiler.libraryLoader.loadLibrary(core).then((_) {
-      // Likewise, always be prepared for runtimeType support.
-      // TODO(johnniwinther): Add global switch to force RTI.
-      compiler.enabledRuntimeType = true;
-      backend.registerRuntimeType(
-          compiler.enqueuer.resolution, compiler.globalDependencies);
-      return compiler;
+
+    return compiler.setupSdk().then((_) {
+      return compiler.libraryLoader.loadLibrary(core).then((_) {
+        // Likewise, always be prepared for runtimeType support.
+        // TODO(johnniwinther): Add global switch to force RTI.
+        compiler.enabledRuntimeType = true;
+        backend.registerRuntimeType(
+            compiler.enqueuer.resolution, compiler.globalDependencies);
+        return compiler;
+      });
     });
   } else {
     for (final task in compiler.tasks) {
diff --git a/pkg/dart2js_incremental/lib/dart2js_incremental.dart b/pkg/dart2js_incremental/lib/dart2js_incremental.dart
index 12d285c..1ce8039 100644
--- a/pkg/dart2js_incremental/lib/dart2js_incremental.dart
+++ b/pkg/dart2js_incremental/lib/dart2js_incremental.dart
@@ -12,7 +12,7 @@
     UserTag;
 
 import 'package:compiler/src/apiimpl.dart' show
-    Compiler;
+    CompilerImpl;
 
 import 'package:compiler/compiler_new.dart' show
     CompilerDiagnostics,
@@ -59,7 +59,7 @@
   final List<String> _updates = <String>[];
   final IncrementalCompilerContext _context = new IncrementalCompilerContext();
 
-  Compiler _compiler;
+  CompilerImpl _compiler;
 
   IncrementalCompiler({
       this.libraryRoot,
@@ -86,16 +86,16 @@
 
   LibraryElement get mainApp => _compiler.mainApp;
 
-  Compiler get compiler => _compiler;
+  CompilerImpl get compiler => _compiler;
 
   Future<bool> compile(Uri script) {
-    return _reuseCompiler(null).then((Compiler compiler) {
+    return _reuseCompiler(null).then((CompilerImpl compiler) {
       _compiler = compiler;
       return compiler.run(script);
     });
   }
 
-  Future<Compiler> _reuseCompiler(
+  Future<CompilerImpl> _reuseCompiler(
       Future<bool> reuseLibrary(LibraryElement library)) {
     List<String> options = this.options == null
         ? <String> [] : new List<String>.from(this.options);
@@ -124,7 +124,7 @@
     }
     Future mappingInputProvider(Uri uri) {
       Uri updatedFile = updatedFiles[uri];
-      return inputProvider(updatedFile == null ? uri : updatedFile);
+      return inputProvider.readFromUri(updatedFile == null ? uri : updatedFile);
     }
     LibraryUpdater updater = new LibraryUpdater(
         _compiler,
@@ -133,8 +133,8 @@
         logVerbose,
         _context);
     _context.registerUriWithUpdates(updatedFiles.keys);
-    Future<Compiler> future = _reuseCompiler(updater.reuseLibrary);
-    return future.then((Compiler compiler) {
+    Future<CompilerImpl> future = _reuseCompiler(updater.reuseLibrary);
+    return future.then((CompilerImpl compiler) {
       _compiler = compiler;
       if (compiler.compilationFailed) {
         return null;
@@ -157,9 +157,7 @@
   return main(args);
 }""", {'updates': updates, 'helper': backend.namer.accessIncrementalHelper});
 
-    jsAst.Printer printer = new jsAst.Printer(_compiler, null);
-    printer.blockOutWithoutBraces(mainRunner);
-    return printer.outBuffer.getText();
+    return jsAst.prettyPrint(mainRunner, _compiler).getText();
   }
 }
 
diff --git a/pkg/js/CHANGELOG.md b/pkg/js/CHANGELOG.md
new file mode 100644
index 0000000..4ef2ebc
--- /dev/null
+++ b/pkg/js/CHANGELOG.md
@@ -0,0 +1,3 @@
+## 0.6.0
+
+ * Version 0.6.0 is a complete rewrite of `package:js`.
diff --git a/pkg/js/README.md b/pkg/js/README.md
index d27b6eb..3ba66d1 100644
--- a/pkg/js/README.md
+++ b/pkg/js/README.md
@@ -1,21 +1,8 @@
-Dart-JavaScript Interop
-=======================
+Methods and annotations to specify interoperability with JavaScript APIs.
 
-Status
-------
+*This packages requires Dart SDK 1.13.0.*
 
-Version 0.6.0 is a complete rewrite of package:js 
-
-The package now only contains annotations specifying the shape of the
-JavaScript API to import into Dart.
-The core implementation is defined directly in Dart2Js, Dartium, and DDC.
-
-**Warning: support in Dartium and Dart2Js is still in progress.
-
-#### Example - TODO(jacobr)
-
-Configuration and Initialization
---------------------------------
+*This is beta software. Please files [issues].*
 
 ### Adding the dependency
 
@@ -23,38 +10,98 @@
 
 ```yaml
 dependencies:
-  js: ">=0.6.0 <0.7.0"
+  js: ^0.6.0
 ```
 
-##### main.html
+### Example
 
-```html
-<html>
-  <head>
-  </head>
-  <body>
-    <script type="application/dart" src="main.dart"></script>
-  </body>
-</html>
-```
+See the [Chart.js Dart API](https://github.com/google/chartjs.dart/) for an
+end-to-end example.
 
-##### main.dart
+### Usage
 
-TODO(jacobr): example under construction.
+#### Calling methods
+
 ```dart
-library main;
+// Calls invoke JavaScript `JSON.stringify(obj)`.
+@JS("JSON.stringify")
+external String stringify(obj);
+```
 
-import 'package:js/js.dart';
+#### Classes and Namespaces
 
-main() {
+```dart
+@JS('google.maps')
+library maps;
+
+// Invokes the JavaScript getter `google.maps.map`.
+external Map get map;
+
+// `new Map` invokes JavaScript `new google.maps.Map(location)`
+@JS()
+class Map {
+  external Map(Location location);
+  external Location getLocation();
+}
+
+// `new Location(...)` invokes JavaScript `new google.maps.LatLng(...)`
+//
+// We recommend against using custom JavaScript names whenever
+// possible. It is easier for users if the JavaScript names and Dart names
+// are consistent.
+@JS("LatLng")
+class Location {
+  external Location(num lat, num lng);
 }
 ```
 
-Contributing and Filing Bugs
-----------------------------
+#### JavaScript object literals
 
-Please file bugs and features requests on the Github issue tracker: https://github.com/dart-lang/js-interop/issues
+Many JavaScript APIs take an object literal as an argument. For example:
+```js
+// JavaScript
+printOptions({responsive: true});
+```
 
-We also love and accept community contributions, from API suggestions to pull requests. Please file an issue before beginning work so we can discuss the design and implementation. We are trying to create issues for all current and future work, so if something there intrigues you (or you need it!) join in on the discussion.
+If you want to use `printOptions` from Dart, you cannot simply pass a Dart `Map`
+object – they are are "opaque" in JavaScript.
 
-All we require is that you sign the Google Individual Contributor License Agreement https://developers.google.com/open-source/cla/individual?csw=1
+
+Instead, create a Dart class with both the `@JS()` and
+`@anonymous` annotations.
+
+```dart
+// Dart
+void main() {
+  printOptions(new Options(responsive: true));
+}
+
+@JS()
+external printOptions(Options options);
+
+@JS()
+@anonymous
+class Options {
+  external bool get responsive;
+
+  external factory Options({bool responsive});
+}
+```
+
+#### Passing functions to JavaScript.
+
+If you are passing a Dart function to a JavaScript API, you must wrap it using
+`allowInterop` or `allowInteropCaptureThis`.
+
+## Contributing and Filing Bugs
+
+Please file bugs and features requests on the [Github issue tracker][issues].
+
+We also love and accept community contributions, from API suggestions to pull requests.
+Please file an issue before beginning work so we can discuss the design and implementation.
+We are trying to create issues for all current and future work, so if something there intrigues you (or you need it!) join in on the discussion.
+
+Code contributors must sign the
+[Google Individual Contributor License Agreement](https://developers.google.com/open-source/cla/individual?csw=1).
+
+[issues]: https://goo.gl/j3rzs0
diff --git a/pkg/js/example/README.md b/pkg/js/example/README.md
new file mode 100644
index 0000000..6e5403e
--- /dev/null
+++ b/pkg/js/example/README.md
@@ -0,0 +1 @@
+See the [Chart.js Dart API](https://github.com/google/chartjs.dart/) for a usage example.
diff --git a/pkg/js/lib/src/varargs.dart b/pkg/js/lib/src/varargs.dart
new file mode 100644
index 0000000..6d316b3
--- /dev/null
+++ b/pkg/js/lib/src/varargs.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Declarations for variable arguments support
+/// (rest params and spread operator).
+///
+/// These are currently *not* supported by dart2js or Dartium.
+library js.varargs;
+
+class _Rest {
+  const _Rest();
+}
+
+/// Annotation to tag ES6 rest parameters (https://goo.gl/r0bJ1K).
+///
+/// This is *not* supported by dart2js or Dartium (yet).
+///
+/// This is meant to be used by the Dart Dev Compiler
+/// when compiling helper functions of its runtime to ES6.
+///
+/// The following function:
+///
+///     foo(a, b, @rest others) { ... }
+///
+/// Will be compiled to ES6 code like the following:
+///
+///     function foo(a, b, ...others) { ... }
+///
+/// Which is roughly equivalent to the following ES5 code:
+///
+///     function foo(a, b/*, ...others*/) {
+///       var others = [].splice.call(arguments, 2);
+///       ...
+///     }
+///
+const _Rest rest = const _Rest();
+
+/// Intrinsic function that maps to the ES6 spread operator
+/// (https://goo.gl/NedHKr).
+///
+/// This is *not* supported by dart2js or Dartium (yet),
+/// and *cannot* be called at runtime.
+///
+/// This is meant to be used by the Dart Dev Compiler when
+/// compiling its runtime to ES6.
+///
+/// The following expression:
+///
+///     foo(a, b, spread(others))
+///
+/// Will be compiled to ES6 code like the following:
+///
+///     foo(a, b, ...others)
+///
+/// Which is roughly equivalent to the following ES5 code:
+///
+///     foo.apply(null, [a, b].concat(others))
+///
+dynamic spread(args) {
+  throw new StateError(
+      'The spread function cannot be called, '
+      'it should be compiled away.');
+}
diff --git a/pkg/js/pubspec.yaml b/pkg/js/pubspec.yaml
index d558126..7555876 100644
--- a/pkg/js/pubspec.yaml
+++ b/pkg/js/pubspec.yaml
@@ -1,9 +1,10 @@
 name: js
-version: 0.6.0-dev.1
+version: 0.6.0
 authors:
 - Dart Team <misc@dartlang.org>
-- Alexandre Ardhuin <alexandre.ardhuin@gmail.com>
 description: Access JavaScript from Dart.
-homepage: https://github.com/dart-lang/js-interop
+homepage: https://github.com/dart-lang/sdk/tree/master/pkg/js
 environment:
-  sdk: '>=1.13.0-dev <2.0.0'
+  sdk: '>=1.13.0 <2.0.0'
+dev_dependencies:
+  browser: '^0.10.0+2'
diff --git a/pkg/js_ast/lib/src/nodes.dart b/pkg/js_ast/lib/src/nodes.dart
index 95c8819..b6d11aa 100644
--- a/pkg/js_ast/lib/src/nodes.dart
+++ b/pkg/js_ast/lib/src/nodes.dart
@@ -985,7 +985,7 @@
 
   int get value;
 
-  int get precedenceLevel => PRIMARY;
+  int get precedenceLevel => value.isNegative ? UNARY : PRIMARY;
 }
 
 /// Interace for a deferred string value. An implementation has to provide
@@ -1074,6 +1074,8 @@
 
   LiteralNumber(this.value);
 
+  int get precedenceLevel => value.startsWith('-') ? UNARY : PRIMARY;
+  
   accept(NodeVisitor visitor) => visitor.visitLiteralNumber(this);
   LiteralNumber _clone() => new LiteralNumber(value);
 }
diff --git a/pkg/js_ast/lib/src/printer.dart b/pkg/js_ast/lib/src/printer.dart
index 7a1124f..b2fd29d 100644
--- a/pkg/js_ast/lib/src/printer.dart
+++ b/pkg/js_ast/lib/src/printer.dart
@@ -933,7 +933,10 @@
       LiteralString selectorString = selector;
       String fieldWithQuotes = selectorString.value;
       if (isValidJavaScriptId(fieldWithQuotes)) {
-        if (access.receiver is LiteralNumber) out(" ", isWhitespace: true);
+        if (access.receiver is LiteralNumber &&
+            lastCharCode != charCodes.$CLOSE_PAREN) {
+          out(" ", isWhitespace: true);
+        }
         out(".");
         startNode(selector);
         out(fieldWithQuotes.substring(1, fieldWithQuotes.length - 1));
@@ -941,7 +944,10 @@
         return;
       }
     } else if (selector is Name) {
-      if (access.receiver is LiteralNumber) out(" ", isWhitespace: true);
+      if (access.receiver is LiteralNumber &&
+          lastCharCode != charCodes.$CLOSE_PAREN) {
+        out(" ", isWhitespace: true);
+      }
       out(".");
       startNode(selector);
       selector.accept(this);
@@ -1487,4 +1493,4 @@
     context.exitNode(node, startPosition, position, closingPosition);
     return parent;
   }
-}
\ No newline at end of file
+}
diff --git a/pkg/pkg.status b/pkg/pkg.status
index e9c99b2..8c76824 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -19,40 +19,70 @@
 unittest/*: Skip # Issue 21949
 lookup_map/*: SkipByDesign
 
-[ $runtime == vm && $mode == debug]
-analysis_server/test/analysis_server_test: SkipSlow  # Times out
-analysis_server/test/completion_test: SkipSlow  # Times out
-analysis_server/test/domain_context_test: SkipSlow  # Times out
-analysis_server/test/domain_server_test: SkipSlow  # Times out
-analysis_server/test/integration/*: SkipSlow # Times out
-analysis_server/tool/spec/check_all_test: SkipSlow # Times out
-analyzer/test/generated/element_test: SkipSlow  # Times out
-analyzer/test/generated/parser_test: SkipSlow  # Times out
+[ $runtime == vm && $mode == debug ]
+analysis_server/test/completion_test: Pass, Slow
 
 [ $runtime == vm && $system == windows]
 analysis_server/test/analysis/get_errors_test: Skip # runtime error, Issue 22180
+analysis_server/test/integration/analysis/analysis_options_test: RuntimeError # Issue 24796
+analyzer/test/generated/all_the_rest_test: Fail # Issue 21772
 
 [ $compiler == dart2js ]
+analysis_server/test/*: Skip # Issue 22161
+analysis_server/test/analysis_notification_highlights_test: Pass, Slow # 19756, 21628
+analysis_server/test/analysis_notification_navigation_test: Pass, Slow # Issue 19756, 21628
+analysis_server/test/analysis_notification_occurrences_test: Pass, Slow # Issue 19756, 21628
+analysis_server/test/analysis_notification_outline_test: Pass, Slow # Issue 19756, 21628
+analysis_server/test/domain_analysis_test: Pass, Slow # Issue 19756, 21628
+analysis_server/test/domain_completion_test: Pass, Slow
+analysis_server/test/edit/assists_test: Pass, Slow
+analysis_server/test/edit/format_test: Pass, Slow
+analysis_server/test/edit/refactoring_test: Pass, Slow # Issue 19756, 21628
+analysis_server/test/search/element_references_test: Pass, Slow
+analysis_server/test/search/top_level_declarations_test: Pass, Slow # 19756, 21628
+analysis_server/test/services/index/store/codec_test: Pass, Slow
+analysis_server/test/socket_server_test: Pass, Slow # Issue 19756, 21628
+analyzer/test/enum_test: Slow, Pass, Fail # Issue 21323
+analyzer/test/generated/all_the_rest_test: Pass, Slow # Issue 21628
+analyzer/test/generated/ast_test: Pass, Slow # Issue 21628
+analyzer/test/generated/compile_time_error_code_test: Pass, Slow
+analyzer/test/generated/compile_time_error_code_test: Pass, Slow # Issue 21628
+analyzer/test/generated/element_test: Pass, Slow # Issue 21628
+analyzer/test/generated/engine_test: SkipSlow
+analyzer/test/generated/incremental_resolver_test: Pass, Slow # Issue 21628
+analyzer/test/generated/incremental_scanner_test: Pass, Slow # Issue 21628
+analyzer/test/generated/non_error_resolver_test: Pass, Slow # Issue 21628
+analyzer/test/generated/parser_test: Pass, Slow # Issue 21628
+analyzer/test/generated/resolver_test: Pass, Slow # Issue 21628
+analyzer/test/generated/scanner_test: Pass, Slow # Issue 21628
+analyzer/test/generated/source_factory_test: Pass, Slow # Issue 21628
+analyzer/test/generated/static_type_warning_code_test: Pass, Slow
+analyzer/test/generated/static_type_warning_code_test: Pass, Slow # Issue 21628
+analyzer/test/generated/static_warning_code_test: Pass, Slow # Issue 21628
+analyzer/test/generated/utilities_test: Pass, Slow # Issue 21628
+analyzer/test/src/context/cache_test: Pass, Slow # Issue 21628
+analyzer/test/src/context/context_test: Pass, Timeout # dartbug.com/23658
+analyzer/test/src/summary/summary_test: Pass, Slow # Issue 21628
+analyzer/test/src/task/dart_test: Pass, Slow # Issue 21628
+analyzer/test/src/task/dart_work_manager_test: Pass, Slow # Issue 21628
+analyzer/test/src/task/driver_test: Pass, Slow # Issue 21628
+analyzer/test/src/task/general_test: Pass, Slow # Issue 21628
+analyzer/test/src/task/html_test: Pass, Slow # Issue 21628
+analyzer/test/src/task/html_work_manager_test: Pass, Slow # Issue 21628
+analyzer/test/src/task/incremental_element_builder_test: Pass, Slow # Issue 21628
+analyzer/test/src/task/inputs_test: Pass, Slow # Issue 21628
+analyzer/test/src/task/manager_test: Pass, Slow # Issue 21628
+analyzer/test/src/task/model_test: Pass, Slow # Issue 21628
+analyzer/test/src/task/options_test: Pass, Slow # Issue 21628
+analyzer/test/src/task/options_work_manager_test: Pass, Slow # Issue 21628
 collection/test/equality_test/01: Fail # Issue 1533
 collection/test/equality_test/02: Fail # Issue 1533
 collection/test/equality_test/03: Fail # Issue 1533
 collection/test/equality_test/04: Fail # Issue 1533
 collection/test/equality_test/05: Fail # Issue 1533
 collection/test/equality_test/none: Pass, Fail # Issue 14348
+lookup_map/test/version_check_test: SkipByDesign # Only meant to run in vm.
 typed_data/test/typed_buffers_test/01: Fail # Not supporting Int64List, Uint64List.
-analyzer/test/generated/engine_test: SkipSlow
-analyzer/test/generated/static_type_warning_code_test: Pass, Slow
-analyzer/test/generated/compile_time_error_code_test: Pass, Slow
-
-analyzer/test/enum_test: Slow, Pass, Fail # Issue 21323
-analyzer/test/src/context/context_test: Pass, Timeout # dartbug.com/23658
-
-analysis_server/test/*: Skip # Issue 22161
-analysis_server/test/search/element_references_test: Pass, Slow
-analysis_server/test/services/index/store/codec_test: Pass, Slow
-analysis_server/test/domain_completion_test: Pass, Slow
-analysis_server/test/edit/assists_test: Pass, Slow
-analysis_server/test/edit/format_test: Pass, Slow
 
 # Analysis server integration tests don't make sense to run under
 # dart2js, since the code under test always runs in the Dart vm as a
@@ -70,41 +100,6 @@
 analysis_server/test/search/element_reference_test: Pass, Slow # Issue 19756
 analysis_server/index/store/codec_test: Pass, Slow # Issue 19756
 
-[ $compiler == dart2js ]
-analysis_server/test/analysis_notification_highlights_test: Pass, Slow # 19756, 21628
-analysis_server/test/analysis_notification_navigation_test: Pass, Slow # Issue 19756, 21628
-analysis_server/test/analysis_notification_occurrences_test: Pass, Slow # Issue 19756, 21628
-analysis_server/test/analysis_notification_outline_test: Pass, Slow # Issue 19756, 21628
-analysis_server/test/domain_analysis_test: Pass, Slow # Issue 19756, 21628
-analysis_server/test/edit/refactoring_test: Pass, Slow # Issue 19756, 21628
-analysis_server/test/search/top_level_declarations_test: Pass, Slow # 19756, 21628
-analysis_server/test/socket_server_test: Pass, Slow # Issue 19756, 21628
-analyzer/test/generated/all_the_rest_test: Pass, Slow # Issue 21628
-analyzer/test/generated/ast_test: Pass, Slow # Issue 21628
-analyzer/test/generated/compile_time_error_code_test: Pass, Slow # Issue 21628
-analyzer/test/generated/element_test: Pass, Slow # Issue 21628
-analyzer/test/generated/incremental_resolver_test: Pass, Slow # Issue 21628
-analyzer/test/generated/incremental_scanner_test: Pass, Slow # Issue 21628
-analyzer/test/generated/non_error_resolver_test: Pass, Slow # Issue 21628
-analyzer/test/generated/parser_test: Pass, Slow # Issue 21628
-analyzer/test/generated/resolver_test: Pass, Slow # Issue 21628
-analyzer/test/generated/scanner_test: Pass, Slow # Issue 21628
-analyzer/test/generated/source_factory_test: Pass, Slow # Issue 21628
-analyzer/test/generated/static_type_warning_code_test: Pass, Slow # Issue 21628
-analyzer/test/generated/static_warning_code_test: Pass, Slow # Issue 21628
-analyzer/test/generated/utilities_test: Pass, Slow # Issue 21628
-analyzer/test/src/context/cache_test: Pass, Slow # Issue 21628
-analyzer/test/src/task/dart_test: Pass, Slow # Issue 21628
-analyzer/test/src/task/dart_work_manager_test: Pass, Slow # Issue 21628
-analyzer/test/src/task/driver_test: Pass, Slow # Issue 21628
-analyzer/test/src/task/general_test: Pass, Slow # Issue 21628
-analyzer/test/src/task/html_work_manager_test: Pass, Slow # Issue 21628
-analyzer/test/src/task/incremental_element_builder_test: Pass, Slow # Issue 21628
-analyzer/test/src/task/inputs_test: Pass, Slow # Issue 21628
-analyzer/test/src/task/manager_test: Pass, Slow # Issue 21628
-analyzer/test/src/task/model_test: Pass, Slow # Issue 21628
-lookup_map/test/version_check_test: SkipByDesign # Only meant to run in vm.
-
 [ $runtime == jsshell ]
 async/test/stream_zip_test: RuntimeError, OK # Timers are not supported.
 
@@ -123,9 +118,6 @@
 # Unexplained errors only occuring on Safari 6.1 and earlier.
 typed_data/test/typed_buffers_test: RuntimeError
 
-[ $runtime == vm && $system == windows ]
-analyzer/test/generated/all_the_rest_test: Fail # Issue 21772
-
 [ $compiler == dartanalyzer || $compiler == dart2analyzer ]
 compiler/samples/compile_loop/compile_loop: CompileTimeError  # Issue 16524
 
@@ -144,6 +136,7 @@
 analysis_server/tool/spec/check_all_test: SkipByDesign # Uses dart:io.
 analyzer/test/*: SkipByDesign # Uses dart:io.
 analyzer/tool/task_dependency_graph/check_test: SkipByDesign # Uses dart:io.
+analyzer/tool/summary/check_test: SkipByDesign # Uses dart:io.
 analyzer2dart/*: SkipByDesign # Uses dart:io.
 http_server/test/*: Fail, OK # Uses dart:io.
 observe/test/transformer_test: Fail, OK # Uses dart:io.
@@ -164,9 +157,6 @@
 [ $use_repository_packages ]
 analyzer/test/*: PubGetError
 
-[ $compiler == dart2js && $cps_ir ]
-lookup_map/test/lookup_map_test: RuntimeError # $async$temp1.get$tests is not a function
-
 [ $compiler == dart2js && $cps_ir && $host_checked ]
 analyzer/test/enum_test: Crash # Issue 24485
 analyzer/test/generated/all_the_rest_test: Crash # Issue 24485
diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn
index cbc0643..94de113 100644
--- a/runtime/BUILD.gn
+++ b/runtime/BUILD.gn
@@ -11,6 +11,11 @@
   # Debug build of Dart so that clients can still use a Release build of Dart
   # while themselves doing a Debug build.
   dart_debug = false
+
+  # Explicitly set the target architecture in case of precompilation. Leaving
+  # this unspecified results in automatic target architecture detection.
+  # Available options are: arm, arm64, mips, x64 and ia32
+  dart_target_arch = ""
 }
 
 config("dart_public_config") {
@@ -21,6 +26,24 @@
 
 config("dart_config") {
   defines = []
+
+  if (dart_target_arch != "") {
+    if (dart_target_arch == "arm") {
+      defines += [ "TARGET_ARCH_ARM" ]
+    } else if (dart_target_arch == "arm64") {
+      defines += [ "TARGET_ARCH_ARM64" ]
+    } else if (dart_target_arch == "mips") {
+      defines += [ "TARGET_ARCH_MIPS" ]
+    } else if (dart_target_arch == "x64") {
+      defines += [ "TARGET_ARCH_X64" ]
+    } else if (dart_target_arch == "ia32") {
+      defines += [ "TARGET_ARCH_IA32" ]
+    } else  {
+      print("Invalid |dart_target_arch|")
+      assert(false)
+    }
+  }
+
   if (dart_debug) {
     defines += ["DEBUG"]
   } else {
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 1185ee4..b6d6ac1 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -8,6 +8,32 @@
 }
 
 
+resources_sources_gypi =
+    exec_script("../../tools/gypi_to_gn.py",
+                [rebase_path("resources_sources.gypi")],
+                "scope",
+                ["resources_sources.gypi"])
+
+# Generate a resources.cc file for the service isolate without Observatory.
+action("gen_resources_cc") {
+  visibility = [ ":*" ] # Only targets in this file can see this.
+  script = "../tools/create_resources.py"
+  inputs = [
+    "../tools/create_resources.py",
+  ]
+  sources = resources_sources_gypi.sources
+  outputs = [ "$target_gen_dir/resources_gen.cc" ]
+  args = [
+    "--output",
+    rebase_path("$target_gen_dir/resources_gen.cc", root_build_dir),
+    "--outer_namespace", "dart",
+    "--inner_namespace", "bin",
+    "--table_name", "service_bin",
+    "--root_prefix", rebase_path(".", root_build_dir) + "/",
+  ] + rebase_path(sources, root_build_dir)
+}
+
+
 template("gen_library_src_path") {
   assert(defined(invoker.sources), "Need sources in $target_name")
   assert(defined(invoker.output), "Need output in $target_name")
@@ -143,6 +169,8 @@
 executable("gen_snapshot") {
   configs += ["..:dart_config"]
   deps = [
+    ":gen_resources_cc",
+    ":gen_snapshot_dart_io",
     ":generate_builtin_cc_file",
     ":generate_io_cc_file",
     ":generate_io_patch_cc_file",
@@ -163,10 +191,13 @@
     "platform_macos.cc",
     "platform_win.cc",
     "platform.h",
+    "vmservice_impl.cc",
+    "vmservice_impl.h",
     # Include generated source files.
     "$target_gen_dir/builtin_gen.cc",
     "$target_gen_dir/io_gen.cc",
     "$target_gen_dir/io_patch_gen.cc",
+    "$target_gen_dir/resources_gen.cc",
   ]
 
   include_dirs = [
@@ -189,6 +220,61 @@
                 "scope",
                 [ "io_impl_sources.gypi" ])
 
+
+# A source set for the implementation of 'dart:io' library
+# (without secure sockets) suitable for linking with gen_snapshot.
+source_set("gen_snapshot_dart_io") {
+  configs += ["..:dart_config",]
+
+  # Set custom sources assignment filter. The custom filters does three things:
+  # 1) Filters out unnecessary files pulled in from the gypi files.
+  # 2) Filters out secure socket support.
+  # 3) Enables dart:io by filtering out _unsupported.cc implementations.
+  custom_sources_filter = [
+    "*net/nss_memio.cc",
+    "*net/nss_memio.h",
+    "*secure_socket.cc",
+    "*secure_socket.h",
+    "filter.cc",
+    "*io_service_unsupported.cc",
+    "platform_*.cc",
+    "*io_service.cc",
+    "*io_service.h",
+    "*_test.cc",
+    "*_test.h",
+    "*dbg*",
+    "builtin.cc",
+    "builtin_common.cc",
+    "builtin_gen_snapshot.cc",
+  ]
+  if (!is_mac && !is_ios) {
+    # Dart tree uses *_macos.* instead of *_mac.*
+    custom_sources_filter += [
+      "*_macos.h",
+      "*_macos.cc",
+    ]
+  }
+  set_sources_assignment_filter(custom_sources_filter)
+
+  defines = [ "DART_IO_SECURE_SOCKET_DISABLED" ]
+
+  sources = io_impl_sources_gypi.sources + builtin_impl_sources_gypi.sources
+  sources += [
+    "io_natives.cc",
+    "io_natives.h",
+    "log_android.cc",
+    "log_linux.cc",
+    "log_macos.cc",
+    "log_win.cc",
+    "log.h",
+  ]
+
+  include_dirs = [
+    "..",
+    "//third_party"
+  ]
+}
+
 # A source set for the implementation of 'dart:io' library
 # (without secure sockets).
 source_set("embedded_dart_io") {
diff --git a/runtime/bin/bin.gypi b/runtime/bin/bin.gypi
index 1777513..a7f3bf7 100644
--- a/runtime/bin/bin.gypi
+++ b/runtime/bin/bin.gypi
@@ -18,6 +18,8 @@
     'bootstrap_resources_cc_file':
         '<(gen_source_dir)/bootstrap_resources_gen.cc',
     'snapshot_cc_file': '<(gen_source_dir)/snapshot_gen.cc',
+    'observatory_assets_cc_file': '<(gen_source_dir)/observatory_assets.cc',
+    'observatory_assets_tar_file': '<(gen_source_dir)/observatory_assets.tar',
   },
   'targets': [
     {
@@ -137,9 +139,6 @@
         'log_macos.cc',
         'log_win.cc',
       ],
-      'defines': [
-        'LEGACY_DEBUG_PROTOCOL_ENABLED',
-      ],
       'includes': [
         'builtin_impl_sources.gypi',
         '../platform/platform_sources.gypi',
@@ -202,6 +201,7 @@
         'generate_io_patch_cc_file#host',
         'generate_snapshot_file#host',
         'generate_resources_cc_file#host',
+        'generate_observatory_assets_cc_file#host',
       ],
       'sources': [
         'builtin_common.cc',
@@ -221,6 +221,7 @@
         'vmservice_impl.cc',
         'vmservice_impl.h',
         '<(resources_cc_file)',
+        '<(observatory_assets_cc_file)',
       ],
       'sources/': [
         ['exclude', '_test\\.(cc|h)$'],
@@ -373,8 +374,11 @@
       'type': 'executable',
       'toolsets':['host'],
       'dependencies': [
+        'generate_resources_cc_file#host',
+        'generate_observatory_assets_cc_file#host',
         'libdart_nosnapshot',
         'libdart_builtin',
+        'libdart_io',
       ],
       'include_dirs': [
         '..',
@@ -392,13 +396,16 @@
         'platform_macos.cc',
         'platform_win.cc',
         'platform.h',
+        'vmservice_impl.cc',
+        'vmservice_impl.h',
         # Include generated source files.
         '<(builtin_cc_file)',
         '<(io_cc_file)',
         '<(io_patch_cc_file)',
+        '<(resources_cc_file)',
       ],
       'defines': [
-        'PLATFORM_DISABLE_SOCKET'
+        'PLATFORM_DISABLE_SOCKET',
       ],
       'conditions': [
         ['OS=="win"', {
@@ -472,12 +479,40 @@
       ]
     },
     {
-      'target_name': 'generate_resources_cc_file',
+      'target_name': 'generate_observatory_assets_cc_file',
       'type': 'none',
       'toolsets':['host'],
       'dependencies': [
         'build_observatory#host',
       ],
+      'actions': [
+        {
+          'action_name': 'generate_observatory_assets_cc_file',
+          'inputs': [
+            '../tools/create_archive.py',
+            '<(PRODUCT_DIR)/observatory/deployed/web/index.html'
+          ],
+          'outputs': [
+            '<(observatory_assets_cc_file)',
+          ],
+          'action': [
+            'python',
+            'tools/create_archive.py',
+            '--output', '<(observatory_assets_cc_file)',
+            '--tar_output', '<(observatory_assets_tar_file)',
+            '--outer_namespace', 'dart',
+            '--inner_namespace', 'bin',
+            '--name', 'observatory_assets_archive',
+            '--client_root', '<(PRODUCT_DIR)/observatory/deployed/web/',
+          ],
+          'message': 'Generating ''<(observatory_assets_cc_file)'' file.'
+        },
+      ]
+    },
+    {
+      'target_name': 'generate_resources_cc_file',
+      'type': 'none',
+      'toolsets':['host'],
       'includes': [
         'resources_sources.gypi',
       ],
@@ -486,8 +521,6 @@
           'action_name': 'generate_resources_cc',
           'inputs': [
             '../tools/create_resources.py',
-            # The following two files are used to trigger a rebuild.
-            '<(PRODUCT_DIR)/observatory/deployed/web/index.html',
             '<@(_sources)',
           ],
           'outputs': [
@@ -496,13 +529,11 @@
           'action': [
             'python',
             'tools/create_resources.py',
-            '--compress',
             '--output', '<(resources_cc_file)',
             '--outer_namespace', 'dart',
             '--inner_namespace', 'bin',
             '--table_name', 'service_bin',
             '--root_prefix', 'bin/',
-            '--client_root', '<(PRODUCT_DIR)/observatory/deployed/web/',
             '<@(_sources)'
           ],
           'message': 'Generating ''<(resources_cc_file)'' file.'
@@ -552,6 +583,7 @@
         'build_observatory#host',
         'generate_snapshot_file#host',
         'generate_resources_cc_file#host',
+        'generate_observatory_assets_cc_file#host',
       ],
       'include_dirs': [
         '..',
@@ -567,6 +599,7 @@
         'vmservice_impl.h',
         '<(snapshot_cc_file)',
         '<(resources_cc_file)',
+        '<(observatory_assets_cc_file)',
       ],
       'conditions': [
         ['OS=="win"', {
@@ -621,6 +654,7 @@
         '<(io_cc_file)',
         '<(io_patch_cc_file)',
         '<(bootstrap_resources_cc_file)',
+        'observatory_assets_empty.cc',
         'snapshot_empty.cc',
       ],
       'conditions': [
@@ -656,6 +690,7 @@
         'libdart_builtin',
         'libdart_io',
         'generate_resources_cc_file#host',
+        'generate_observatory_assets_cc_file#host',
       ],
       'include_dirs': [
         '..',
@@ -674,6 +709,7 @@
         '<(io_cc_file)',
         '<(io_patch_cc_file)',
         '<(resources_cc_file)',
+        '<(observatory_assets_cc_file)',
         'snapshot_empty.cc',
       ],
       'conditions': [
@@ -740,7 +776,6 @@
         '../vm/vm_sources.gypi',
       ],
       'defines': [
-        'LEGACY_DEBUG_PROTOCOL_ENABLED',
         'TESTING',
       ],
       # Only include _test.[cc|h] files.
diff --git a/runtime/bin/builtin.cc b/runtime/bin/builtin.cc
index c52f314..021140b 100644
--- a/runtime/bin/builtin.cc
+++ b/runtime/bin/builtin.cc
@@ -27,8 +27,14 @@
 static void LoadPatchFiles(Dart_Handle library,
                            const char* patch_uri,
                            const char** patch_files) {
-  for (intptr_t j = 0; patch_files[j] != NULL; j += 2) {
+  for (intptr_t j = 0; patch_files[j] != NULL; j += 3) {
     Dart_Handle patch_src = DartUtils::ReadStringFromFile(patch_files[j + 1]);
+    if (!Dart_IsString(patch_src)) {
+      // In case reading the file caused an error, use the sources directly.
+      const char* source = patch_files[j + 2];
+      patch_src = Dart_NewStringFromUTF8(
+          reinterpret_cast<const uint8_t*>(source), strlen(source));
+    }
 
     // Prepend the patch library URI to form a unique script URI for the patch.
     intptr_t len = snprintf(NULL, 0, "%s/%s", patch_uri, patch_files[j]);
@@ -69,17 +75,20 @@
   if (source_paths == NULL) {
     return Dart_Null();  // No path mapping information exists for library.
   }
-  const char* source_path = NULL;
-  for (intptr_t i = 0; source_paths[i] != NULL; i += 2) {
+  for (intptr_t i = 0; source_paths[i] != NULL; i += 3) {
     if (!strcmp(uri, source_paths[i])) {
-      source_path = source_paths[i + 1];
-      break;
+      const char* source_path = source_paths[i + 1];
+      Dart_Handle src = DartUtils::ReadStringFromFile(source_path);
+      if (!Dart_IsString(src)) {
+        // In case reading the file caused an error, use the sources directly.
+        const char* source = source_paths[i + 2];
+        src = Dart_NewStringFromUTF8(
+            reinterpret_cast<const uint8_t*>(source), strlen(source));
+      }
+      return src;
     }
   }
-  if (source_path == NULL) {
-    return Dart_Null();  // Uri does not exist in path mapping information.
-  }
-  return DartUtils::ReadStringFromFile(source_path);
+  return Dart_Null();  // Uri does not exist in path mapping information.
 }
 
 
diff --git a/runtime/bin/builtin.dart b/runtime/bin/builtin.dart
index d6d945e..5ae31ae 100644
--- a/runtime/bin/builtin.dart
+++ b/runtime/bin/builtin.dart
@@ -44,9 +44,9 @@
 Uri _uriBase() {
   // We are not using Dircetory.current here to limit the dependency
   // on dart:io. This code is the same as:
-  //   return new Uri.file(Directory.current.path + "/");
-  var result = _getCurrentDirectoryPath();
-  return new Uri.file("$result/");
+  //   return new Uri.directory(Directory.current.path);
+  var path = _getCurrentDirectoryPath();
+  return new Uri.directory(path);
 }
 
 
diff --git a/runtime/bin/builtin_gen_snapshot.cc b/runtime/bin/builtin_gen_snapshot.cc
index 2852464..c1263bd 100644
--- a/runtime/bin/builtin_gen_snapshot.cc
+++ b/runtime/bin/builtin_gen_snapshot.cc
@@ -9,6 +9,7 @@
 #include "include/dart_api.h"
 
 #include "bin/builtin.h"
+#include "bin/io_natives.h"
 
 namespace dart {
 namespace bin {
@@ -45,7 +46,7 @@
       return reinterpret_cast<Dart_NativeFunction>(entry->function_);
     }
   }
-  return NULL;
+  return IONativeLookup(name, argument_count, auto_setup_scope);
 }
 
 
@@ -57,7 +58,7 @@
       return reinterpret_cast<const uint8_t*>(entry->name_);
     }
   }
-  return NULL;
+  return IONativeSymbol(nf);
 }
 
 
diff --git a/runtime/bin/builtin_in.cc b/runtime/bin/builtin_in.cc
index 2f30aad..45b2cbf 100644
--- a/runtime/bin/builtin_in.cc
+++ b/runtime/bin/builtin_in.cc
@@ -9,5 +9,5 @@
 const char* {{VAR_NAME}}[] = {
 {{LIBRARY_SOURCE_MAP}}
 {{PART_SOURCE_MAP}}
-  NULL, NULL
+  NULL, NULL, NULL
 };
diff --git a/runtime/bin/builtin_natives.cc b/runtime/bin/builtin_natives.cc
index ad7f6e1..f737132 100644
--- a/runtime/bin/builtin_natives.cc
+++ b/runtime/bin/builtin_natives.cc
@@ -13,6 +13,7 @@
 
 #include "bin/builtin.h"
 #include "bin/dartutils.h"
+#include "bin/file.h"
 #include "bin/io_natives.h"
 #include "bin/platform.h"
 
@@ -79,9 +80,6 @@
 }
 
 
-extern bool capture_stdout;
-
-
 // Implementation of native functions which are used for some
 // test/debug functionality in standalone dart mode.
 void FUNCTION_NAME(Builtin_PrintString)(Dart_NativeArguments args) {
@@ -95,7 +93,7 @@
   fwrite(chars, 1, length, stdout);
   fputs("\n", stdout);
   fflush(stdout);
-  if (capture_stdout) {
+  if (File::capture_stdout()) {
     // For now we report print output on the Stdout stream.
     uint8_t newline[] = { '\n' };
     Dart_ServiceSendDataEvent("Stdout", "WriteEvent", chars, length);
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index 3c01e64..50ae7d0 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -284,6 +284,27 @@
 }
 
 
+Dart_Handle DartUtils::MakeUint8Array(const uint8_t* buffer, intptr_t len) {
+  Dart_Handle array = Dart_NewTypedData(Dart_TypedData_kUint8, len);
+  RETURN_IF_ERROR(array);
+  {
+    Dart_TypedData_Type td_type;
+    void* td_data;
+    intptr_t td_len;
+    Dart_Handle result =
+        Dart_TypedDataAcquireData(array, &td_type, &td_data, &td_len);
+    RETURN_IF_ERROR(result);
+    ASSERT(td_type == Dart_TypedData_kUint8);
+    ASSERT(td_len == len);
+    ASSERT(td_data != NULL);
+    memmove(td_data, buffer, td_len);
+    result = Dart_TypedDataReleaseData(array);
+    RETURN_IF_ERROR(result);
+  }
+  return array;
+}
+
+
 Dart_Handle DartUtils::SetWorkingDirectory(Dart_Handle builtin_lib) {
   Dart_Handle directory = NewString(original_working_directory);
   return SingleArgDart_Invoke(builtin_lib, "_setWorkingDirectory", directory);
@@ -663,7 +684,8 @@
     // Wait for the service isolate to initialize the load port.
     Dart_Port load_port = Dart_ServiceWaitForLoadPort();
     if (load_port == ILLEGAL_PORT) {
-      return NewDartUnsupportedError("Service did not return load port.");
+      return Dart_NewUnhandledExceptionError(
+          NewDartUnsupportedError("Service did not return load port."));
     }
     result = Builtin::SetLoadPort(load_port);
     RETURN_IF_ERROR(result);
diff --git a/runtime/bin/dartutils.h b/runtime/bin/dartutils.h
index d337a10..cd3ce0e 100644
--- a/runtime/bin/dartutils.h
+++ b/runtime/bin/dartutils.h
@@ -119,6 +119,7 @@
   static void CloseFile(void* stream);
   static bool EntropySource(uint8_t* buffer, intptr_t length);
   static Dart_Handle ReadStringFromFile(const char* filename);
+  static Dart_Handle MakeUint8Array(const uint8_t* buffer, intptr_t length);
   static Dart_Handle LibraryTagHandler(Dart_LibraryTag tag,
                                        Dart_Handle library,
                                        Dart_Handle url);
@@ -580,11 +581,11 @@
 class ScopedBlockingCall {
  public:
   ScopedBlockingCall() {
-    Dart_IsolateBlocked();
+    Dart_ThreadDisableProfiling();
   }
 
   ~ScopedBlockingCall() {
-    Dart_IsolateUnblocked();
+    Dart_ThreadEnableProfiling();
   }
 };
 
diff --git a/runtime/bin/extensions.cc b/runtime/bin/extensions.cc
index 3b02971..eaed7bb 100644
--- a/runtime/bin/extensions.cc
+++ b/runtime/bin/extensions.cc
@@ -29,19 +29,20 @@
   void* library_handle = LoadExtensionLibrary(library_file);
   free(library_file);
   if (library_handle == NULL) {
-    return Dart_NewApiError("Cannot find extension library");
+    return GetError();
   }
 
   const char* strings[] = { extension_name, "_Init", NULL };
   char* init_function_name = Concatenate(strings);
-  typedef Dart_Handle (*InitFunctionType)(Dart_Handle import_map);
-  InitFunctionType fn = reinterpret_cast<InitFunctionType>(
-      ResolveSymbol(library_handle, init_function_name));
+  void* init_function = ResolveSymbol(library_handle, init_function_name);
   free(init_function_name);
-
-  if (fn == NULL) {
-    return Dart_NewApiError("Cannot find initialization function in extension");
+  Dart_Handle result = GetError();
+  if (Dart_IsError(result)) {
+    return result;
   }
+  ASSERT(init_function != NULL);
+  typedef Dart_Handle (*InitFunctionType)(Dart_Handle import_map);
+  InitFunctionType fn = reinterpret_cast<InitFunctionType>(init_function);
   return (*fn)(parent_library);
 }
 
diff --git a/runtime/bin/extensions.h b/runtime/bin/extensions.h
index 25dbfeb..8c172b8 100644
--- a/runtime/bin/extensions.h
+++ b/runtime/bin/extensions.h
@@ -26,6 +26,8 @@
   static void* ResolveSymbol(void* lib_handle, const char* symbol);
 
  private:
+  static Dart_Handle GetError();
+
   // The returned string must be freed.
   static char* Concatenate(const char** strings);
 
diff --git a/runtime/bin/extensions_android.cc b/runtime/bin/extensions_android.cc
index 1b79991..0c79bff 100644
--- a/runtime/bin/extensions_android.cc
+++ b/runtime/bin/extensions_android.cc
@@ -21,9 +21,15 @@
 
 void* Extensions::ResolveSymbol(void* lib_handle, const char* symbol) {
   dlerror();
-  void* result = dlsym(lib_handle, symbol);
-  if (dlerror() != NULL) return NULL;
-  return result;
+  return dlsym(lib_handle, symbol);
+}
+
+Dart_Handle Extensions::GetError() {
+  const char* err_str = dlerror();
+  if (err_str != NULL) {
+    return Dart_NewApiError(err_str);
+  }
+  return Dart_Null();
 }
 
 }  // namespace bin
diff --git a/runtime/bin/extensions_linux.cc b/runtime/bin/extensions_linux.cc
index 23ee6ed..e172f0d 100644
--- a/runtime/bin/extensions_linux.cc
+++ b/runtime/bin/extensions_linux.cc
@@ -21,9 +21,15 @@
 
 void* Extensions::ResolveSymbol(void* lib_handle, const char* symbol) {
   dlerror();
-  void* result = dlsym(lib_handle, symbol);
-  if (dlerror() != NULL) return NULL;
-  return result;
+  return dlsym(lib_handle, symbol);
+}
+
+Dart_Handle Extensions::GetError() {
+  const char* err_str = dlerror();
+  if (err_str != NULL) {
+    return Dart_NewApiError(err_str);
+  }
+  return Dart_Null();
 }
 
 }  // namespace bin
diff --git a/runtime/bin/extensions_macos.cc b/runtime/bin/extensions_macos.cc
index 92a5e98..e248a47 100644
--- a/runtime/bin/extensions_macos.cc
+++ b/runtime/bin/extensions_macos.cc
@@ -21,9 +21,15 @@
 
 void* Extensions::ResolveSymbol(void* lib_handle, const char* symbol) {
   dlerror();
-  void* result = dlsym(lib_handle, symbol);
-  if (dlerror() != NULL) return NULL;
-  return result;
+  return dlsym(lib_handle, symbol);
+}
+
+Dart_Handle Extensions::GetError() {
+  const char* err_str = dlerror();
+  if (err_str != NULL) {
+    return Dart_NewApiError(err_str);
+  }
+  return Dart_Null();
 }
 
 }  // namespace bin
diff --git a/runtime/bin/extensions_win.cc b/runtime/bin/extensions_win.cc
index 8c0a15f..d3b49f2 100644
--- a/runtime/bin/extensions_win.cc
+++ b/runtime/bin/extensions_win.cc
@@ -17,13 +17,24 @@
 const char* kPrecompiledSymbolName = "_kInstructionsSnapshot";
 
 void* Extensions::LoadExtensionLibrary(const char* library_file) {
+  SetLastError(0);
   return LoadLibraryW(StringUtilsWin::Utf8ToWide(library_file));
 }
 
 void* Extensions::ResolveSymbol(void* lib_handle, const char* symbol) {
+  SetLastError(0);
   return GetProcAddress(reinterpret_cast<HMODULE>(lib_handle), symbol);
 }
 
+Dart_Handle Extensions::GetError() {
+  int last_error = GetLastError();
+  if (last_error != 0) {
+    OSError err;
+    return Dart_NewApiError(err.message());
+  }
+  return Dart_Null();
+}
+
 }  // namespace bin
 }  // namespace dart
 
diff --git a/runtime/bin/file.cc b/runtime/bin/file.cc
index 8175d9b..cfd5637 100644
--- a/runtime/bin/file.cc
+++ b/runtime/bin/file.cc
@@ -17,14 +17,14 @@
 
 static const int kMSPerSecond = 1000;
 
-// Are we capturing output from either stdout or stderr for the VM Service?
-bool capture_stdio = false;
-
 // Are we capturing output from stdout for the VM service?
-bool capture_stdout = false;
+bool File::capture_stdout_ = false;
 
 // Are we capturing output from stderr for the VM service?
-bool capture_stderr = false;
+bool File::capture_stderr_ = false;
+
+// Are we capturing output from either stdout or stderr for the VM Service?
+bool File::capture_any_ = false;
 
 
 // The file pointer has been passed into Dart as an intptr_t and it is safe
@@ -62,13 +62,13 @@
     remaining -= bytes_written;  // Reduce the number of remaining bytes.
     current_buffer += bytes_written;  // Move the buffer forward.
   }
-  if (capture_stdio) {
+  if (capture_any_) {
     intptr_t fd = GetFD();
-    if (fd == STDOUT_FILENO && capture_stdout) {
+    if (fd == STDOUT_FILENO && capture_stdout_) {
       Dart_ServiceSendDataEvent("Stdout", "WriteEvent",
                                 reinterpret_cast<const uint8_t*>(buffer),
                                 num_bytes);
-    } else if (fd == STDERR_FILENO && capture_stderr) {
+    } else if (fd == STDERR_FILENO && capture_stderr_) {
       Dart_ServiceSendDataEvent("Stderr", "WriteEvent",
                                 reinterpret_cast<const uint8_t*>(buffer),
                                 num_bytes);
diff --git a/runtime/bin/file.h b/runtime/bin/file.h
index 633c006..28e85e3 100644
--- a/runtime/bin/file.h
+++ b/runtime/bin/file.h
@@ -187,6 +187,18 @@
   static CObject* StatRequest(const CObjectArray& request);
   static CObject* LockRequest(const CObjectArray& request);
 
+  static void set_capture_stdout(bool value) {
+    capture_stdout_ = value;
+    capture_any_ = (capture_stdout_ || capture_stderr_);
+  }
+  static bool capture_stdout() { return capture_stdout_; }
+
+  static void set_capture_stderr(bool value) {
+    capture_stderr_ = value;
+    capture_any_ = (capture_stdout_ || capture_stderr_);
+  }
+  static bool capture_stderr() { return capture_stderr_; }
+
  private:
   explicit File(FileHandle* handle) : handle_(handle) { }
   void Close();
@@ -196,6 +208,10 @@
   // FileHandle is an OS specific class which stores data about the file.
   FileHandle* handle_;  // OS specific handle for the file.
 
+  static bool capture_stdout_;
+  static bool capture_stderr_;
+  static bool capture_any_;
+
   DISALLOW_COPY_AND_ASSIGN(File);
 };
 
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 72ee0f1..773c0af 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -9,13 +9,17 @@
 #include <string.h>
 #include <stdio.h>
 
+#include <cstdarg>
+
 #include "include/dart_api.h"
 
 #include "bin/builtin.h"
 #include "bin/dartutils.h"
+#include "bin/eventhandler.h"
 #include "bin/file.h"
 #include "bin/log.h"
 #include "bin/thread.h"
+#include "bin/vmservice_impl.h"
 
 #include "platform/globals.h"
 
@@ -36,6 +40,8 @@
 // if so which file to write the snapshot into.
 static const char* vm_isolate_snapshot_filename = NULL;
 static const char* isolate_snapshot_filename = NULL;
+static const char* instructions_snapshot_filename = NULL;
+static const char* embedder_entry_points_manifest = NULL;
 static const char* package_root = NULL;
 
 
@@ -86,6 +92,26 @@
 }
 
 
+static bool ProcessInstructionsSnapshotOption(const char* option) {
+  const char* name = ProcessOption(option, "--instructions_snapshot=");
+  if (name != NULL) {
+    instructions_snapshot_filename = name;
+    return true;
+  }
+  return false;
+}
+
+
+static bool ProcessEmbedderEntryPointsManifestOption(const char* option) {
+  const char* name = ProcessOption(option, "--embedder_entry_points_manifest=");
+  if (name != NULL) {
+    embedder_entry_points_manifest = name;
+    return true;
+  }
+  return false;
+}
+
+
 static bool ProcessPackageRootOption(const char* option) {
   const char* name = ProcessOption(option, "--package_root=");
   if (name != NULL) {
@@ -125,6 +151,8 @@
   while ((i < argc) && IsValidFlag(argv[i], kPrefix, kPrefixLen)) {
     if (ProcessVmIsolateSnapshotOption(argv[i]) ||
         ProcessIsolateSnapshotOption(argv[i]) ||
+        ProcessInstructionsSnapshotOption(argv[i]) ||
+        ProcessEmbedderEntryPointsManifestOption(argv[i]) ||
         ProcessURLmappingOption(argv[i]) ||
         ProcessPackageRootOption(argv[i])) {
       i += 1;
@@ -152,10 +180,32 @@
     return -1;
   }
 
+  if (instructions_snapshot_filename != NULL &&
+      embedder_entry_points_manifest == NULL) {
+    Log::PrintErr(
+        "Specifying an instructions snapshot filename indicates precompilation"
+        ". But no embedder entry points manifest was specified.\n\n");
+    return -1;
+  }
+
+  if (embedder_entry_points_manifest != NULL &&
+      instructions_snapshot_filename == NULL) {
+    Log::PrintErr(
+        "Specifying the embedder entry points manifest indicates "
+        "precompilation. But no instuctions snapshot was specified.\n\n");
+    return -1;
+  }
+
   return 0;
 }
 
 
+static bool IsSnapshottingForPrecompilation(void) {
+  return embedder_entry_points_manifest != NULL &&
+         instructions_snapshot_filename != NULL;
+}
+
+
 static void WriteSnapshotFile(const char* filename,
                               const uint8_t* buffer,
                               const intptr_t size) {
@@ -419,26 +469,50 @@
 
 static void PrintUsage() {
   Log::PrintErr(
-"Usage:\n"
-"\n"
-"  gen_snapshot [<vm-flags>] [<options>] \\\n"
-"               --snapshot=<out-file> [<dart-script-file>]\n"
-"\n"
-"  Writes a snapshot of <dart-script-file> to <out-file>. If no\n"
-"  <dart-script-file> is passed, a generic snapshot of all the corelibs is\n"
-"  created. It is required to specify an output file name:\n"
-"\n"
-"    --snapshot=<file>          Generates a complete snapshot. Uses the url\n"
-"                               mapping specified on the command line to load\n"
-"                               the libraries.\n"
-"Supported options:\n"
-"\n"
-"--package_root=<path>\n"
-"  Where to find packages, that is, \"package:...\" imports.\n"
-"\n"
-"--url_mapping=<mapping>\n"
-"  Uses the URL mapping(s) specified on the command line to load the\n"
-"  libraries. For use only with --snapshot=.\n");
+"Usage:                                                                      \n"
+" gen_snapshot [<vm-flags>] [<options>] [<dart-script-file>]                 \n"
+"                                                                            \n"
+"  Writes a snapshot of <dart-script-file> to the specified snapshot files.  \n"
+"  If no <dart-script-file> is passed, a generic snapshot of all the corelibs\n"
+"  is created. It is required to specify the VM isolate snapshot and the     \n"
+"  isolate snapshot. The other flags are related to precompilation and are   \n"
+"  optional.                                                                 \n"
+"                                                                            \n"
+"  Precompilation:                                                           \n"
+"  In order to configure the snapshotter for precompilation, both the        \n"
+"  instructions snapshot and embedder entry points manifest must be          \n"
+"  specified. Assembly for the target architecture will be dumped into the   \n"
+"  instructions snapshot. This must be linked into the target binary in a    \n"
+"  separate step. The embedder entry points manifest lists the standalone    \n"
+"  entry points into the VM. Not specifying these will cause the tree shaker \n"
+"  to disregard the same as being used. The format of this manifest is as    \n"
+"  follows. Each line in the manifest is a comma separated list of three     \n"
+"  elements. The first entry is the library URI, the second entry is the     \n"
+"  class name and the final entry the function name. The file must be        \n"
+"  terminated with a newline charater.                                       \n"
+"                                                                            \n"
+"    Example:                                                                \n"
+"      dart:something,SomeClass,doSomething                                  \n"
+"                                                                            \n"
+"  Supported options:                                                        \n"
+"    --vm_isolate_snapshot=<file>      A full snapshot is a compact          \n"
+"    --isolate_snapshot=<file>         representation of the dart vm isolate \n"
+"                                      heap and dart isolate heap states.    \n"
+"                                      Both these options are required       \n"
+"                                                                            \n"
+"    --package_root=<path>             Where to find packages, that is,      \n"
+"                                      package:...  imports.                 \n"
+"                                                                            \n"
+"    --url_mapping=<mapping>           Uses the URL mapping(s) specified on  \n"
+"                                      the command line to load the          \n"
+"                                      libraries.                            \n"
+"                                                                            \n"
+"    --instructions_snapshot=<file>    (Precompilation only) Contains the    \n"
+"                                      assembly that must be linked into     \n"
+"                                      the target binary                     \n"
+"                                                                            \n"
+"    --embedder_entry_points_manifest=<file> (Precompilation only) Contains  \n"
+"                                      the stanalone embedder entry points\n");
 }
 
 
@@ -454,7 +528,326 @@
 }
 
 
+static const char StubNativeFunctionName[] = "StubNativeFunction";
+
+
+void StubNativeFunction(Dart_NativeArguments arguments) {
+  // This is a stub function for the resolver
+  UNREACHABLE();
+}
+
+
+static Dart_NativeFunction StubNativeLookup(Dart_Handle name,
+                                            int argument_count,
+                                            bool* auto_setup_scope) {
+  return &StubNativeFunction;
+}
+
+
+static const uint8_t* StubNativeSymbol(Dart_NativeFunction nf) {
+  return reinterpret_cast<const uint8_t *>(StubNativeFunctionName);
+}
+
+
+static void SetupStubNativeResolver(size_t lib_index,
+                                    const Dart_QualifiedFunctionName* entry) {
+  // TODO(24686): Remove this.
+  Dart_Handle library_string = Dart_NewStringFromCString(entry->library_uri);
+  DART_CHECK_VALID(library_string);
+  Dart_Handle library = Dart_LookupLibrary(library_string);
+  // Embedder entry points may be setup in libraries that have not been
+  // explicitly loaded by the application script. In such cases, library lookup
+  // will fail. Manually load those libraries.
+  if (Dart_IsError(library)) {
+    static const uint32_t kLoadBufferMaxSize = 128;
+    char* load_buffer =
+        reinterpret_cast<char*>(calloc(kLoadBufferMaxSize, sizeof(char)));
+    snprintf(load_buffer,
+             kLoadBufferMaxSize,
+             "import '%s';",
+             DartUtils::GetStringValue(library_string));
+    Dart_Handle script_handle = Dart_NewStringFromCString(load_buffer);
+    memset(load_buffer, 0, kLoadBufferMaxSize);
+    snprintf(load_buffer,
+             kLoadBufferMaxSize,
+             "dart:_snapshot_%zu",
+             lib_index);
+    Dart_Handle script_url = Dart_NewStringFromCString(load_buffer);
+    free(load_buffer);
+    Dart_Handle loaded = Dart_LoadLibrary(script_url, script_handle, 0, 0);
+    DART_CHECK_VALID(loaded);
+
+    // Do a fresh lookup
+    library = Dart_LookupLibrary(library_string);
+  }
+
+  DART_CHECK_VALID(library);
+  Dart_Handle result =  Dart_SetNativeResolver(library,
+                                               &StubNativeLookup,
+                                               &StubNativeSymbol);
+  DART_CHECK_VALID(result);
+}
+
+
+static void ImportNativeEntryPointLibrariesIntoRoot(
+    const Dart_QualifiedFunctionName* entries) {
+  if (entries == NULL) {
+    return;
+  }
+
+  size_t index = 0;
+  while (true) {
+    Dart_QualifiedFunctionName entry = entries[index++];
+    if (entry.library_uri == NULL) {
+      // The termination sentinel has null members.
+      break;
+    }
+    Dart_Handle entry_library =
+        Dart_LookupLibrary(Dart_NewStringFromCString(entry.library_uri));
+    DART_CHECK_VALID(entry_library);
+    Dart_Handle import_result = Dart_LibraryImportLibrary(
+        entry_library, Dart_RootLibrary(), Dart_EmptyString());
+    DART_CHECK_VALID(import_result);
+  }
+}
+
+
+static void SetupStubNativeResolversForPrecompilation(
+    const Dart_QualifiedFunctionName* entries) {
+
+  if (entries == NULL) {
+    return;
+  }
+
+  // Setup native resolvers for all libraries found in the manifest.
+  size_t index = 0;
+  while (true) {
+    Dart_QualifiedFunctionName entry = entries[index++];
+    if (entry.library_uri == NULL) {
+      // The termination sentinel has null members.
+      break;
+    }
+    // Setup stub resolvers on loaded libraries
+    SetupStubNativeResolver(index, &entry);
+  }
+}
+
+
+static void CleanupEntryPointItem(const Dart_QualifiedFunctionName *entry) {
+  if (entry == NULL) {
+    return;
+  }
+  // The allocation used for these entries is zero'ed. So even in error cases,
+  // references to some entries will be null. Calling this on an already cleaned
+  // up entry is programmer error.
+  free(const_cast<char*>(entry->library_uri));
+  free(const_cast<char*>(entry->class_name));
+  free(const_cast<char*>(entry->function_name));
+}
+
+
+static void CleanupEntryPointsCollection(Dart_QualifiedFunctionName* entries) {
+  if (entries == NULL) {
+    return;
+  }
+
+  size_t index = 0;
+  while (true) {
+    Dart_QualifiedFunctionName entry = entries[index++];
+    if (entry.library_uri == NULL) {
+      break;
+    }
+    CleanupEntryPointItem(&entry);
+  }
+  free(entries);
+}
+
+
+char* ParserErrorStringCreate(const char* format, ...) {
+  static const size_t kErrorBufferSize = 256;
+
+  char* error_buffer =
+      reinterpret_cast<char*>(calloc(kErrorBufferSize, sizeof(char)));
+  va_list args;
+  va_start(args, format);
+  vsnprintf(error_buffer, kErrorBufferSize, format, args);
+  va_end(args);
+
+  // In case of error, the buffer is released by the caller
+  return error_buffer;
+}
+
+
+const char* ParseEntryNameForIndex(uint8_t index) {
+  switch (index) {
+    case 0:
+      return "Library";
+    case 1:
+      return "Class";
+    case 2:
+      return "Function";
+    default:
+      return "Unknown";
+  }
+  return NULL;
+}
+
+
+static bool ParseEntryPointsManifestSingleLine(
+    const char* line, Dart_QualifiedFunctionName* entry, char** error) {
+  bool success = true;
+  size_t offset = 0;
+  for (uint8_t i = 0; i < 3; i++) {
+    const char* component = strchr(line + offset, i == 2 ? '\n' : ',');
+    if (component == NULL) {
+      success = false;
+      *error = ParserErrorStringCreate(
+          "Manifest entries must be comma separated and newline terminated. "
+          "Could not parse '%s' on line '%s'",
+          ParseEntryNameForIndex(i), line);
+      break;
+    }
+
+    int64_t chars_read = component - (line + offset);
+    if (chars_read <= 0) {
+      success = false;
+      *error =
+          ParserErrorStringCreate("There is no '%s' specified on line '%s'",
+                                  ParseEntryNameForIndex(i), line);
+      break;
+    }
+
+    if (entry != NULL) {
+      // These allocations are collected in |CleanupEntryPointsCollection|.
+      char* entry_item =
+          reinterpret_cast<char*>(calloc(chars_read + 1, sizeof(char)));
+      memmove(entry_item, line + offset, chars_read);
+
+      switch (i) {
+        case 0:  // library
+          entry->library_uri = entry_item;
+          break;
+        case 1:  // class
+          entry->class_name = entry_item;
+          break;
+        case 2:  // function
+          entry->function_name = entry_item;
+          break;
+        default:
+          free(entry_item);
+          success = false;
+          *error = ParserErrorStringCreate("Internal parser error\n");
+          break;
+      }
+    }
+
+    offset += chars_read + 1;
+  }
+  return success;
+}
+
+
+int64_t ParseEntryPointsManifestLines(FILE* file,
+                                      Dart_QualifiedFunctionName* collection) {
+  int64_t entries = 0;
+
+  static const int kManifestMaxLineLength = 1024;
+  char* line = reinterpret_cast<char*>(malloc(kManifestMaxLineLength));
+  size_t line_number = 0;
+  while (true) {
+    line_number++;
+    char* read_line = fgets(line, kManifestMaxLineLength, file);
+
+    if (read_line == NULL) {
+      if ((feof(file) != 0) && (ferror(file) != 0)) {
+        Log::PrintErr(
+            "Error while reading line number %zu. The manifest must be "
+            "terminated by a newline\n",
+            line_number);
+        entries = -1;
+      }
+      break;
+    }
+
+    Dart_QualifiedFunctionName* entry =
+        collection != NULL ? collection + entries : NULL;
+
+    char* error_buffer = NULL;
+    if (!ParseEntryPointsManifestSingleLine(read_line, entry, &error_buffer)) {
+      CleanupEntryPointItem(entry);
+      Log::PrintErr("Parser error on line %zu: %s\n", line_number,
+                    error_buffer);
+      free(error_buffer);
+      entries = -1;
+      break;
+    }
+
+    entries++;
+  }
+
+  free(line);
+
+  return entries;
+}
+
+
+static Dart_QualifiedFunctionName* ParseEntryPointsManifestFile(
+    const char* path) {
+  if (path == NULL) {
+    return NULL;
+  }
+
+  FILE* file = fopen(path, "r");
+
+  if (file == NULL) {
+    Log::PrintErr("Could not open entry points manifest file\n");
+    return NULL;
+  }
+
+  // Parse the file once but don't store the results. This is done to first
+  // determine the number of entries in the manifest
+  int64_t entry_count = ParseEntryPointsManifestLines(file, NULL);
+
+  if (entry_count <= 0) {
+    Log::PrintErr(
+        "Manifest file specified is invalid or contained no entries\n");
+    fclose(file);
+    return NULL;
+  }
+
+  rewind(file);
+
+  // Allocate enough storage for the entries in the file plus a termination
+  // sentinel and parse it again to populate the allocation
+  Dart_QualifiedFunctionName* entries =
+      reinterpret_cast<Dart_QualifiedFunctionName*>(
+          calloc(entry_count + 1, sizeof(Dart_QualifiedFunctionName)));
+
+  int64_t parsed_entry_count = ParseEntryPointsManifestLines(file, entries);
+  ASSERT(parsed_entry_count == entry_count);
+
+  fclose(file);
+
+  // The entries allocation must be explicitly cleaned up via
+  // |CleanupEntryPointsCollection|
+  return entries;
+}
+
+
+static Dart_QualifiedFunctionName* ParseEntryPointsManifestIfPresent() {
+  Dart_QualifiedFunctionName* entries =
+      ParseEntryPointsManifestFile(embedder_entry_points_manifest);
+  if (entries == NULL && IsSnapshottingForPrecompilation()) {
+    Log::PrintErr(
+        "Could not find native embedder entry points during precompilation\n");
+    exit(255);
+  }
+  return entries;
+}
+
+
 static void CreateAndWriteSnapshot() {
+  ASSERT(!IsSnapshottingForPrecompilation());
   Dart_Handle result;
   uint8_t* vm_isolate_buffer = NULL;
   intptr_t vm_isolate_size = 0;
@@ -483,6 +876,49 @@
 }
 
 
+static void CreateAndWritePrecompiledSnapshot(
+    Dart_QualifiedFunctionName* standalone_entry_points) {
+  ASSERT(IsSnapshottingForPrecompilation());
+  Dart_Handle result;
+  uint8_t* vm_isolate_buffer = NULL;
+  intptr_t vm_isolate_size = 0;
+  uint8_t* isolate_buffer = NULL;
+  intptr_t isolate_size = 0;
+  uint8_t* instructions_buffer = NULL;
+  intptr_t instructions_size = 0;
+
+  // Precompile with specified embedder entry points
+  result = Dart_Precompile(standalone_entry_points, true);
+  CHECK_RESULT(result);
+
+  // Create a precompiled snapshot. This gives us an instruction buffer with
+  // machine code
+  result = Dart_CreatePrecompiledSnapshot(&vm_isolate_buffer,
+                                          &vm_isolate_size,
+                                          &isolate_buffer,
+                                          &isolate_size,
+                                          &instructions_buffer,
+                                          &instructions_size);
+  CHECK_RESULT(result);
+
+  // Now write the vm isolate, isolate and instructions snapshots out to the
+  // specified files and exit.
+  WriteSnapshotFile(vm_isolate_snapshot_filename,
+                    vm_isolate_buffer,
+                    vm_isolate_size);
+  WriteSnapshotFile(isolate_snapshot_filename,
+                    isolate_buffer,
+                    isolate_size);
+  WriteSnapshotFile(instructions_snapshot_filename,
+                    instructions_buffer,
+                    instructions_size);
+  Dart_ExitScope();
+
+  // Shutdown the isolate.
+  Dart_ShutdownIsolate();
+}
+
+
 static void SetupForUriResolution() {
   // Set up the library tag handler for this isolate.
   Dart_Handle result = Dart_SetLibraryTagHandler(DartUtils::LibraryTagHandler);
@@ -515,6 +951,52 @@
 }
 
 
+static Dart_Isolate CreateServiceIsolate(const char* script_uri,
+                                         const char* main,
+                                         const char* package_root,
+                                         const char** package_map,
+                                         Dart_IsolateFlags* flags,
+                                         void* data,
+                                         char** error) {
+  Dart_Isolate isolate = NULL;
+  isolate = Dart_CreateIsolate(script_uri,
+                               main,
+                               NULL,
+                               NULL,
+                               NULL,
+                               error);
+
+  if (isolate == NULL) {
+    Log::PrintErr("Error: Could not create service isolate");
+    return NULL;
+  }
+
+  Dart_EnterScope();
+  if (!Dart_IsServiceIsolate(isolate)) {
+    Log::PrintErr("Error: We only expect to create the service isolate");
+    return NULL;
+  }
+  Dart_Handle result = Dart_SetLibraryTagHandler(DartUtils::LibraryTagHandler);
+  // Setup the native resolver.
+  Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
+  Builtin::LoadAndCheckLibrary(Builtin::kIOLibrary);
+  if (Dart_IsError(result)) {
+    Log::PrintErr("Error: Could not set tag handler for service isolate");
+    return NULL;
+  }
+  CHECK_RESULT(result);
+  ASSERT(Dart_IsServiceIsolate(isolate));
+  // Load embedder specific bits and return. Will not start http server.
+  if (!VmService::Setup("127.0.0.1", -1, false /* running_precompiled */)) {
+    *error = strdup(VmService::GetErrorMessage());
+    return NULL;
+  }
+  Dart_ExitScope();
+  Dart_ExitIsolate();
+  return isolate;
+}
+
+
 int main(int argc, char** argv) {
   const int EXTRA_VM_ARGUMENTS = 2;
   CommandLineOptions vm_options(argc + EXTRA_VM_ARGUMENTS);
@@ -534,23 +1016,40 @@
 
   Thread::InitOnce();
   DartUtils::SetOriginalWorkingDirectory();
+  // Start event handler.
+  EventHandler::Start();
 
   vm_options.AddArgument("--load_deferred_eagerly");
   // Workaround until issue 21620 is fixed.
   // (https://github.com/dart-lang/sdk/issues/21620)
   vm_options.AddArgument("--no-concurrent_sweep");
+
+  if (IsSnapshottingForPrecompilation()) {
+    vm_options.AddArgument("--precompilation");
+#if TARGET_ARCH_ARM
+    // This is for the iPod Touch 5th Generation (and maybe other older devices)
+    vm_options.AddArgument("--no-use_integer_division");
+#endif
+  }
+
   Dart_SetVMFlags(vm_options.count(), vm_options.arguments());
 
   // Initialize the Dart VM.
   // Note: We don't expect isolates to be created from dart code during
   // snapshot generation.
-  char* error = Dart_Initialize(NULL, NULL,
-      NULL, NULL, NULL, NULL,
+  char* error = Dart_Initialize(
+      NULL,
+      NULL,
+      CreateServiceIsolate,
+      NULL,
+      NULL,
+      NULL,
       DartUtils::OpenFile,
       DartUtils::ReadFile,
       DartUtils::WriteFile,
       DartUtils::CloseFile,
-      DartUtils::EntropySource);
+      DartUtils::EntropySource,
+      NULL);
   if (error != NULL) {
     Log::PrintErr("VM initialization failed: %s\n", error);
     free(error);
@@ -617,13 +1116,30 @@
     // URL mapping specified on the command line to load the libraries.
     result = Dart_SetLibraryTagHandler(CreateSnapshotLibraryTagHandler);
     CHECK_RESULT(result);
+
+    Dart_QualifiedFunctionName* entry_points =
+        ParseEntryPointsManifestIfPresent();
+
+    SetupStubNativeResolversForPrecompilation(entry_points);
+
     // Load the specified script.
     library = LoadSnapshotCreationScript(app_script_name);
     VerifyLoaded(library);
+
+    ImportNativeEntryPointLibrariesIntoRoot(entry_points);
+
     // Ensure that we mark all libraries as loaded.
     result = Dart_FinalizeLoading(false);
     CHECK_RESULT(result);
-    CreateAndWriteSnapshot();
+
+    if (entry_points == NULL) {
+      ASSERT(!IsSnapshottingForPrecompilation());
+      CreateAndWriteSnapshot();
+    } else {
+      CreateAndWritePrecompiledSnapshot(entry_points);
+    }
+
+    CleanupEntryPointsCollection(entry_points);
 
     Dart_EnterIsolate(UriResolverIsolateScope::isolate);
     Dart_ShutdownIsolate();
@@ -631,6 +1147,7 @@
     SetupForGenericSnapshotCreation();
     CreateAndWriteSnapshot();
   }
+  EventHandler::Stop();
   return 0;
 }
 
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 1429ff4e..72c5460 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -38,6 +38,7 @@
 
 // Global state that stores a pointer to the application script snapshot.
 static bool generate_script_snapshot = false;
+static bool generate_script_snapshot_after_run = false;
 static const char* snapshot_filename = NULL;
 
 
@@ -117,7 +118,10 @@
 // Exit code indicating a vm restart request.  Never returned to the user.
 static const int kRestartRequestExitCode = 1000;
 
-extern bool do_vm_shutdown;  // Defined in bin/process.cc
+// Global flag that is used to indicate that the VM should do a clean
+// shutdown.
+static bool do_vm_shutdown = false;
+
 static void ErrorExit(int exit_code, const char* format, ...) {
   va_list arguments;
   va_start(arguments, format);
@@ -141,7 +145,7 @@
     DebuggerConnectionHandler::StopHandler();
     EventHandler::Stop();
   }
-  exit(exit_code);
+  Platform::Exit(exit_code);
 }
 
 
@@ -381,9 +385,10 @@
 }
 
 
-static bool ProcessGenScriptSnapshotOption(const char* filename,
-                                           CommandLineOptions* vm_options) {
-  if (filename != NULL && strlen(filename) != 0) {
+static bool ProcessScriptSnapshotOptionHelper(const char* filename,
+                                              bool* snapshot_option) {
+  *snapshot_option = false;
+  if ((filename != NULL) && (strlen(filename) != 0)) {
     // Ensure that we are already running using a full snapshot.
     if (isolate_snapshot_buffer == NULL) {
       Log::PrintErr("Script snapshots cannot be generated in this version of"
@@ -391,13 +396,31 @@
       return false;
     }
     snapshot_filename = filename;
-    generate_script_snapshot = true;
+    *snapshot_option = true;
+    if (generate_script_snapshot && generate_script_snapshot_after_run) {
+      Log::PrintErr("--snapshot and --snapshot-after-run options"
+                    " cannot be specified at the same time\n");
+      return false;
+    }
     return true;
   }
   return false;
 }
 
 
+static bool ProcessScriptSnapshotOption(const char* filename,
+                                        CommandLineOptions* vm_options) {
+  return ProcessScriptSnapshotOptionHelper(filename, &generate_script_snapshot);
+}
+
+
+static bool ProcessScriptSnapshotAfterRunOption(
+    const char* filename, CommandLineOptions* vm_options) {
+  return ProcessScriptSnapshotOptionHelper(filename,
+                                           &generate_script_snapshot_after_run);
+}
+
+
 static bool ProcessEnableVmServiceOption(const char* option_value,
                                          CommandLineOptions* vm_options) {
   ASSERT(option_value != NULL);
@@ -508,7 +531,8 @@
   { "--observe", ProcessObserveOption },
   { "--run-precompiled-snapshot", ProcessRunPrecompiledSnapshotOption },
   { "--shutdown", ProcessShutdownOption },
-  { "--snapshot=", ProcessGenScriptSnapshotOption },
+  { "--snapshot=", ProcessScriptSnapshotOption },
+  { "--snapshot-after-run=", ProcessScriptSnapshotAfterRunOption },
   { "--trace-debug-protocol", ProcessTraceDebugProtocolOption },
   { "--trace-loading", ProcessTraceLoadingOption },
   { NULL, NULL }
@@ -743,7 +767,9 @@
 
   if (Dart_IsServiceIsolate(isolate)) {
     // If this is the service isolate, load embedder specific bits and return.
-    if (!VmService::Setup(vm_service_server_ip, vm_service_server_port)) {
+    if (!VmService::Setup(vm_service_server_ip,
+                          vm_service_server_port,
+                          has_run_precompiled_snapshot)) {
       *error = strdup(VmService::GetErrorMessage());
       return NULL;
     }
@@ -1029,21 +1055,16 @@
 }
 
 
-extern bool capture_stdio;
-extern bool capture_stdout;
-extern bool capture_stderr;
 static const char* kStdoutStreamId = "Stdout";
 static const char* kStderrStreamId = "Stderr";
 
 
 static bool ServiceStreamListenCallback(const char* stream_id) {
   if (strcmp(stream_id, kStdoutStreamId) == 0) {
-    capture_stdio = true;
-    capture_stdout = true;
+    File::set_capture_stdout(true);
     return true;
   } else if (strcmp(stream_id, kStderrStreamId) == 0) {
-    capture_stdio = true;
-    capture_stderr = true;
+    File::set_capture_stderr(true);
     return true;
   }
   return false;
@@ -1052,11 +1073,10 @@
 
 static void ServiceStreamCancelCallback(const char* stream_id) {
   if (strcmp(stream_id, kStdoutStreamId) == 0) {
-    capture_stdout = false;
+    File::set_capture_stdout(false);
   } else if (strcmp(stream_id, kStderrStreamId) == 0) {
-    capture_stderr = false;
+    File::set_capture_stderr(false);
   }
-  capture_stdio = (capture_stdout || capture_stderr);
 }
 
 
@@ -1095,17 +1115,45 @@
   void* library = Extensions::LoadExtensionLibrary(libname);
   if (library == NULL) {
     Log::PrintErr("Error: Failed to load library '%s'\n", libname);
-    exit(kErrorExitCode);
+    Platform::Exit(kErrorExitCode);
   }
   void* symbol = Extensions::ResolveSymbol(library, symname);
   if (symbol == NULL) {
     Log::PrintErr("Error: Failed to load symbol '%s'\n", symname);
-    exit(kErrorExitCode);
+    Platform::Exit(kErrorExitCode);
   }
   return symbol;
 }
 
 
+static void GenerateScriptSnapshot() {
+  // First create a snapshot.
+  uint8_t* buffer = NULL;
+  intptr_t size = 0;
+  Dart_Handle result = Dart_CreateScriptSnapshot(&buffer, &size);
+  if (Dart_IsError(result)) {
+    ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
+  }
+
+  // Open the snapshot file.
+  File* snapshot_file = File::Open(snapshot_filename, File::kWriteTruncate);
+  if (snapshot_file == NULL) {
+    ErrorExit(kErrorExitCode,
+              "Unable to open file %s for writing the snapshot\n",
+              snapshot_filename);
+  }
+
+  // Write the magic number to indicate file is a script snapshot.
+  DartUtils::WriteMagicNumber(snapshot_file);
+
+  // Now write the snapshot out to specified file.
+  bool bytes_written = snapshot_file->WriteFully(buffer, size);
+  ASSERT(bytes_written);
+  delete snapshot_file;
+  snapshot_file = NULL;
+}
+
+
 #define CHECK_RESULT(result)                                                   \
   if (Dart_IsError(result)) {                                                  \
     if (Dart_IsVMRestartRequest(result)) {                                     \
@@ -1118,6 +1166,7 @@
     ErrorExit(exit_code, "%s\n", Dart_GetError(result));                       \
   }
 
+
 bool RunMainIsolate(const char* script_name,
                     CommandLineOptions* dart_options) {
   // Call CreateIsolateAndSetup which creates an isolate and loads up
@@ -1152,7 +1201,7 @@
       DebuggerConnectionHandler::StopHandler();
       EventHandler::Stop();
     }
-    exit((exit_code != 0) ? exit_code : kErrorExitCode);
+    Platform::Exit((exit_code != 0) ? exit_code : kErrorExitCode);
   }
   delete [] isolate_name;
 
@@ -1164,29 +1213,7 @@
   Dart_EnterScope();
 
   if (generate_script_snapshot) {
-    // First create a snapshot.
-    Dart_Handle result;
-    uint8_t* buffer = NULL;
-    intptr_t size = 0;
-    result = Dart_CreateScriptSnapshot(&buffer, &size);
-    CHECK_RESULT(result);
-
-    // Open the snapshot file.
-    File* snapshot_file = File::Open(snapshot_filename, File::kWriteTruncate);
-    if (snapshot_file == NULL) {
-      ErrorExit(kErrorExitCode,
-                "Unable to open file %s for writing the snapshot\n",
-                snapshot_filename);
-    }
-
-    // Write the magic number to indicate file is a script snapshot.
-    DartUtils::WriteMagicNumber(snapshot_file);
-
-    // Now write the snapshot out to specified file.
-    bool bytes_written = snapshot_file->WriteFully(buffer, size);
-    ASSERT(bytes_written);
-    delete snapshot_file;
-    snapshot_file = NULL;
+    GenerateScriptSnapshot();
   } else {
     // Lookup the library of the root script.
     Dart_Handle root_lib = Dart_RootLibrary();
@@ -1197,6 +1224,18 @@
     ASSERT(!Dart_IsError(builtin_lib));
     result = Dart_LibraryImportLibrary(builtin_lib, root_lib, Dart_Null());
 
+    if (has_gen_precompiled_snapshot) {
+      // Load the embedder's portion of the VM service's Dart code so it will
+      // be included in the precompiled snapshot.
+      if (!VmService::LoadForGenPrecompiled()) {
+        fprintf(stderr,
+                "VM service loading failed: %s\n",
+                VmService::GetErrorMessage());
+        fflush(stderr);
+        exit(kErrorExitCode);
+      }
+    }
+
     if (has_noopt || has_gen_precompiled_snapshot) {
       Dart_QualifiedFunctionName standalone_entry_points[] = {
         { "dart:_builtin", "::", "_getMainClosure" },
@@ -1204,14 +1243,19 @@
         { "dart:_builtin", "::", "_getUriBaseClosure" },
         { "dart:_builtin", "::", "_resolveUri" },
         { "dart:_builtin", "::", "_setWorkingDirectory" },
+        { "dart:_builtin", "::", "_setPackageRoot" },
+        { "dart:_builtin", "::", "_addPackageMapEntry" },
+        { "dart:_builtin", "::", "_loadPackagesMap" },
         { "dart:_builtin", "::", "_loadDataAsync" },
         { "dart:io", "::", "_makeUint8ListView" },
         { "dart:io", "::", "_makeDatagram" },
         { "dart:io", "::", "_setupHooks" },
+        { "dart:io", "::", "_getWatchSignalInternal" },
         { "dart:io", "CertificateException", "CertificateException." },
         { "dart:io", "HandshakeException", "HandshakeException." },
+        { "dart:io", "OSError", "OSError." },
         { "dart:io", "TlsException", "TlsException." },
-        { "dart:io", "X509Certificate", "X509Certificate." },
+        { "dart:io", "X509Certificate", "X509Certificate._" },
         { "dart:io", "_ExternalBuffer", "set:data" },
         { "dart:io", "_Platform", "set:_nativeScript" },
         { "dart:io", "_ProcessStartStatus", "set:_errorCode" },
@@ -1220,6 +1264,7 @@
         { "dart:io", "_SecureFilterImpl", "get:SIZE" },
         { "dart:vmservice_io", "::", "_addResource" },
         { "dart:vmservice_io", "::", "main" },
+        { "dart:vmservice_io", "::", "boot" },
         { NULL, NULL, NULL }  // Must be terminated with NULL entries.
       };
 
@@ -1299,6 +1344,11 @@
       // Keep handling messages until the last active receive port is closed.
       result = Dart_RunLoop();
       CHECK_RESULT(result);
+
+      // Generate a script snapshot after execution if specified.
+      if (generate_script_snapshot_after_run) {
+        GenerateScriptSnapshot();
+      }
     }
   }
 
@@ -1312,6 +1362,15 @@
 
 #undef CHECK_RESULT
 
+extern unsigned int observatory_assets_archive_len;
+extern const uint8_t* observatory_assets_archive;
+
+Dart_Handle GetVMServiceAssetsArchiveCallback() {
+  return DartUtils::MakeUint8Array(
+      observatory_assets_archive,
+      observatory_assets_archive_len);
+}
+
 
 void main(int argc, char** argv) {
   char* script_name;
@@ -1341,18 +1400,18 @@
                      &verbose_debug_seen) < 0) {
     if (has_help_option) {
       PrintUsage();
-      exit(0);
+      Platform::Exit(0);
     } else if (has_version_option) {
       PrintVersion();
-      exit(0);
+      Platform::Exit(0);
     } else if (print_flags_seen) {
       // Will set the VM flags, print them out and then we exit as no
       // script was specified on the command line.
       Dart_SetVMFlags(vm_options.count(), vm_options.arguments());
-      exit(0);
+      Platform::Exit(0);
     } else {
       PrintUsage();
-      exit(kErrorExitCode);
+      Platform::Exit(kErrorExitCode);
     }
   }
 
@@ -1362,7 +1421,7 @@
     OSError err;
     fprintf(stderr, "Error determining current directory: %s\n", err.message());
     fflush(stderr);
-    exit(kErrorExitCode);
+    Platform::Exit(kErrorExitCode);
   }
 
   if (generate_script_snapshot) {
@@ -1402,7 +1461,8 @@
       DartUtils::ReadFile,
       DartUtils::WriteFile,
       DartUtils::CloseFile,
-      DartUtils::EntropySource);
+      DartUtils::EntropySource,
+      GetVMServiceAssetsArchiveCallback);
   if (error != NULL) {
     if (do_vm_shutdown) {
       DebuggerConnectionHandler::StopHandler();
@@ -1411,7 +1471,7 @@
     fprintf(stderr, "VM initialization failed: %s\n", error);
     fflush(stderr);
     free(error);
-    exit(kErrorExitCode);
+    Platform::Exit(kErrorExitCode);
   }
 
   Dart_RegisterIsolateServiceRequestCallback(
@@ -1453,7 +1513,7 @@
     delete environment;
   }
 
-  exit(Process::GlobalExitCode());
+  Platform::Exit(Process::GlobalExitCode());
 }
 
 }  // namespace bin
diff --git a/runtime/bin/observatory_assets_empty.cc b/runtime/bin/observatory_assets_empty.cc
new file mode 100644
index 0000000..80d5fe1
--- /dev/null
+++ b/runtime/bin/observatory_assets_empty.cc
@@ -0,0 +1,24 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This file is linked into the dart executable when it does not have
+// Observatory baked in.
+
+#if defined(_WIN32)
+typedef unsigned __int8 uint8_t;
+#else
+#include <inttypes.h>
+#include <stdint.h>
+#endif
+#include <stddef.h>
+
+namespace dart {
+namespace bin {
+
+static const uint8_t observatory_assets_archive_[] = { '\0' };
+unsigned int observatory_assets_archive_len = 0;
+const uint8_t* observatory_assets_archive = observatory_assets_archive_;
+
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/bin/platform.h b/runtime/bin/platform.h
index 3d3c0f3..4d847e7 100644
--- a/runtime/bin/platform.h
+++ b/runtime/bin/platform.h
@@ -76,6 +76,8 @@
     return argv_;
   }
 
+  static DART_NORETURN void Exit(int exit_code);
+
  private:
   // The path to the executable.
   static const char* executable_name_;
diff --git a/runtime/bin/platform_android.cc b/runtime/bin/platform_android.cc
index dddb4e1..3c44c04 100644
--- a/runtime/bin/platform_android.cc
+++ b/runtime/bin/platform_android.cc
@@ -77,6 +77,10 @@
   return File::LinkTarget("/proc/self/exe");
 }
 
+void Platform::Exit(int exit_code) {
+  exit(exit_code);
+}
+
 }  // namespace bin
 }  // namespace dart
 
diff --git a/runtime/bin/platform_linux.cc b/runtime/bin/platform_linux.cc
index 8469a21..24cbfd3 100644
--- a/runtime/bin/platform_linux.cc
+++ b/runtime/bin/platform_linux.cc
@@ -77,6 +77,10 @@
   return File::LinkTarget("/proc/self/exe");
 }
 
+void Platform::Exit(int exit_code) {
+  exit(exit_code);
+}
+
 }  // namespace bin
 }  // namespace dart
 
diff --git a/runtime/bin/platform_macos.cc b/runtime/bin/platform_macos.cc
index 54b48d6..0f7c629 100644
--- a/runtime/bin/platform_macos.cc
+++ b/runtime/bin/platform_macos.cc
@@ -53,7 +53,11 @@
 
 
 const char* Platform::OperatingSystem() {
+#if TARGET_OS_IOS
+  return "ios";
+#else
   return "macos";
+#endif
 }
 
 
@@ -120,6 +124,10 @@
   return canon_path;
 }
 
+void Platform::Exit(int exit_code) {
+  exit(exit_code);
+}
+
 }  // namespace bin
 }  // namespace dart
 
diff --git a/runtime/bin/platform_win.cc b/runtime/bin/platform_win.cc
index 9830db2..9b29cb7 100644
--- a/runtime/bin/platform_win.cc
+++ b/runtime/bin/platform_win.cc
@@ -14,6 +14,10 @@
 
 
 namespace dart {
+
+// Defined in vm/os_thread_win.cc
+extern bool private_flag_windows_run_tls_destructors;
+
 namespace bin {
 
 bool Platform::Initialize() {
@@ -105,6 +109,14 @@
   return canon_path;
 }
 
+void Platform::Exit(int exit_code) {
+  // TODO(zra): Remove once VM shuts down cleanly.
+  ::dart::private_flag_windows_run_tls_destructors = false;
+  // On Windows we use ExitProcess so that threads can't clobber the exit_code.
+  // See: https://code.google.com/p/nativeclient/issues/detail?id=2870
+  ::ExitProcess(exit_code);
+}
+
 }  // namespace bin
 }  // namespace dart
 
diff --git a/runtime/bin/process.cc b/runtime/bin/process.cc
index 47e2ff5..8188693 100644
--- a/runtime/bin/process.cc
+++ b/runtime/bin/process.cc
@@ -17,10 +17,6 @@
 namespace dart {
 namespace bin {
 
-// Global flag that is used to indicate that the VM should do a clean
-// shutdown.
-bool do_vm_shutdown = false;
-
 static const int kProcessIdNativeField = 0;
 
 int Process::global_exit_code_ = 0;
@@ -254,26 +250,8 @@
   int64_t status = 0;
   // Ignore result if passing invalid argument and just exit 0.
   DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 0), &status);
-  Dart_ShutdownIsolate();
-  Process::TerminateExitCodeHandler();
-  char* error = Dart_Cleanup();
-  if (error != NULL) {
-    Log::PrintErr("VM cleanup failed: %s\n", error);
-    free(error);
-  }
-  if (do_vm_shutdown) {
-#ifdef LEGACY_DEBUG_PROTOCOL_ENABLED
-    // Note that this dependency crosses logical project boundaries by making
-    // the dart:io implementation depend upon the standalone VM's legacy debug
-    // protocol. This breaks projects which want to use our dart:io
-    // implementation. Because the protocol is going away shortly, it's
-    // reasonable to leave it behind a #ifdef that is only enabled for the
-    // standalone VM for now.
-    DebuggerConnectionHandler::StopHandler();
-#endif
-    EventHandler::Stop();
-  }
-  exit(static_cast<int>(status));
+  Dart_ExitIsolate();
+  Platform::Exit(static_cast<int>(status));
 }
 
 
diff --git a/runtime/bin/resources_sources.gypi b/runtime/bin/resources_sources.gypi
index 1469d82..91e0255 100644
--- a/runtime/bin/resources_sources.gypi
+++ b/runtime/bin/resources_sources.gypi
@@ -7,11 +7,8 @@
   'sources': [
 # Standalone VM service sources.
     'vmservice/loader.dart',
-    'vmservice/resources.dart',
     'vmservice/server.dart',
     'vmservice/vmservice_io.dart',
-# We no longer list client sources explicitly and instead include all deployed
-# files.
   ],
 }
 
diff --git a/runtime/bin/run_vm_tests.cc b/runtime/bin/run_vm_tests.cc
index c45a2a0..19ef7e9b 100644
--- a/runtime/bin/run_vm_tests.cc
+++ b/runtime/bin/run_vm_tests.cc
@@ -5,16 +5,20 @@
 #include <stdio.h>
 
 #include "bin/file.h"
+#include "bin/dartutils.h"
+#include "bin/platform.h"
 
 #include "vm/benchmark_test.h"
 #include "vm/dart.h"
-#include "bin/dartutils.h"
 #include "vm/unit_test.h"
 
 
 // TODO(iposva, asiva): This is a placeholder for the real unittest framework.
 namespace dart {
 
+// Defined in vm/os_thread_win.cc
+extern bool private_flag_windows_run_tls_destructors;
+
 // vm_isolate_snapshot_buffer points to a snapshot for the vm isolate if we
 // link in a snapshot otherwise it is initialized to NULL.
 extern const uint8_t* bin::vm_isolate_snapshot_buffer;
@@ -108,6 +112,7 @@
                                        dart::bin::DartUtils::ReadFile,
                                        dart::bin::DartUtils::WriteFile,
                                        dart::bin::DartUtils::CloseFile,
+                                       NULL,
                                        NULL);
   ASSERT(err_msg == NULL);
   // Apply the filter to all registered tests.
@@ -120,6 +125,11 @@
     ASSERT(err_msg == NULL);
   }
 
+#if defined(TARGET_OS_WINDOWS)
+  // TODO(zra): Remove once VM shuts down cleanly.
+  private_flag_windows_run_tls_destructors = false;
+#endif
+
   // Print a warning message if no tests or benchmarks were matched.
   if (run_matches == 0) {
     fprintf(stderr, "No tests matched: %s\n", run_filter);
diff --git a/runtime/bin/secure_socket.cc b/runtime/bin/secure_socket.cc
index c5bdae9..b1be87c 100644
--- a/runtime/bin/secure_socket.cc
+++ b/runtime/bin/secure_socket.cc
@@ -81,6 +81,7 @@
   Dart_Handle os_error = DartUtils::NewDartOSError(&os_error_struct);
   Dart_Handle exception =
       DartUtils::NewDartIOException(exception_type, message, os_error);
+  ASSERT(!Dart_IsError(exception));
   if (free_message) {
     free(const_cast<char*>(message));
   }
diff --git a/runtime/bin/thread_win.cc b/runtime/bin/thread_win.cc
index a69f82c..05949a1 100644
--- a/runtime/bin/thread_win.cc
+++ b/runtime/bin/thread_win.cc
@@ -104,12 +104,22 @@
 
 bool Thread::Join(ThreadId id) {
   HANDLE handle = OpenThread(SYNCHRONIZE, false, id);
-  if (handle == INVALID_HANDLE_VALUE) {
+
+  // TODO(zra): OSThread::Start() closes the handle to the thread. Thus, by the
+  // time we try to join the thread, its resources may have already been
+  // reclaimed, and joining will fail. This can be avoided in a couple of ways.
+  // First, GetCurrentThreadJoinId could call OpenThread and return a handle.
+  // This is bad, because each of those handles would have to be closed.
+  // Second OSThread could be refactored to no longer be AllStatic. Then the
+  // handle could be cached in the object by the Start method.
+  if (handle == NULL) {
     return false;
   }
+
   DWORD res = WaitForSingleObject(handle, INFINITE);
   CloseHandle(handle);
-  return res == WAIT_OBJECT_0;
+  ASSERT(res == WAIT_OBJECT_0);
+  return true;
 }
 
 
diff --git a/runtime/bin/thread_win.h b/runtime/bin/thread_win.h
index e500b16..5e1dba51 100644
--- a/runtime/bin/thread_win.h
+++ b/runtime/bin/thread_win.h
@@ -18,7 +18,6 @@
 typedef DWORD ThreadLocalKey;
 typedef DWORD ThreadId;
 
-
 class ThreadInlineImpl {
  private:
   ThreadInlineImpl() {}
diff --git a/runtime/bin/vmservice/resources.dart b/runtime/bin/vmservice/resources.dart
deleted file mode 100644
index 9153455..0000000
--- a/runtime/bin/vmservice/resources.dart
+++ /dev/null
@@ -1,62 +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.
-
-part of vmservice_io;
-
-String detectMimeType(String name) {
-  var extensionStart = name.lastIndexOf('.');
-  var extension = name.substring(extensionStart+1);
-  switch (extension) {
-    case 'html':
-      return 'text/html; charset=UTF-8';
-    case 'dart':
-      return 'application/dart; charset=UTF-8';
-    case 'js':
-      return 'application/javascript; charset=UTF-8';
-    case 'css':
-      return 'text/css; charset=UTF-8';
-    case 'gif':
-      return 'image/gif';
-    case 'png':
-      return 'image/png';
-    case 'jpg':
-      return 'image/jpeg';
-    case 'jpeg':
-      return 'image/jpeg';
-    case 'svg':
-      return 'image/svg+xml';
-    default:
-      return 'text/plain';
-  }
-}
-
-
-class Resource {
-  final String name;
-  final String mimeType;
-  final List<int> data;
-  Resource(this.name, this.mimeType, this.data);
-  static final Map<String, Resource> resources = new Map<String, Resource>();
-}
-
-ZLibCodec _zlib;
-
-void _addResource(String name, List<int> data, bool compressed) {
-  var mimeType = detectMimeType(name);
-  if (compressed) {
-    if (_zlib == null) {
-      _zlib = new ZLibCodec();
-    }
-    try {
-      data = _zlib.decode(data);
-    } catch(e) {
-      print('error decompressing service isolate resource: $name');
-      return;
-    }
-  }
-  Resource resource = new Resource(name, mimeType, data);
-  Resource.resources[name] = resource;
-}
-
-void _triggerResourceLoad() native "VMServiceIO_TriggerResourceLoad";
\ No newline at end of file
diff --git a/runtime/bin/vmservice/server.dart b/runtime/bin/vmservice/server.dart
index 8697e65..69e9b2e 100644
--- a/runtime/bin/vmservice/server.dart
+++ b/runtime/bin/vmservice/server.dart
@@ -130,18 +130,20 @@
           request.uri.path == '/' ? ROOT_REDIRECT_PATH : request.uri.path;
 
     if (path == WEBSOCKET_PATH) {
-      WebSocketTransformer.upgrade(request).then((WebSocket webSocket) {
+      WebSocketTransformer.upgrade(request,
+                                   compression: CompressionOptions.OFF).then(
+                                   (WebSocket webSocket) {
         new WebSocketClient(webSocket, _service);
       });
       return;
     }
 
-    var resource = Resource.resources[path];
-    if (resource != null) {
-      // Serving up a static resource (e.g. .css, .html, .png).
+    Asset asset = assets[path];
+    if (asset != null) {
+      // Serving up a static asset (e.g. .css, .html, .png).
       request.response.headers.contentType =
-          ContentType.parse(resource.mimeType);
-      request.response.add(resource.data);
+          ContentType.parse(asset.mimeType);
+      request.response.add(asset.data);
       request.response.close();
       return;
     }
diff --git a/runtime/bin/vmservice/vmservice_io.dart b/runtime/bin/vmservice/vmservice_io.dart
index eb44a6c..1f7eee2 100644
--- a/runtime/bin/vmservice/vmservice_io.dart
+++ b/runtime/bin/vmservice/vmservice_io.dart
@@ -11,7 +11,6 @@
 import 'dart:_vmservice';
 
 part 'loader.dart';
-part 'resources.dart';
 part 'server.dart';
 
 // The TCP ip/port that the HTTP server listens on.
@@ -25,9 +24,10 @@
 var _signalWatch;
 var _signalSubscription;
 
-// HTTP servr.
+// HTTP server.
 Server server;
 Future<Server> serverFuture;
+Map<String, Asset> assets;
 
 _onShutdown() {
   if (server != null) {
@@ -42,8 +42,11 @@
 }
 
 _bootServer() {
-  // Load resources.
-  _triggerResourceLoad();
+  try {
+    assets = Asset.request();
+  } catch (e) {
+    print('Could not load Observatory assets: $e');
+  }
   // Lazily create service.
   var service = new VMService();
   service.onShutdown = _onShutdown;
diff --git a/runtime/bin/vmservice_dartium.cc b/runtime/bin/vmservice_dartium.cc
index 40e61ef..6215fe71 100644
--- a/runtime/bin/vmservice_dartium.cc
+++ b/runtime/bin/vmservice_dartium.cc
@@ -70,7 +70,8 @@
 
   ASSERT(Dart_IsServiceIsolate(isolate));
   if (!VmService::Setup(DEFAULT_VM_SERVICE_SERVER_IP,
-                        DEFAULT_VM_SERVICE_SERVER_PORT)) {
+                        DEFAULT_VM_SERVICE_SERVER_PORT,
+                        false /* running_precompiled */)) {
     fprintf(stderr,
             "Vmservice::Setup failed: %s\n", VmService::GetErrorMessage());
     isolate = NULL;
diff --git a/runtime/bin/vmservice_impl.cc b/runtime/bin/vmservice_impl.cc
index 6ffe61e..2a38c32 100644
--- a/runtime/bin/vmservice_impl.cc
+++ b/runtime/bin/vmservice_impl.cc
@@ -31,6 +31,7 @@
   }
 
 #define kLibrarySourceNamePrefix "/vmservice"
+static const char* kVMServiceIOLibraryUri = "dart:vmservice_io";
 static const char* kVMServiceIOLibraryScriptResourceName = "vmservice_io.dart";
 
 struct ResourcesEntry {
@@ -160,7 +161,23 @@
 intptr_t VmService::server_port_ = 0;
 
 
-bool VmService::Setup(const char* server_ip, intptr_t server_port) {
+bool VmService::LoadForGenPrecompiled() {
+  Dart_Handle result;
+  Dart_SetLibraryTagHandler(LibraryTagHandler);
+  Dart_Handle library = LoadLibrary(kVMServiceIOLibraryScriptResourceName);
+  ASSERT(library != Dart_Null());
+  SHUTDOWN_ON_ERROR(library);
+  result = Dart_SetNativeResolver(library, VmServiceIONativeResolver, NULL);
+  SHUTDOWN_ON_ERROR(result);
+  result = Dart_FinalizeLoading(false);
+  SHUTDOWN_ON_ERROR(result);
+  return true;
+}
+
+
+bool VmService::Setup(const char* server_ip,
+                      intptr_t server_port,
+                      bool running_precompiled) {
   Dart_Isolate isolate = Dart_CurrentIsolate();
   ASSERT(isolate != NULL);
   SetServerIPAndPort("", 0);
@@ -177,15 +194,25 @@
       NULL, NULL, NULL, true, false, builtin_lib);
   SHUTDOWN_ON_ERROR(result);
 
-  // Load main script.
-  Dart_SetLibraryTagHandler(LibraryTagHandler);
-  Dart_Handle library = LoadScript(kVMServiceIOLibraryScriptResourceName);
-  ASSERT(library != Dart_Null());
-  SHUTDOWN_ON_ERROR(library);
-  result = Dart_SetNativeResolver(library, VmServiceIONativeResolver, NULL);
-  SHUTDOWN_ON_ERROR(result);
-  result = Dart_FinalizeLoading(false);
-  SHUTDOWN_ON_ERROR(result);
+  if (running_precompiled) {
+    Dart_Handle url = DartUtils::NewString(kVMServiceIOLibraryUri);
+    Dart_Handle library = Dart_LookupLibrary(url);
+    SHUTDOWN_ON_ERROR(library);
+    result = Dart_SetRootLibrary(library);
+    SHUTDOWN_ON_ERROR(library);
+    result = Dart_SetNativeResolver(library, VmServiceIONativeResolver, NULL);
+    SHUTDOWN_ON_ERROR(result);
+  } else {
+    // Load main script.
+    Dart_SetLibraryTagHandler(LibraryTagHandler);
+    Dart_Handle library = LoadScript(kVMServiceIOLibraryScriptResourceName);
+    ASSERT(library != Dart_Null());
+    SHUTDOWN_ON_ERROR(library);
+    result = Dart_SetNativeResolver(library, VmServiceIONativeResolver, NULL);
+    SHUTDOWN_ON_ERROR(result);
+    result = Dart_FinalizeLoading(false);
+    SHUTDOWN_ON_ERROR(result);
+  }
 
   // Make runnable.
   Dart_ExitScope();
@@ -200,7 +227,7 @@
   Dart_EnterIsolate(isolate);
   Dart_EnterScope();
 
-  library = Dart_RootLibrary();
+  Dart_Handle library = Dart_RootLibrary();
   SHUTDOWN_ON_ERROR(library);
 
   // Set HTTP server state.
@@ -279,16 +306,23 @@
 
 
 Dart_Handle VmService::LoadScript(const char* name) {
-  Dart_Handle url = Dart_NewStringFromCString("dart:vmservice_io");
+  Dart_Handle uri = Dart_NewStringFromCString(kVMServiceIOLibraryUri);
   Dart_Handle source = GetSource(name);
-  return Dart_LoadScript(url, source, 0, 0);
+  return Dart_LoadScript(uri, source, 0, 0);
+}
+
+
+Dart_Handle VmService::LoadLibrary(const char* name) {
+  Dart_Handle uri = Dart_NewStringFromCString(kVMServiceIOLibraryUri);
+  Dart_Handle source = GetSource(name);
+  return Dart_LoadLibrary(uri, source, 0, 0);
 }
 
 
 Dart_Handle VmService::LoadSource(Dart_Handle library, const char* name) {
-  Dart_Handle url = Dart_NewStringFromCString(name);
+  Dart_Handle uri = Dart_NewStringFromCString(name);
   Dart_Handle source = GetSource(name);
-  return Dart_LoadSource(library, url, source, 0, 0);
+  return Dart_LoadSource(library, uri, source, 0, 0);
 }
 
 
diff --git a/runtime/bin/vmservice_impl.h b/runtime/bin/vmservice_impl.h
index e53c752..590aece 100644
--- a/runtime/bin/vmservice_impl.h
+++ b/runtime/bin/vmservice_impl.h
@@ -14,7 +14,11 @@
 
 class VmService {
  public:
-  static bool Setup(const char* server_ip, intptr_t server_port);
+  static bool LoadForGenPrecompiled();
+
+  static bool Setup(const char* server_ip,
+                    intptr_t server_port,
+                    bool running_precompiled);
 
   // Error message if startup failed.
   static const char* GetErrorMessage();
@@ -37,6 +41,7 @@
   static void SetServerIPAndPort(const char* ip, intptr_t port);
   static Dart_Handle GetSource(const char* name);
   static Dart_Handle LoadScript(const char* name);
+  static Dart_Handle LoadLibrary(const char* name);
   static Dart_Handle LoadSource(Dart_Handle library, const char* name);
   static Dart_Handle LoadResources(Dart_Handle library);
   static Dart_Handle LoadResource(Dart_Handle library, const char* name);
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index e6f643c..29826af 100755
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -868,6 +868,18 @@
 typedef bool (*Dart_EntropySource)(uint8_t* buffer, intptr_t length);
 
 /**
+ * Callback provided by the embedder that is used by the vmservice isolate
+ * to request the asset archive. The asset archive must be an uncompressed tar
+ * archive that is stored in a Uint8List.
+ *
+ * If the embedder has no vmservice isolate assets, the callback can be NULL.
+ *
+ * \return The embedder must return a handle to a Uint8List containing an
+ *   uncompressed tar archive or null.
+ */
+typedef Dart_Handle (*Dart_GetVMServiceAssetsArchive)();
+
+/**
  * Initializes the VM.
  *
  * \param vm_isolate_snapshot A buffer containing a snapshot of the VM isolate
@@ -883,6 +895,10 @@
  * \param shutdown A function to be called when an isolate is shutdown.
  *   See Dart_IsolateShutdownCallback.
  *
+ * \param get_service_assets A function to be called by the service isolate when
+ *    it requires the vmservice assets archive.
+ *    See Dart_GetVMServiceAssetsArchive.
+ *
  * \return NULL if initialization is successful. Returns an error message
  *   otherwise. The caller is responsible for freeing the error message.
  */
@@ -897,7 +913,8 @@
     Dart_FileReadCallback file_read,
     Dart_FileWriteCallback file_write,
     Dart_FileCloseCallback file_close,
-    Dart_EntropySource entropy_source);
+    Dart_EntropySource entropy_source,
+    Dart_GetVMServiceAssetsArchive get_service_assets);
 
 /**
  * Cleanup state in the VM before process termination.
@@ -1010,14 +1027,25 @@
 DART_EXPORT void Dart_EnterIsolate(Dart_Isolate isolate);
 
 /**
- * Notifies the VM that the current isolate is about to make a blocking call.
+ * Notifies the VM that the current thread should not be profiled until a
+ * matching call to Dart_ThreadEnableProfiling is made.
+ *
+ * NOTE: By default, if a thread has entered an isolate it will be profiled.
+ * This function should be used when an embedder knows a thread is about
+ * to make a blocking call and wants to avoid unnecessary interrupts by
+ * the profiler.
  */
-DART_EXPORT void Dart_IsolateBlocked();
+DART_EXPORT void Dart_ThreadDisableProfiling();
 
 /**
- * Notifies the VM that the current isolate is no longer blocked.
+ * Notifies the VM that the current thread should be profiled.
+ *
+ * NOTE: It is only legal to call this function *after* calling
+ *   Dart_ThreadDisableProfiling.
+ *
+ * NOTE: By default, if a thread has entered an isolate it will be profiled.
  */
-DART_EXPORT void Dart_IsolateUnblocked();
+DART_EXPORT void Dart_ThreadEnableProfiling();
 
 /**
  * Exits an isolate. After this call, Dart_CurrentIsolate will
@@ -2103,8 +2131,8 @@
  *
  * \param type Type of object to be constructed.
  * \param constructor_name The name of the constructor to invoke.  Use
- *   Dart_Null() to invoke the unnamed constructor.  This name should
- *   not include the name of the class.
+ *   Dart_Null() or Dart_EmptyString() to invoke the unnamed constructor.
+ *   This name should not include the name of the class.
  * \param number_of_arguments Size of the arguments array.
  * \param arguments An array of arguments to the constructor.
  *
@@ -2197,6 +2225,7 @@
  *
  * \param target An object.
  * \param name The name of the constructor to invoke.
+ *   Use Dart_Null() or Dart_EmptyString() to invoke the unnamed constructor.
  * \param number_of_arguments Size of the arguments array.
  * \param arguments An array of arguments to the function.
  *
@@ -2697,6 +2726,15 @@
  */
 DART_EXPORT Dart_Handle Dart_RootLibrary();
 
+
+/**
+ * Sets the root library for the current isolate.
+ *
+ * \return Returns an error handle if `library` is not a library handle.
+ */
+DART_EXPORT Dart_Handle Dart_SetRootLibrary(Dart_Handle library);
+
+
 /**
  * Lookup or instantiate a type by name and type arguments from a Library.
  *
diff --git a/runtime/include/dart_tools_api.h b/runtime/include/dart_tools_api.h
index 88c2616..13be4f9 100644
--- a/runtime/include/dart_tools_api.h
+++ b/runtime/include/dart_tools_api.h
@@ -894,20 +894,23 @@
 #define DART_TIMELINE_STREAM_COMPILER (1 << 1)
 /** Timeline stream for Dart provided events */
 #define DART_TIMELINE_STREAM_DART (1 << 2)
+/** Timeline stream for debugger provided events */
+#define DART_TIMELINE_STREAM_DEBUGGER (1 << 3)
 /** Timeline stream for embedder provided events */
-#define DART_TIMELINE_STREAM_EMBEDDER (1 << 3)
+#define DART_TIMELINE_STREAM_EMBEDDER (1 << 4)
 /** Timeline stream for GC events */
-#define DART_TIMELINE_STREAM_GC (1 << 4)
+#define DART_TIMELINE_STREAM_GC (1 << 5)
 /** Timeline stream for isolate events */
-#define DART_TIMELINE_STREAM_ISOLATE (1 << 5)
+#define DART_TIMELINE_STREAM_ISOLATE (1 << 6)
 
 /** Timeline stream for VM events */
-#define DART_TIMELINE_STREAM_VM (1 << 6)
+#define DART_TIMELINE_STREAM_VM (1 << 7)
 
 /** Enable all timeline stream recording for an isolate */
 #define DART_TIMELINE_STREAM_ALL (DART_TIMELINE_STREAM_API |                   \
                                   DART_TIMELINE_STREAM_COMPILER |              \
                                   DART_TIMELINE_STREAM_DART |                  \
+                                  DART_TIMELINE_STREAM_DEBUGGER |              \
                                   DART_TIMELINE_STREAM_EMBEDDER |              \
                                   DART_TIMELINE_STREAM_GC |                    \
                                   DART_TIMELINE_STREAM_ISOLATE)
diff --git a/runtime/lib/array_patch.dart b/runtime/lib/array_patch.dart
index abe5a19..c0ddfee 100644
--- a/runtime/lib/array_patch.dart
+++ b/runtime/lib/array_patch.dart
@@ -20,10 +20,10 @@
     return new _List<E>(length);
   }
 
-  /* patch */ factory List.filled(int length, E fill) {
+  /* patch */ factory List.filled(int length, E fill, {bool growable: false}) {
     // All error handling on the length parameter is done at the implementation
     // of new _List.
-    var result = new _List<E>(length);
+    var result = growable ? new _GrowableList<E>(length) : new _List<E>(length);
     if (fill != null) {
       for (int i = 0; i < length; i++) {
         result[i] = fill;
diff --git a/runtime/lib/bool.cc b/runtime/lib/bool.cc
index 83d370f..b536ccf 100644
--- a/runtime/lib/bool.cc
+++ b/runtime/lib/bool.cc
@@ -21,7 +21,7 @@
   GET_NATIVE_ARGUMENT(Bool, default_value, arguments->NativeArgAt(2));
   // Call the embedder to supply us with the environment.
   const String& env_value =
-      String::Handle(Api::CallEnvironmentCallback(isolate, name));
+      String::Handle(Api::CallEnvironmentCallback(thread, name));
   if (!env_value.IsNull()) {
     if (Symbols::True().Equals(env_value)) {
       return Bool::True().raw();
diff --git a/runtime/lib/double.dart b/runtime/lib/double.dart
index ea7c1cf..87d8046 100644
--- a/runtime/lib/double.dart
+++ b/runtime/lib/double.dart
@@ -46,17 +46,14 @@
     return _remainder(other.toDouble());
   }
   double _remainder(double other) native "Double_remainder";
-  double operator -() {
-    // Handles properly 0.0, NAN, and other doubles.
-    return this._flipSignBit;
-  }
-  double get _flipSignBit native "Double_flipSignBit";
+
+  double operator -() native "Double_flipSignBit";
 
   bool operator ==(other) {
     if (!(other is num)) return false;
     return _equal(other.toDouble());
   }
-  bool _equal(double other)native "Double_equal";
+  bool _equal(double other) native "Double_equal";
   bool _equalToInteger(int other) native "Double_equalToInteger";
   bool operator <(num other) {
     return other > this;
diff --git a/runtime/lib/integers.cc b/runtime/lib/integers.cc
index e8d655c..8deeee4 100644
--- a/runtime/lib/integers.cc
+++ b/runtime/lib/integers.cc
@@ -237,7 +237,7 @@
   GET_NATIVE_ARGUMENT(Integer, default_value, arguments->NativeArgAt(2));
   // Call the embedder to supply us with the environment.
   const String& env_value =
-      String::Handle(Api::CallEnvironmentCallback(isolate, name));
+      String::Handle(Api::CallEnvironmentCallback(thread, name));
   if (!env_value.IsNull()) {
     const Integer& result = Integer::Handle(ParseInteger(env_value));
     if (!result.IsNull()) {
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index 349788c..00efcae 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -2,6 +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 "include/dart_native_api.h"
 #include "platform/assert.h"
 #include "vm/bootstrap_natives.h"
 #include "vm/class_finalizer.h"
@@ -125,60 +126,70 @@
 }
 
 
-static bool CreateIsolate(Isolate* parent_isolate,
-                          IsolateSpawnState* state,
-                          char** error) {
-  Dart_IsolateCreateCallback callback = Isolate::CreateCallback();
-  if (callback == NULL) {
-    *error = strdup("Null callback specified for isolate creation\n");
-    return false;
+class SpawnIsolateTask : public ThreadPool::Task {
+ public:
+  explicit SpawnIsolateTask(IsolateSpawnState* state) : state_(state) {}
+
+  virtual void Run() {
+    // Create a new isolate.
+    char* error = NULL;
+    Dart_IsolateCreateCallback callback = Isolate::CreateCallback();
+    if (callback == NULL) {
+      ReportError(
+          "Isolate spawn is not supported by this Dart implementation\n");
+      delete state_;
+      state_ = NULL;
+      return;
+    }
+
+    Dart_IsolateFlags api_flags;
+    state_->isolate_flags()->CopyTo(&api_flags);
+
+    Isolate* isolate = reinterpret_cast<Isolate*>(
+        (callback)(state_->script_url(),
+                   state_->function_name(),
+                   state_->package_root(),
+                   state_->package_map(),
+                   &api_flags,
+                   state_->init_data(),
+                   &error));
+    if (isolate == NULL) {
+      ReportError(error);
+      delete state_;
+      state_ = NULL;
+      free(error);
+      return;
+    }
+
+    if (state_->origin_id() != ILLEGAL_PORT) {
+      // For isolates spawned using spawnFunction we set the origin_id
+      // to the origin_id of the parent isolate.
+      isolate->set_origin_id(state_->origin_id());
+    }
+    MutexLocker ml(isolate->mutex());
+    state_->set_isolate(reinterpret_cast<Isolate*>(isolate));
+    isolate->set_spawn_state(state_);
+    state_ = NULL;
+    if (isolate->is_runnable()) {
+      isolate->Run();
+    }
   }
 
-  Dart_IsolateFlags api_flags;
-  state->isolate_flags()->CopyTo(&api_flags);
+ private:
+  void ReportError(const char* error) {
+    Dart_CObject error_cobj;
+    error_cobj.type = Dart_CObject_kString;
+    error_cobj.value.as_string = const_cast<char*>(error);
+    if (!Dart_PostCObject(state_->parent_port(), &error_cobj)) {
+      // Perhaps the parent isolate died or closed the port before we
+      // could report the error.  Ignore.
+    }
+  }
 
-  void* init_data = parent_isolate->init_callback_data();
-  Isolate* child_isolate = reinterpret_cast<Isolate*>(
-      (callback)(state->script_url(),
-                 state->function_name(),
-                 state->package_root(),
-                 state->package_map(),
-                 &api_flags,
-                 init_data,
-                 error));
-  if (child_isolate == NULL) {
-    return false;
-  }
-  if (!state->is_spawn_uri()) {
-    // For isolates spawned using the spawn semantics we set
-    // the origin_id to the origin_id of the parent isolate.
-    child_isolate->set_origin_id(parent_isolate->origin_id());
-  }
-  state->set_isolate(reinterpret_cast<Isolate*>(child_isolate));
-  return true;
-}
+  IsolateSpawnState* state_;
 
-
-static void Spawn(Isolate* parent_isolate, IsolateSpawnState* state) {
-  Thread::ExitIsolate();
-  // Create a new isolate.
-  char* error = NULL;
-  if (!CreateIsolate(parent_isolate, state, &error)) {
-    Thread::EnterIsolate(parent_isolate);
-    delete state;
-    const String& msg = String::Handle(String::New(error));
-    free(error);
-    ThrowIsolateSpawnException(msg);
-  }
-  Thread::EnterIsolate(parent_isolate);
-  // Start the new isolate if it is already marked as runnable.
-  Isolate* spawned_isolate = state->isolate();
-  MutexLocker ml(spawned_isolate->mutex());
-  spawned_isolate->set_spawn_state(state);
-  if (spawned_isolate->is_runnable()) {
-    spawned_isolate->Run();
-  }
-}
+  DISALLOW_COPY_AND_ASSIGN(SpawnIsolateTask);
+};
 
 
 DEFINE_NATIVE_ENTRY(Isolate_spawnFunction, 7) {
@@ -206,13 +217,16 @@
       Dart_Port on_exit_port = onExit.IsNull() ? ILLEGAL_PORT : onExit.Id();
       Dart_Port on_error_port = onError.IsNull() ? ILLEGAL_PORT : onError.Id();
 
-      Spawn(isolate, new IsolateSpawnState(port.Id(),
-                                           func,
-                                           message,
-                                           paused.value(),
-                                           fatal_errors,
-                                           on_exit_port,
-                                           on_error_port));
+      Dart::thread_pool()->Run(new SpawnIsolateTask(
+          new IsolateSpawnState(port.Id(),
+                                isolate->origin_id(),
+                                isolate->init_callback_data(),
+                                func,
+                                message,
+                                paused.value(),
+                                fatal_errors,
+                                on_exit_port,
+                                on_error_port)));
       return Object::null();
     }
   }
@@ -233,12 +247,13 @@
 }
 
 
-static char* CanonicalizeUri(Isolate* isolate,
+static char* CanonicalizeUri(Thread* thread,
                              const Library& library,
                              const String& uri,
                              char** error) {
   char* result = NULL;
-  Zone* zone = isolate->current_zone();
+  Zone* zone = thread->zone();
+  Isolate* isolate = thread->isolate();
   Dart_LibraryTagHandler handler = isolate->library_tag_handler();
   if (handler != NULL) {
     Dart_EnterScope();
@@ -292,7 +307,7 @@
   const Library& root_lib =
       Library::Handle(isolate->object_store()->root_library());
   char* error = NULL;
-  char* canonical_uri = CanonicalizeUri(isolate, root_lib, uri, &error);
+  char* canonical_uri = CanonicalizeUri(thread, root_lib, uri, &error);
   if (canonical_uri == NULL) {
     const String& msg = String::Handle(String::New(error));
     ThrowIsolateSpawnException(msg);
@@ -326,6 +341,7 @@
 
   IsolateSpawnState* state = new IsolateSpawnState(
       port.Id(),
+      isolate->init_callback_data(),
       canonical_uri,
       utf8_package_root,
       const_cast<const char**>(utf8_package_map),
@@ -341,7 +357,7 @@
     state->isolate_flags()->set_checked(checked.value());
   }
 
-  Spawn(isolate, state);
+  Dart::thread_pool()->Run(new SpawnIsolateTask(state));
   return Object::null();
 }
 
diff --git a/runtime/lib/isolate_patch.dart b/runtime/lib/isolate_patch.dart
index 41389a5..bb37371 100644
--- a/runtime/lib/isolate_patch.dart
+++ b/runtime/lib/isolate_patch.dart
@@ -130,8 +130,6 @@
     return sendPort.hashCode;
   }
 
-  Uri get remotePortUri => new Uri.https('localhost', '55');
-
   /**** Internal implementation details ****/
   _get_id() native "RawReceivePortImpl_get_id";
   _get_sendport() native "RawReceivePortImpl_get_sendport";
@@ -286,18 +284,7 @@
       readyPort = new RawReceivePort();
       _spawnFunction(readyPort.sendPort, entryPoint, message,
                      paused, errorsAreFatal, onExit, onError);
-      Completer completer = new Completer<Isolate>.sync();
-      readyPort.handler = (readyMessage) {
-        readyPort.close();
-        assert(readyMessage is List);
-        assert(readyMessage.length == 2);
-        SendPort controlPort = readyMessage[0];
-        List capabilities = readyMessage[1];
-        completer.complete(new Isolate(controlPort,
-                                       pauseCapability: capabilities[0],
-                                       terminateCapability: capabilities[1]));
-      };
-      return completer.future;
+      return _spawnCommon(readyPort);
     } catch (e, st) {
       if (readyPort != null) {
         readyPort.close();
@@ -330,24 +317,36 @@
                 errorsAreFatal, checked,
                 null, /* environment */
                 packageRootString, packagesList);
-      Completer completer = new Completer<Isolate>.sync();
-      readyPort.handler = (readyMessage) {
-        readyPort.close();
-        assert(readyMessage is List);
-        assert(readyMessage.length == 2);
-        SendPort controlPort = readyMessage[0];
-        List capabilities = readyMessage[1];
-        completer.complete(new Isolate(controlPort,
-                                       pauseCapability: capabilities[0],
-                                       terminateCapability: capabilities[1]));
-      };
-      return completer.future;
+      return _spawnCommon(readyPort);
     } catch (e, st) {
       if (readyPort != null) {
         readyPort.close();
       }
       return new Future<Isolate>.error(e, st);
     }
+  }
+
+  static Future<Isolate> _spawnCommon(RawReceivePort readyPort) {
+    Completer completer = new Completer<Isolate>.sync();
+    readyPort.handler = (readyMessage) {
+      readyPort.close();
+      if (readyMessage is List && readyMessage.length == 2) {
+        SendPort controlPort = readyMessage[0];
+        List capabilities = readyMessage[1];
+        completer.complete(new Isolate(controlPort,
+                                       pauseCapability: capabilities[0],
+                                       terminateCapability: capabilities[1]));
+      } else if (readyMessage is String) {
+        // We encountered an error while starting the new isolate.
+        completer.completeError(new IsolateSpawnException(
+            'Unable to spawn isolate: ${readyMessage}'));
+      } else {
+        // This shouldn't happen.
+        completer.completeError(new IsolateSpawnException(
+            "Internal error: unexpected format for ready message: "
+            "'${readyMessage}'"));
+      }
+    };
     return completer.future;
   }
 
diff --git a/runtime/lib/lib_prefix.dart b/runtime/lib/lib_prefix.dart
index fb9fe81..4f509da 100644
--- a/runtime/lib/lib_prefix.dart
+++ b/runtime/lib/lib_prefix.dart
@@ -7,21 +7,24 @@
 
 // This type corresponds to the VM-internal class LibraryPrefix.
 class _LibraryPrefix {
-
   bool _load() native "LibraryPrefix_load";
   Error _loadError() native "LibraryPrefix_loadError";
   bool isLoaded() native "LibraryPrefix_isLoaded";
-
   bool _invalidateDependentCode()
       native "LibraryPrefix_invalidateDependentCode";
 
   loadLibrary() {
-    var completer = _outstandingLoadRequests[this];
-    if (completer != null) {
-      return completer.future;
+    for (int i = 0; i < _outstandingLoadRequests.length; i++) {
+      if (_outstandingLoadRequests[i][0] == this) {
+        return _outstandingLoadRequests[i][1].future;
+      }
     }
-    completer = new Completer<bool>();
-    _outstandingLoadRequests[this] = completer;
+
+    var completer = new Completer<bool>();
+    var pair = new List();
+    pair.add(this);
+    pair.add(completer);
+    _outstandingLoadRequests.add(pair);
     Timer.run(() {
       var hasCompleted = this._load();
       // Loading can complete immediately, for example when the same
@@ -32,20 +35,23 @@
       if (hasCompleted) {
         _invalidateDependentCode();
         completer.complete(true);
-        _outstandingLoadRequests.remove(this);
+        _outstandingLoadRequests.remove(pair);
       }
     });
     return completer.future;
   }
 }
 
-var _outstandingLoadRequests = new Map<_LibraryPrefix, Completer>();
-
+// A list of two element lists. The first element is the _LibraryPrefix. The
+// second element is the Completer for the load request.
+var _outstandingLoadRequests = new List<List>();
 
 // Called from the VM when all outstanding load requests have
 // finished.
 _completeDeferredLoads() {
-  _outstandingLoadRequests.forEach((prefix, completer) {
+  for (int i = 0; i < _outstandingLoadRequests.length; i++) {
+    var prefix = _outstandingLoadRequests[i][0];
+    var completer = _outstandingLoadRequests[i][1];
     var error = prefix._loadError();
     if (error != null) {
       completer.completeError(error);
@@ -53,6 +59,6 @@
       prefix._invalidateDependentCode();
       completer.complete(true);
     }
-  });
+  }
   _outstandingLoadRequests.clear();
 }
diff --git a/runtime/lib/libgen_in.cc b/runtime/lib/libgen_in.cc
index 03dedf8..4e10df6 100644
--- a/runtime/lib/libgen_in.cc
+++ b/runtime/lib/libgen_in.cc
@@ -9,5 +9,5 @@
 const char* {{VAR_NAME}}[] = {
 {{LIBRARY_SOURCE_MAP}}
 {{PART_SOURCE_MAP}}
-  NULL, NULL
+  NULL, NULL, NULL
 };
diff --git a/runtime/lib/math.cc b/runtime/lib/math.cc
index f4b4626..d383471 100644
--- a/runtime/lib/math.cc
+++ b/runtime/lib/math.cc
@@ -93,9 +93,10 @@
 
 
 // Implements:
-//   var state = ((_A * (_state[kSTATE_LO])) + _state[kSTATE_HI]) & _MASK_64;
-//   _state[kSTATE_LO] = state & _MASK_32;
-//   _state[kSTATE_HI] = state >> 32;
+//   var state =
+//       ((_A * (_state[_kSTATE_LO])) + _state[_kSTATE_HI]) & (1 << 64) - 1);
+//   _state[_kSTATE_LO] = state & (1 << 32) - 1);
+//   _state[_kSTATE_HI] = state >> 32;
 DEFINE_NATIVE_ENTRY(Random_nextState, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, receiver, arguments->NativeArgAt(0));
   const TypedData& array = TypedData::Handle(GetRandomStateArray(receiver));
@@ -145,8 +146,8 @@
 //     hash = 0x5A17;
 //   }
 //   var result = new Uint32List(2);
-//   result[kSTATE_LO] = seed & _MASK_32;
-//   result[kSTATE_HI] = seed >> 32;
+//   result[_kSTATE_LO] = seed & ((1 << 32) - 1);
+//   result[_kSTATE_HI] = seed >> 32;
 //   return result;
 DEFINE_NATIVE_ENTRY(Random_setupSeed, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, seed_int, arguments->NativeArgAt(0));
@@ -198,4 +199,25 @@
   return CreateRandomState(zone, seed);
 }
 
+
+DEFINE_NATIVE_ENTRY(SecureRandom_getBytes, 1) {
+  GET_NON_NULL_NATIVE_ARGUMENT(Smi, count, arguments->NativeArgAt(0));
+  const intptr_t n = count.Value();
+  ASSERT((n > 0) && (n <= 8));
+  uint8_t buffer[8];
+  Dart_EntropySource entropy_source = isolate->entropy_source_callback();
+  if ((entropy_source == NULL) || !entropy_source(buffer, n)) {
+    const String& error = String::Handle(String::New(
+        "No source of cryptographically secure random numbers available."));
+    const Array& args = Array::Handle(Array::New(1));
+    args.SetAt(0, error);
+    Exceptions::ThrowByType(Exceptions::kUnsupported, args);
+  }
+  uint64_t result = 0;
+  for (intptr_t i = 0; i < n; i++) {
+    result = (result << 8) | buffer[i];
+  }
+  return Integer::New(result);
+}
+
 }  // namespace dart
diff --git a/runtime/lib/math_patch.dart b/runtime/lib/math_patch.dart
index e9cc083..667174c 100644
--- a/runtime/lib/math_patch.dart
+++ b/runtime/lib/math_patch.dart
@@ -90,14 +90,18 @@
                                         .._nextState()
                                         .._nextState();
   }
+
+  /*patch*/ factory Random.secure() {
+    return new _SecureRandom();
+  }
 }
 
 
 class _Random implements Random {
   // Internal state of the random number generator.
   final _state;
-  static const kSTATE_LO = 0;
-  static const kSTATE_HI = 1;
+  static const _kSTATE_LO = 0;
+  static const _kSTATE_HI = 1;  // Unused in Dart code.
 
   _Random._withState(Uint32List this._state);
 
@@ -106,32 +110,33 @@
   // The constant A is selected from "Numerical Recipes 3rd Edition" p.348 B1.
 
   // Implements:
-  //   var state = ((_A * (_state[kSTATE_LO])) + _state[kSTATE_HI]) & _MASK_64;
-  //   _state[kSTATE_LO] = state & _MASK_32;
-  //   _state[kSTATE_HI] = state >> 32;
+  //   var state =
+  //       ((_A * (_state[_kSTATE_LO])) + _state[_kSTATE_HI]) & ((1 << 64) - 1);
+  //   _state[_kSTATE_LO] = state & ((1 << 32) - 1);
+  //   _state[_kSTATE_HI] = state >> 32;
   // This is a native to prevent 64-bit operations in Dart, which
   // fail with --throw_on_javascript_int_overflow.
   void _nextState() native "Random_nextState";
 
   int nextInt(int max) {
     const limit = 0x3FFFFFFF;
-    if (max <= 0 || ((max > limit) && (max > _POW2_32))) {
-      throw new ArgumentError("max must be positive and < 2^32:"
-                                         " $max");
+    if ((max <= 0) || ((max > limit) && (max > _POW2_32))) {
+      throw new RangeError.range(max, 1, _POW2_32, "max",
+                                 "Must be positive and <= 2^32");
     }
     if ((max & -max) == max) {
       // Fast case for powers of two.
       _nextState();
-      return _state[kSTATE_LO] & (max - 1);
+      return _state[_kSTATE_LO] & (max - 1);
     }
 
     var rnd32;
     var result;
     do {
       _nextState();
-      rnd32 = _state[kSTATE_LO];
+      rnd32 = _state[_kSTATE_LO];
       result = rnd32 % max;
-    } while ((rnd32 - result + max) >= _POW2_32);
+    } while ((rnd32 - result + max) > _POW2_32);
     return result;
   }
 
@@ -143,9 +148,7 @@
     return nextInt(2) == 0;
   }
 
-  // Constants used by the algorithm or masking.
-  static const _MASK_32 = (1 << 32) - 1;
-  static const _MASK_64 = (1 << 64) - 1;
+  // Constants used by the algorithm.
   static const _POW2_32 = 1 << 32;
   static const _POW2_53_D = 1.0 * (1 << 53);
   static const _POW2_27_D = 1.0 * (1 << 27);
@@ -164,6 +167,46 @@
   static int _nextSeed() {
     // Trigger the PRNG once to change the internal state.
     _prng._nextState();
-    return _prng._state[kSTATE_LO];
+    return _prng._state[_kSTATE_LO];
   }
 }
+
+
+class _SecureRandom implements Random {
+  _SecureRandom() {
+    // Throw early in constructor if entropy source is not hooked up.
+    _getBytes(1);
+  }
+
+  // Return count bytes of entropy as a positive integer; count <= 8.
+  static int _getBytes(int count) native "SecureRandom_getBytes";
+
+  int nextInt(int max) {
+    RangeError.checkValueInInterval(
+        max, 1, _POW2_32, "max", "Must be positive and <= 2^32");
+    final byteCount = ((max - 1).bitLength + 7) >> 3;
+    if (byteCount == 0) {
+      return 0;  // Not random if max == 1.
+    }
+    var rnd;
+    var result;
+    do {
+      rnd = _getBytes(byteCount);
+      result = rnd % max;
+    } while ((rnd - result + max) > (1 << (byteCount << 3)));
+    return result;
+  }
+
+  double nextDouble() {
+    return (_getBytes(7) >> 3) / _POW2_53_D;
+  }
+
+  bool nextBool() {
+    return _getBytes(1).isEven;
+  }
+
+  // Constants used by the algorithm.
+  static const _POW2_32 = 1 << 32;
+  static const _POW2_53_D = 1.0 * (1 << 53);
+}
+
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index d33b754..4b8627f 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -1229,7 +1229,7 @@
   // arguments have been provided, or all arguments are dynamic. Return a list
   // of typemirrors on dynamic in this case.
   if (args.IsNull()) {
-    arg_type ^= Object::dynamic_type();
+    arg_type ^= Object::dynamic_type().raw();
     type_mirror ^= CreateTypeMirror(arg_type);
     for (intptr_t i = 0; i < num_params; i++) {
       result.SetAt(i, type_mirror);
diff --git a/runtime/lib/mirrors_impl.dart b/runtime/lib/mirrors_impl.dart
index 8b099c9..0a839fb 100644
--- a/runtime/lib/mirrors_impl.dart
+++ b/runtime/lib/mirrors_impl.dart
@@ -293,6 +293,7 @@
   bool get isConstConstructor => false;
   bool get isGenerativeConstructor => false;
   bool get isFactoryConstructor => false;
+  bool get isExternal => false;
   bool get isRedirectingConstructor => false;
   bool get isAbstract => false;
 
diff --git a/runtime/lib/string.cc b/runtime/lib/string.cc
index 2eae245..62e5aac 100644
--- a/runtime/lib/string.cc
+++ b/runtime/lib/string.cc
@@ -20,7 +20,7 @@
   GET_NATIVE_ARGUMENT(String, default_value, arguments->NativeArgAt(2));
   // Call the embedder to supply us with the environment.
   const String& env_value =
-      String::Handle(Api::CallEnvironmentCallback(isolate, name));
+      String::Handle(Api::CallEnvironmentCallback(thread, name));
   if (!env_value.IsNull()) {
     return Symbols::New(env_value);
   }
diff --git a/runtime/lib/timeline.cc b/runtime/lib/timeline.cc
index 32f5896..a26c847 100644
--- a/runtime/lib/timeline.cc
+++ b/runtime/lib/timeline.cc
@@ -14,8 +14,11 @@
 namespace dart {
 
 // Native implementations for the dart:developer library.
-DEFINE_NATIVE_ENTRY(Timeline_getTraceClock, 0) {
-  return Integer::New(OS::GetCurrentTraceMicros(), Heap::kNew, true);
+
+DEFINE_NATIVE_ENTRY(Timeline_getIsolateNum, 0) {
+  return Integer::New(static_cast<int64_t>(isolate->main_port()),
+                      Heap::kOld,
+                      true);
 }
 
 
@@ -28,6 +31,11 @@
 }
 
 
+DEFINE_NATIVE_ENTRY(Timeline_getTraceClock, 0) {
+  return Integer::New(OS::GetCurrentTraceMicros(), Heap::kNew, true);
+}
+
+
 DEFINE_NATIVE_ENTRY(Timeline_reportTaskEvent, 6) {
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, start, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, id, arguments->NativeArgAt(1));
@@ -46,11 +54,10 @@
     return Object::null();
   }
 
-
   int64_t pid = OS::ProcessId();
   int64_t tid = OSThread::ThreadIdToIntPtr(OSThread::GetCurrentThreadTraceId());
 
-  char* event = OS::SCreate(zone,
+  char* json = OS::SCreate(zone,
       "{\"name\":\"%s\",\"cat\":\"%s\",\"tid\":%" Pd64 ",\"pid\":%" Pd64 ","
       "\"ts\":%" Pd64 ",\"ph\":\"%s\",\"id\":%" Pd64 ", \"args\":%s}",
       name.ToCString(),
@@ -62,8 +69,14 @@
       id.AsInt64Value(),
       args.ToCString());
 
-  // event was allocated in the zone and will be copied by AppendDartEvent.
-  recorder->AppendDartEvent(isolate, event);
+  TimelineEvent* event = isolate->GetDartStream()->StartEvent();
+  if (event == NULL) {
+    // Stream was turned off.
+    return Object::null();
+  }
+  // json was allocated in the zone and a copy will be stored in event.
+  event->SerializedJSON(json);
+  event->Complete();
 
   return Object::null();
 }
@@ -90,7 +103,7 @@
   int64_t pid = OS::ProcessId();
   int64_t tid = OSThread::ThreadIdToIntPtr(OSThread::GetCurrentThreadTraceId());
 
-  char* event = OS::SCreate(zone,
+  char* json = OS::SCreate(zone,
       "{\"name\":\"%s\",\"cat\":\"%s\",\"tid\":%" Pd64 ",\"pid\":%" Pd64 ","
       "\"ts\":%" Pd64 ",\"ph\":\"X\",\"dur\":%" Pd64 ",\"args\":%s}",
       name.ToCString(),
@@ -101,8 +114,56 @@
       duration,
       args.ToCString());
 
-  // event was allocated in the zone and will be copied by AppendDartEvent.
-  recorder->AppendDartEvent(isolate, event);
+  TimelineEvent* event = isolate->GetDartStream()->StartEvent();
+  if (event == NULL) {
+    // Stream was turned off.
+    return Object::null();
+  }
+  // json was allocated in the zone and a copy will be stored in event.
+  event->SerializedJSON(json);
+  event->Complete();
+
+  return Object::null();
+}
+
+
+DEFINE_NATIVE_ENTRY(Timeline_reportInstantEvent, 4) {
+  GET_NON_NULL_NATIVE_ARGUMENT(Integer, start, arguments->NativeArgAt(0));
+  GET_NON_NULL_NATIVE_ARGUMENT(String, category, arguments->NativeArgAt(1));
+  GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(2));
+  GET_NON_NULL_NATIVE_ARGUMENT(String, args, arguments->NativeArgAt(3));
+
+  TimelineEventRecorder* recorder = Timeline::recorder();
+  if (recorder == NULL) {
+    return Object::null();
+  }
+
+  if (!isolate->GetDartStream()->Enabled()) {
+    // Dart stream is not enabled for this isolate, do nothing.
+    return Object::null();
+  }
+
+  int64_t pid = OS::ProcessId();
+  int64_t tid = OSThread::ThreadIdToIntPtr(OSThread::GetCurrentThreadTraceId());
+
+  char* json = OS::SCreate(zone,
+      "{\"name\":\"%s\",\"cat\":\"%s\",\"tid\":%" Pd64 ",\"pid\":%" Pd64 ","
+      "\"ts\":%" Pd64 ",\"ph\":\"I\",\"args\":%s}",
+      name.ToCString(),
+      category.ToCString(),
+      tid,
+      pid,
+      start.AsInt64Value(),
+      args.ToCString());
+
+  TimelineEvent* event = isolate->GetDartStream()->StartEvent();
+  if (event == NULL) {
+    // Stream was turned off.
+    return Object::null();
+  }
+  // json was allocated in the zone and a copy will be stored in event.
+  event->SerializedJSON(json);
+  event->Complete();
 
   return Object::null();
 }
diff --git a/runtime/lib/timeline.dart b/runtime/lib/timeline.dart
index 12b9278..3a336e2 100644
--- a/runtime/lib/timeline.dart
+++ b/runtime/lib/timeline.dart
@@ -8,6 +8,8 @@
 
 patch int _getNextAsyncId() native "Timeline_getNextAsyncId";
 
+patch int _getIsolateNum() native "Timeline_getIsolateNum";
+
 patch void _reportTaskEvent(
     int start,
     int taskId,
@@ -22,3 +24,9 @@
     String category,
     String name,
     String argumentsAsJson) native "Timeline_reportCompleteEvent";
+
+patch void _reportInstantEvent(
+    int start,
+    String category,
+    String name,
+    String argumentsAsJson) native "Timeline_reportInstantEvent";
diff --git a/runtime/lib/uri_patch.dart b/runtime/lib/uri_patch.dart
index 93abe0d..2664b9b 100644
--- a/runtime/lib/uri_patch.dart
+++ b/runtime/lib/uri_patch.dart
@@ -2,6 +2,8 @@
 // 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:convert" show ASCII;
+
 // VM implementation of Uri.
 typedef Uri _UriBaseClosure();
 
@@ -21,4 +23,51 @@
   /* patch */ static Uri get base => _uriBaseClosure();
 
   static bool get _isWindowsPlatform native "Uri_isWindowsPlatform";
+
+  /* patch */ static String _uriEncode(List<int> canonicalTable,
+                                       String text,
+                                       Encoding encoding,
+                                       bool spaceToPlus) {
+    // First check if the text will be changed by encoding.
+    int i = 0;
+    if (identical(encoding, UTF8) ||
+        identical(encoding, LATIN1) ||
+        identical(encoding, ASCII)) {
+      // Encoding is compatible with the original string.
+      // Find first character that needs encoding.
+      for (; i < text.length; i++) {
+        var char = text.codeUnitAt(i);
+        if (char >= 128 ||
+            canonicalTable[char >> 4] & (1 << (char & 0x0f)) == 0) {
+          break;
+        }
+      }
+    }
+    if (i == text.length) return text;
+
+    // Encode the string into bytes then generate an ASCII only string
+    // by percent encoding selected bytes.
+    StringBuffer result = new StringBuffer();
+    for (int j = 0; j < i; j++) {
+      result.writeCharCode(text.codeUnitAt(j));
+    }
+
+    // TODO(lrn): Is there a way to only encode from index i and forwards.
+    var bytes = encoding.encode(text);
+    for (; i < bytes.length; i++) {
+      int byte = bytes[i];
+      if (byte < 128 &&
+          ((canonicalTable[byte >> 4] & (1 << (byte & 0x0f))) != 0)) {
+        result.writeCharCode(byte);
+      } else if (spaceToPlus && byte == _SPACE) {
+        result.writeCharCode(_PLUS);
+      } else {
+        const String hexDigits = '0123456789ABCDEF';
+        result..writeCharCode(_PERCENT)
+              ..writeCharCode(hexDigits.codeUnitAt(byte >> 4))
+              ..writeCharCode(hexDigits.codeUnitAt(byte & 0x0f));
+      }
+    }
+    return result.toString();
+  }
 }
diff --git a/runtime/lib/vmservice.cc b/runtime/lib/vmservice.cc
index 9a2cb2a..12aadb6 100644
--- a/runtime/lib/vmservice.cc
+++ b/runtime/lib/vmservice.cc
@@ -63,8 +63,8 @@
     args.SetAt(0, port_int);
     args.SetAt(1, send_port);
     args.SetAt(2, name);
-    Object& r = Object::Handle(service_isolate_->current_zone());
-    r = DartEntry::InvokeFunction(register_function_, args);
+    const Object& r = Object::Handle(
+        DartEntry::InvokeFunction(register_function_, args));
     if (FLAG_trace_service) {
       OS::Print("vm-service: Isolate %s %" Pd64 " registered.\n",
                 name.ToCString(),
@@ -146,4 +146,9 @@
   return Object::null();
 }
 
+
+DEFINE_NATIVE_ENTRY(VMService_RequestAssets, 0) {
+  return Service::RequestAssets();
+}
+
 }  // namespace dart
diff --git a/runtime/lib/vmservice_patch.dart b/runtime/lib/vmservice_patch.dart
index e9b4da7..a885004 100644
--- a/runtime/lib/vmservice_patch.dart
+++ b/runtime/lib/vmservice_patch.dart
@@ -10,3 +10,4 @@
 patch void _onExit() native "VMService_OnExit";
 patch bool _vmListenStream(String streamId) native "VMService_ListenStream";
 patch void _vmCancelStream(String streamId) native "VMService_CancelStream";
+patch Uint8List _requestAssets() native "VMService_RequestAssets";
\ No newline at end of file
diff --git a/runtime/observatory/BUILD.gn b/runtime/observatory/BUILD.gn
new file mode 100644
index 0000000..a4a76ee
--- /dev/null
+++ b/runtime/observatory/BUILD.gn
@@ -0,0 +1,193 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Currently paths here are hard coded for convenience in building Mojo/Flutter.
+declare_args() {
+  # Specify the path to a host compatible version of the Dart SDK.
+  # This SDK is used to compile the Observatory frontend sources.
+  dart_host_sdk = rebase_path("//third_party/dart-sdk/dart-sdk")
+
+  # Specify the path to a host compatible version of pub.
+  # This is used to compile the Observatory frontend sources.
+  dart_host_pub_exe = rebase_path("$dart_host_sdk/bin/pub")
+}
+
+# Helper build rules for packaging the Dart observatory resources.
+observatory_sources_gypi =
+    exec_script("../../tools/gypi_to_gn.py",
+                [ rebase_path(
+                    "//dart/runtime/observatory/observatory_sources.gypi") ],
+                "scope",
+                [ "//dart/runtime/observatory/observatory_sources.gypi" ])
+
+copy("copy_observatory") {
+  sources = rebase_path(observatory_sources_gypi.sources,
+                        "",
+                        ".")
+  outputs = [
+    "$root_gen_dir/observatory_copy/{{source_root_relative_dir}}/{{source_file_part}}",
+  ]
+}
+
+action("write_observatory_pubspec_yaml") {
+  deps = [
+    ":copy_observatory",
+  ]
+
+  script = "../../tools/observatory_tool.py"
+
+  inputs = [
+    rebase_path("pubspec.yaml"),
+  ]
+
+  args = [
+    "--silent=True",
+    "--pub-executable",
+    dart_host_pub_exe,
+    "--directory",
+    rebase_path("$root_gen_dir/observatory_copy/dart/runtime/observatory/"),
+    "--command",
+    "rewrite",
+    rebase_path("//dart/runtime/observatory/pubspec.yaml"),
+    rebase_path(
+        "$root_gen_dir/observatory_copy/dart/runtime/observatory/pubspec.yaml"),
+    "../../third_party/",
+    rebase_path("../../../dart/third_party/"),
+  ]
+
+  outputs = [
+    "$root_gen_dir/observatory_copy/dart/runtime/observatory/pubspec.yaml",
+  ]
+}
+
+action("copy_observatory_deps") {
+  deps = [
+    ":write_observatory_pubspec_yaml",
+  ]
+
+  script = "//dart/tools/observatory_tool.py"
+
+  inputs = [
+    script,
+    "$root_gen_dir/observatory_copy/dart/runtime/observatory/pubspec.yaml",
+  ]
+
+  args = [
+    "--silent=True",
+    "--pub-executable",
+    dart_host_pub_exe,
+    "--directory",
+    rebase_path("$root_gen_dir/observatory_copy/dart/runtime/observatory/"),
+    "--command",
+    "get",
+  ]
+
+  outputs = [
+    "$root_gen_dir/observatory_copy/dart/runtime/observatory/pubspec.lock",
+  ]
+}
+
+action("pub_build_observatory") {
+  sources =
+      rebase_path(observatory_sources_gypi.sources,
+                  "",
+                  "$root_gen_dir/observatory_copy/dart/runtime/observatory")
+
+  deps = [
+    ":copy_observatory",
+    ":copy_observatory_deps",
+  ]
+
+  script = "//dart/tools/observatory_tool.py"
+
+  inputs = [
+    script,
+  ]
+  inputs += sources
+
+  args = [
+    "--silent=True",
+    "--pub-executable",
+    dart_host_pub_exe,
+    "--directory",
+    rebase_path("$root_gen_dir/observatory_copy/dart/runtime/observatory/"),
+    "--command",
+    "build",
+    rebase_path("$root_out_dir/observatory/build"),
+  ]
+
+  outputs = [
+    "$root_out_dir/observatory/build/web/index.html",
+    "$root_out_dir/observatory/build/web/index.html.polymer.bootstrap.dart.js",
+  ]
+}
+
+action("deploy_observatory") {
+  deps = [
+    ":pub_build_observatory",
+  ]
+
+  script = "//dart/tools/observatory_tool.py"
+
+  inputs = [
+    script,
+    "$root_out_dir/observatory/build/web/index.html",
+    "$root_out_dir/observatory/build/web/index.html.polymer.bootstrap.dart.js",
+  ]
+
+  args = [
+    "--silent=True",
+    "--pub-executable",
+    dart_host_pub_exe,
+    "--directory",
+    rebase_path("$root_out_dir/observatory"),
+    "--command",
+    "deploy",
+  ]
+
+  outputs = [
+    "$root_out_dir/observatory/deployed/web/index.html",
+    "$root_out_dir/observatory/deployed/web/index.html.polymer.bootstrap.dart.js",
+  ]
+}
+
+action("archive_observatory") {
+  deps = [
+    ":deploy_observatory",
+  ]
+
+  script = "//dart/runtime/tools/create_archive.py"
+
+  inputs = [
+    script,
+    "$root_out_dir/observatory/deployed/web/index.html",
+    "$root_out_dir/observatory/deployed/web/index.html.polymer.bootstrap.dart.js",
+  ]
+
+  args = [
+    "--output",
+    rebase_path("$root_gen_dir/observatory/observatory_archive.cc"),
+    "--tar_output",
+    rebase_path("$root_gen_dir/observatory/observatory_archive.tar"),
+    "--outer_namespace", "dart",
+    "--inner_namespace", "observatory",
+    "--name", "observatory_assets_archive",
+    "--client_root", rebase_path("$root_out_dir/observatory/deployed/web/"),
+  ]
+
+  outputs = [
+    "$root_gen_dir/observatory/observatory_archive.cc",
+    "$root_gen_dir/observatory/observatory_archive.tar",
+  ]
+}
+
+source_set("embedded_observatory_archive") {
+  deps = [
+    ":archive_observatory",
+  ]
+
+  sources = [
+    rebase_path("$root_gen_dir/observatory/observatory_archive.cc"),
+  ]
+}
diff --git a/runtime/observatory/README_android b/runtime/observatory/README_android
deleted file mode 100644
index 0372732..0000000
--- a/runtime/observatory/README_android
+++ /dev/null
@@ -1,20 +0,0 @@
-Running Observatory against content_shell:
-
-0) Open your mobile web application in Dart Editor and launch it on mobile.
-
-1) Forward localhost:9222 to the content_shell's remote debugging protocol:
-
-$ adb forward tcp:9222 localabstract:content_shell_devtools_remote
-
-2) Start the Observatory servers:
-
-$ ./run.sh
-
-By default Observatory will be available on localhost:9090
-
-3) Release the content_shell's remote debugging protocol by clicking the 'Stop'
-button in the Dart Editor's debugger. By releasing the debugging protocol,
-Observatory can communicate with the content_shell.
-
-4) On Observatory's connect to VM page you should see the name of your app 
-on the right hand side of the page.
diff --git a/runtime/observatory/bin/server.dart b/runtime/observatory/bin/server.dart
deleted file mode 100644
index 4df5a85..0000000
--- a/runtime/observatory/bin/server.dart
+++ /dev/null
@@ -1,159 +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 observatory_server;
-
-import 'dart:async';
-import 'dart:convert';
-import 'dart:io';
-
-import 'package:args/args.dart';
-import 'package:logging/logging.dart';
-
-final Logger logger = new Logger('ObsServe');
-
-class ObservatoryServer {
-  static const _CHROME_PREFIX = '/crdptargets/';
-
-  // Is logging enabled?
-  bool log;
-
-  // Host to listen on.
-  String host;
-  // Port to listen on.
-  int port;
-
-  // Host that pub is listening on.
-  String pubHost;
-  // Port that pub is listening on.
-  int pubPort;
-
-  HttpServer _server;
-  final HttpClient _client = new HttpClient();
-
-  ObservatoryServer(List<String> args) {
-    var parser = new ArgParser();
-    parser.addFlag('log', help: 'Log activity.', defaultsTo: true);
-    parser.addOption('port', help: 'Specify port listen on',
-                     defaultsTo: '9090');
-    parser.addOption('host',
-                     help: 'Specify host to listen on',
-                     defaultsTo: '127.0.0.1');
-    parser.addOption('pub-port', help: 'Specify port that pub is listening on',
-                     defaultsTo: '9191');
-    parser.addOption('pub-host', help: 'Specify host that pub is listening on',
-                     defaultsTo: '127.0.0.1');
-    var results = parser.parse(args);
-    host = results['host'];
-    port = int.parse(results['port']);
-    log = results['log'];
-    pubHost = results['pub-host'];
-    pubPort = int.parse(results['pub-port']);
-  }
-
-  List<Map> _makeTargetList(List<Map> tabs) {
-    var r = <Map>[];
-    tabs.forEach((tab) {
-      var uri = Uri.parse(tab['url']);
-      if (uri.host == 'devtools') {
-        // Ignore.
-        return;
-      }
-      var target = {
-        'lastConnectionTime': 0,
-        'chrome': true,
-        'name': tab['title'],
-        'networkAddress': tab['webSocketDebuggerUrl'],
-      };
-      r.add(target);
-    });
-    return r;
-  }
-
-  void _getChromeTabs(HttpRequest request) {
-    var path = request.uri.path;
-    var method = request.method;
-    if (method != 'GET') {
-      return;
-    }
-    assert(path.startsWith(_CHROME_PREFIX));
-    var networkAddress = path.substring(_CHROME_PREFIX.length);
-    if ((networkAddress == '') || (networkAddress == null)) {
-      request.response.write('[]');
-      request.response.close();
-      return;
-    }
-    networkAddress = Uri.decodeComponent(networkAddress);
-    var chunks = networkAddress.split(':');
-    var chromeAddress = chunks[0];
-    var chromePort =
-        (chunks[1] == null) || (chunks[1] == '') ? 9222 : int.parse(chunks[1]);
-    logger.info('tabs from $chromeAddress:$chromePort');
-    _client.open(method, chromeAddress, chromePort, 'json')
-        .then((HttpClientRequest pubRequest) {
-          // Calling .close() on an HttpClientRequest sends the request to the
-          // server. The future completes to an HttpClientResponse when the
-          // server has responded.
-          return pubRequest.close();
-        }).then((HttpClientResponse response) {
-          var respond = (contents) {
-            var tabs = JSON.decode(contents);
-            var targets = _makeTargetList(tabs);
-            request.response.write(JSON.encode(targets));
-            request.response.close().catchError((e) {
-              logger.severe('tabs from $chromeAddress:$chromePort failed');
-              logger.severe(e.toString());
-            });
-          };
-          response.transform(UTF8.decoder).listen(respond);
-        }).catchError((e) {
-          logger.severe('tabs from $chromeAddress:$chromePort failed');
-          logger.severe(e.toString());
-        });
-  }
-
-  /// Forward [request] to pub.
-  void _forwardToPub(HttpRequest request) {
-    var path = request.uri.path;
-    var method = request.method;
-    logger.info('pub $method $path');
-    _client.open(method, pubHost, pubPort, path)
-        .then((HttpClientRequest pubRequest) {
-          return pubRequest.close();
-        }).then((HttpClientResponse response) {
-          return request.response.addStream(response);
-        }).then((_) => request.response.close())
-        .catchError((e) {
-          logger.severe('pub $method $path failed.');
-          logger.severe(e.toString());
-        });
-  }
-
-  void _onHttpRequest(HttpRequest request) {
-    // Allow cross origin requests.
-    request.response.headers.add('Access-Control-Allow-Origin', '*');
-    if (request.uri.path.startsWith(_CHROME_PREFIX)) {
-      _getChromeTabs(request);
-    } else {
-      _forwardToPub(request);
-    }
-  }
-
-  /// Future completes to [this] on successful startup.
-  Future start() {
-    return HttpServer.bind(host,  port).then((s) {
-      _server = s;
-      _server.listen(_onHttpRequest);
-      print('ObsServe is running on ${_server.address}:${_server.port}');
-    });
-  }
-}
-
-main(List<String> args) {
-  hierarchicalLoggingEnabled = true;
-  logger.level = Level.ALL;
-  logger.onRecord.listen(print);
-  new ObservatoryServer(args)..start();
-}
-
diff --git a/runtime/observatory/lib/base64.dart b/runtime/observatory/lib/base64.dart
deleted file mode 100644
index 4bb0f70..0000000
--- a/runtime/observatory/lib/base64.dart
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library base64;
-
-import 'dart:typed_data';
-
-const _decodeTable =
-    const [null, null, null, null, null, null, null, null,
-           null, null, null, null, null, null, null, null,
-           null, null, null, null, null, null, null, null,
-           null, null, null, null, null, null, null, null,
-           null, null, null, null, null, null, null, null,
-           null, null, null, 62, null, null, null, 63,
-           52, 53, 54, 55, 56, 57, 58, 59,
-           60, 61, null, null, null, 0, null, null,
-           null, 0, 1, 2, 3, 4, 5, 6,
-           7, 8, 9, 10, 11, 12, 13, 14,
-           15, 16, 17, 18, 19, 20, 21, 22,
-           23, 24, 25, null, null, null, null, null,
-           null, 26, 27, 28, 29, 30, 31, 32,
-           33, 34, 35, 36, 37, 38, 39, 40,
-           41, 42, 43, 44, 45, 46, 47, 48,
-           49, 50, 51];
-
-Uint8List decodeBase64(String s) {
-  if (s.length % 4 != 0) throw "Malformed Base64: $s";
-
-  var odd_bits = 0;
-  if (s[s.length - 1] == '=') {
-    if (s[s.length - 2] == '=') {
-      odd_bits = 2;
-    } else {
-      odd_bits = 1;
-    }
-  }
-
-  var decodedByteLength = s.length ~/ 4 * 3 - odd_bits;
-  var result = new Uint8List(decodedByteLength);
-  var limit = s.length;
-  if (odd_bits != 0) {
-    limit = limit - 4;
-  }
-
-  var i = 0, j = 0;
-  while (i < limit) {
-    var triple = _decodeTable[s.codeUnitAt(i++)];
-    triple = (triple << 6) | _decodeTable[s.codeUnitAt(i++)];
-    triple = (triple << 6) | _decodeTable[s.codeUnitAt(i++)];
-    triple = (triple << 6) | _decodeTable[s.codeUnitAt(i++)];
-    result[j++] = triple >> 16;
-    result[j++] = (triple >> 8) & 255;
-    result[j++] = triple & 255;
-  }
-
-  if (odd_bits != 0) {
-    var triple = _decodeTable[s.codeUnitAt(i++)];
-    triple = (triple << 6) | _decodeTable[s.codeUnitAt(i++)];
-    triple = (triple << 6) | _decodeTable[s.codeUnitAt(i++)];
-    triple = (triple << 6) | _decodeTable[s.codeUnitAt(i++)];
-    result[j++] = triple >> 16;
-    if (odd_bits == 1) {
-      result[j++] = (triple >> 8) & 255;
-    }
-  }
-  assert(j == decodedByteLength);
-  return result;
-}
diff --git a/runtime/observatory/lib/elements.dart b/runtime/observatory/lib/elements.dart
index 51309f5..e485407 100644
--- a/runtime/observatory/lib/elements.dart
+++ b/runtime/observatory/lib/elements.dart
@@ -52,6 +52,7 @@
 export 'package:observatory/src/elements/service_ref.dart';
 export 'package:observatory/src/elements/service_view.dart';
 export 'package:observatory/src/elements/sliding_checkbox.dart';
+export 'package:observatory/src/elements/timeline_page.dart';
 export 'package:observatory/src/elements/view_footer.dart';
 export 'package:observatory/src/elements/vm_connect.dart';
 export 'package:observatory/src/elements/vm_ref.dart';
diff --git a/runtime/observatory/lib/elements.html b/runtime/observatory/lib/elements.html
index 87376f0..1f89cbd 100644
--- a/runtime/observatory/lib/elements.html
+++ b/runtime/observatory/lib/elements.html
@@ -44,6 +44,7 @@
 <link rel="import" href="src/elements/script_view.html">
 <link rel="import" href="src/elements/service_ref.html">
 <link rel="import" href="src/elements/sliding_checkbox.html">
+<link rel="import" href="src/elements/timeline_page.html">
 <link rel="import" href="src/elements/view_footer.html">
 <link rel="import" href="src/elements/vm_connect.html">
 <link rel="import" href="src/elements/vm_ref.html">
diff --git a/runtime/observatory/lib/object_graph.dart b/runtime/observatory/lib/object_graph.dart
index 2a5e2b7..e70570e 100644
--- a/runtime/observatory/lib/object_graph.dart
+++ b/runtime/observatory/lib/object_graph.dart
@@ -377,8 +377,8 @@
     _addrToId = null;
     _chunks = null;
 
-    statusReporter.add("Finding post order...");
-    await new Future(() => _buildPostOrder());
+    statusReporter.add("Finding depth-first order...");
+    await new Future(() => _dfs());
 
     statusReporter.add("Finding predecessors...");
     await new Future(() => _buildPredecessors());
@@ -388,12 +388,14 @@
 
     _firstPreds = null;
     _preds = null;
-    _postOrderIndices = null;
+
+    _semi = null;
+    _parent = null;
 
     statusReporter.add("Finding retained sizes...");
     await new Future(() => _calculateRetainedSizes());
 
-    _postOrderOrdinals = null;
+    _vertex = null;
 
     statusReporter.add("Loaded");
     return this;
@@ -417,8 +419,9 @@
 
   // Intermediates.
   AddressMapper _addrToId;
-  Uint32List _postOrderOrdinals; // post-order index -> id
-  Uint32List _postOrderIndices; // id -> post-order index
+  Uint32List _vertex;
+  Uint32List _parent;
+  Uint32List _semi;
   Uint32List _firstPreds; // Offset into preds.
   Uint32List _preds;
 
@@ -514,56 +517,70 @@
     _succs = succs;
   }
 
-  void _buildPostOrder() {
+  void _dfs() {
     var N = _N;
     var E = _E;
     var firstSuccs = _firstSuccs;
     var succs = _succs;
 
-    var postOrderOrdinals = new Uint32List(N);
-    var postOrderIndices = new Uint32List(N + 1);
     var stackNodes = new Uint32List(N);
     var stackCurrentEdgePos = new Uint32List(N);
 
-    var visited = new Uint8List(N + 1);
-    var postOrderIndex = 0;
+    var vertex = new Uint32List(N + 1);
+    var semi = new Uint32List(N + 1);
+    var parent = new Uint32List(N + 1);
+    var dfsNumber = 0;
+
+    var dfsCount = 0;
     var stackTop = 0;
     var root = 1;
 
+    // Push root.
     stackNodes[0] = root;
     stackCurrentEdgePos[0] = firstSuccs[root];
-    visited[root] = 1;
 
     while (stackTop >= 0) {
-      var n = stackNodes[stackTop];
+      var v = stackNodes[stackTop];
       var edgePos = stackCurrentEdgePos[stackTop];
 
-      if (edgePos < firstSuccs[n + 1]) {
+      if (semi[v] == 0) {
+        // First visit.
+        dfsNumber++;
+        semi[v] = dfsNumber;
+        vertex[dfsNumber] = v;
+      }
+
+      if (edgePos < firstSuccs[v + 1]) {
         var childId = succs[edgePos];
         edgePos++;
         stackCurrentEdgePos[stackTop] = edgePos;
-        if (visited[childId] == 1) continue;
 
-        // Push child.
-        stackTop++;
-        stackNodes[stackTop] = childId;
-        edgePos = firstSuccs[childId];
-        stackCurrentEdgePos[stackTop] = edgePos;
-        visited[childId] = 1;
+        if (semi[childId] == 0) {
+          parent[childId] = v;
+
+          // Push child.
+          stackTop++;
+          stackNodes[stackTop] = childId;
+          stackCurrentEdgePos[stackTop] = firstSuccs[childId];
+        }
       } else {
         // Done with all children.
-        postOrderIndices[n] = postOrderIndex;
-        postOrderOrdinals[postOrderIndex++] = n;
         stackTop--;
       }
     }
 
-    assert(postOrderIndex == N);
-    assert(postOrderOrdinals[N - 1] == root);
+    assert(dfsNumber == N);
+    for (var i = 1; i <= N; i++) {
+      assert(semi[i] != 0);
+    }
+    assert(parent[1] == 0);
+    for (var i = 2; i <= N; i++) {
+      assert(parent[i] != 0);
+    }
 
-    _postOrderOrdinals = postOrderOrdinals;
-    _postOrderIndices = postOrderIndices;
-    _E = E;
+    _vertex = vertex;
+    _semi = semi;
+    _parent = parent;
   }
 
   void _buildPredecessors() {
@@ -616,86 +633,166 @@
     _preds = preds;
   }
 
-  // "A Simple, Fast Dominance Algorithm"
-  // Keith D. Cooper, Timothy J. Harvey, and Ken Kennedy
+  static int _eval(int v,
+                   Uint32List ancestor,
+                   Uint32List semi,
+                   Uint32List label,
+                   Uint32List stackNode,
+                   Uint8List stackState) {
+    if (ancestor[v] == 0) {
+      return label[v];
+    } else {
+      {
+        // Inlined 'compress' with an explicit stack to prevent JS stack
+        // overflow.
+        var top = 0;
+        stackNode[top] = v;
+        stackState[top] = 0;
+        while (top >= 0) {
+          var v = stackNode[top];
+          var state = stackState[top];
+          if (state == 0) {
+            assert(ancestor[v] != 0);
+            if (ancestor[ancestor[v]] != 0) {
+              stackState[top] = 1;
+              // Recurse with ancestor[v]
+              top++;
+              stackNode[top] = ancestor[v];
+              stackState[top] = 0;
+            } else {
+              top--;
+            }
+          } else {
+            assert(state == 1);
+            if (semi[label[ancestor[v]]] < semi[label[v]]) {
+              label[v] = label[ancestor[v]];
+            }
+            ancestor[v] = ancestor[ancestor[v]];
+            top--;
+          }
+        }
+      }
+
+      if (semi[label[ancestor[v]]] >= semi[label[v]]) {
+        return label[v];
+      } else {
+        return label[ancestor[v]];
+      }
+    }
+  }
+
+  // Note the version in the main text of Lengauer & Tarjan incorrectly
+  // uses parent instead of ancestor. The correct version is in Appendix B.
+  static void _link(int v,
+                    int w,
+                    Uint32List size,
+                    Uint32List label,
+                    Uint32List semi,
+                    Uint32List child,
+                    Uint32List ancestor) {
+    assert(size[0] == 0);
+    assert(label[0] == 0);
+    assert(semi[0] == 0);
+    var s = w;
+    while (semi[label[w]] < semi[label[child[s]]]) {
+      if (size[s] + size[child[child[s]]] >= 2 * size[child[s]]) {
+        ancestor[child[s]] = s;
+        child[s] = child[child[s]];
+      } else {
+        size[child[s]] = size[s];
+        s = ancestor[s] = child[s];
+      }
+    }
+    label[s] = label[w];
+    size[v] = size[v] + size[w];
+    if (size[v] < 2 * size[w]) {
+      var tmp = s;
+      s = child[v];
+      child[v] = tmp;
+    }
+    while (s != 0) {
+      ancestor[s] = v;
+      s = child[s];
+    }
+  }
+
+  // T. Lengauer and R. E. Tarjan. "A Fast Algorithm for Finding Dominators
+  // in a Flowgraph."
   void _buildDominators() {
     var N = _N;
 
-    var postOrder = _postOrderOrdinals;
-    var postOrderIndex = _postOrderIndices;
+    var vertex = _vertex;
+    var semi = _semi;
+    var parent = _parent;
     var firstPreds = _firstPreds;
     var preds = _preds;
 
     var root = 1;
-    var rootPostOrderIndex = postOrderIndex[root];
-    var domByPOI = new Uint32List(N + 1);
+    var dom = new Uint32List(N + 1);
 
-    domByPOI[rootPostOrderIndex] = rootPostOrderIndex;
+    var ancestor = new Uint32List(N + 1);
+    var label = new Uint32List(N + 1);
+    for (var i = 1; i <= N; i++) {
+      label[i] = i;
+    }
+    var buckets = new List(N + 1);
+    var child = new Uint32List(N + 1);
+    var size = new Uint32List(N + 1);
+    for (var i = 1; i <= N; i++) {
+      size[i] = 1;
+    }
+    var stackNode = new Uint32List(N + 1);
+    var stackState = new Uint8List(N + 1);
 
-    var iteration = 0;
-    var changed = true;
-    while (changed) {
-      changed = false;
-      Logger.root.info("Find dominators iteration $iteration");
-      iteration++; // dart2js heaps typically converge in 10 iterations.
+    for (var i = N; i > 1; i--) {
+      var w = vertex[i];
+      assert(w != root);
 
-      // Visit the nodes, except the root, in reverse post order (top down).
-      for (var curPostOrderIndex = rootPostOrderIndex - 1;
-           curPostOrderIndex > 1;
-           curPostOrderIndex--) {
-        if (domByPOI[curPostOrderIndex] == rootPostOrderIndex)
-          continue;
-
-        var nodeOrdinal = postOrder[curPostOrderIndex];
-        var newDomIndex = 0; // 0 = undefined
-
-        // Intersect the DOM sets of the node's precedessors.
-        var beginPredIndex = firstPreds[nodeOrdinal];
-        var endPredIndex = firstPreds[nodeOrdinal + 1];
-        for (var predIndex = beginPredIndex;
-             predIndex < endPredIndex;
-             predIndex++) {
-          var predOrdinal = preds[predIndex];
-          var predPostOrderIndex = postOrderIndex[predOrdinal];
-          if (domByPOI[predPostOrderIndex] != 0) {
-            if (newDomIndex == 0) {
-              newDomIndex = predPostOrderIndex;
-            } else {
-              // Note this two finger algorithm to find the DOM intersection
-              // relies on comparing nodes by their post order index.
-              while (predPostOrderIndex != newDomIndex) {
-                while(predPostOrderIndex < newDomIndex)
-                  predPostOrderIndex = domByPOI[predPostOrderIndex];
-                while (newDomIndex < predPostOrderIndex)
-                  newDomIndex = domByPOI[newDomIndex];
-              }
-            }
-            if (newDomIndex == rootPostOrderIndex) {
-              break;
-            }
-          }
+      // Lengauer & Tarjan Step 2.
+      var startPred = firstPreds[w];
+      var limitPred = firstPreds[w + 1];
+      for (var predIndex = startPred;
+           predIndex < limitPred;
+           predIndex++) {
+        var v = preds[predIndex];
+        var u = _eval(v, ancestor, semi, label, stackNode, stackState);
+        if (semi[u] < semi[w]) {
+          semi[w] = semi[u];
         }
-        if (newDomIndex != 0 && domByPOI[curPostOrderIndex] != newDomIndex) {
-          domByPOI[curPostOrderIndex] = newDomIndex;
-          changed = true;
+      }
+
+      // w.semi.bucket.add(w);
+      var tmp = vertex[semi[w]];
+      if (buckets[tmp] == null) {
+        buckets[tmp] = new List();
+      }
+      buckets[tmp].add(w);
+
+      _link(parent[w], w, size, label, semi, child, ancestor);
+
+      // Lengauer & Tarjan Step 3.
+      tmp = parent[w];
+      var bucket = buckets[tmp];
+      buckets[tmp] = null;
+      if (bucket != null) {
+        for (var v in bucket) {
+          var u = _eval(v, ancestor, semi, label, stackNode, stackState);
+          dom[v] = semi[u] < semi[v] ? u : parent[w];
         }
       }
     }
-
-    Logger.root.info("Start remap dominators");
-
-    // Reindex doms by id instead of post order index so we can throw away
-    // the post order arrays.
-    var domById = new Uint32List(N + 1);
-    for (var id = 1; id <= N; id++) {
-      domById[id] = postOrder[domByPOI[postOrderIndex[id]]];
+    for (var i = 1; i <= N; i++) {
+      assert(buckets[i] == null);
+    }
+    // Lengauer & Tarjan Step 4.
+    for (var i = 2; i <= N; i++) {
+      var w = vertex[i];
+      if (dom[w] != vertex[semi[w]]) {
+        dom[w] = dom[dom[w]];
+      }
     }
 
-    Logger.root.info("End remap dominators");
-
-    domById[root] = 0;
-
-    _doms = domById;
+    _doms = dom;
   }
 
   void _calculateRetainedSizes() {
@@ -703,7 +800,7 @@
 
     var size = 0;
     var shallowSizes = _shallowSizes;
-    var postOrderOrdinals = _postOrderOrdinals;
+    var vertex = _vertex;
     var doms = _doms;
 
     // Sum shallow sizes.
@@ -716,9 +813,9 @@
 
     // In post order (bottom up), add retained size to dominator's retained
     // size, skipping root.
-    for (var o = 0; o < (N - 1); o++) {
-      var i = postOrderOrdinals[o];
-      assert(i != 1);
+    for (var i = N; i > 1; i--) {
+      var v = vertex[i];
+      assert(v != 1);
       retainedSizes[doms[i]] += retainedSizes[i];
     }
 
diff --git a/runtime/observatory/lib/service.dart b/runtime/observatory/lib/service.dart
index d72af88..cb6f317 100644
--- a/runtime/observatory/lib/service.dart
+++ b/runtime/observatory/lib/service.dart
@@ -13,7 +13,6 @@
 import 'package:observatory/cpu_profile.dart';
 import 'package:observatory/object_graph.dart';
 import 'package:observatory/tracer.dart';
-import 'package:observatory/base64.dart';
 import 'package:observe/observe.dart';
 
 part 'src/service/object.dart';
diff --git a/runtime/observatory/lib/src/app/application.dart b/runtime/observatory/lib/src/app/application.dart
index c4050e5..bda98c0 100644
--- a/runtime/observatory/lib/src/app/application.dart
+++ b/runtime/observatory/lib/src/app/application.dart
@@ -141,6 +141,7 @@
     _pageRegistry.add(new MetricsPage(this));
     _pageRegistry.add(new PortsPage(this));
     _pageRegistry.add(new LoggingPage(this));
+    _pageRegistry.add(new TimelinePage(this));
     // Note that ErrorPage must be the last entry in the list as it is
     // the catch all.
     _pageRegistry.add(new ErrorPage(this));
diff --git a/runtime/observatory/lib/src/app/page.dart b/runtime/observatory/lib/src/app/page.dart
index bc2bb43..21305e1 100644
--- a/runtime/observatory/lib/src/app/page.dart
+++ b/runtime/observatory/lib/src/app/page.dart
@@ -425,3 +425,21 @@
 
   bool canVisit(Uri uri) => uri.path == 'metrics';
 }
+
+class TimelinePage extends Page {
+  TimelinePage(app) : super(app);
+
+  void onInstall() {
+    if (element == null) {
+      element = new Element.tag('timeline-page');
+    }
+    assert(element != null);
+  }
+
+  void _visit(Uri uri) {
+    assert(element != null);
+    assert(canVisit(uri));
+  }
+
+  bool canVisit(Uri uri) => uri.path == 'timeline';
+}
diff --git a/runtime/observatory/lib/src/cpu_profile/cpu_profile.dart b/runtime/observatory/lib/src/cpu_profile/cpu_profile.dart
index c71a41e..d3e0252 100644
--- a/runtime/observatory/lib/src/cpu_profile/cpu_profile.dart
+++ b/runtime/observatory/lib/src/cpu_profile/cpu_profile.dart
@@ -370,15 +370,22 @@
 
     code.profile = this;
 
-    if (code.isDartCode) {
+    if (code.kind == CodeKind.Stub) {
+      attributes.add('stub');
+    } else if (code.kind == CodeKind.Dart) {
+      if (code.isNative) {
+        attributes.add('ffi');  // Not to be confused with a C function.
+      } else {
+        attributes.add('dart');
+      }
+      if (code.hasIntrinsic) {
+        attributes.add('intrinsic');
+      }
       if (code.isOptimized) {
         attributes.add('optimized');
       } else {
         attributes.add('unoptimized');
       }
-    }
-    if (code.isDartCode) {
-      attributes.add('dart');
     } else if (code.kind == CodeKind.Tag) {
       attributes.add('tag');
     } else if (code.kind == CodeKind.Native) {
@@ -516,15 +523,19 @@
     if (function.kind == FunctionKind.kTag) {
       attribs.add('tag');
     } else if (function.kind == FunctionKind.kStub) {
-      attribs.add('dart');
       attribs.add('stub');
     } else if (function.kind == FunctionKind.kNative) {
       attribs.add('native');
     } else if (function.kind.isSynthetic()) {
       attribs.add('synthetic');
+    } else if (function.isNative) {
+      attribs.add('ffi');  // Not to be confused with a C function.
     } else {
       attribs.add('dart');
     }
+    if (function.hasIntrinsic == true) {
+      attribs.add('intrinsic');
+    }
   }
 
   ProfileFunction.fromMap(this.profile, this.function, Map data) {
diff --git a/runtime/observatory/lib/src/debugger/debugger_location.dart b/runtime/observatory/lib/src/debugger/debugger_location.dart
index 31facf2..caf5f57 100644
--- a/runtime/observatory/lib/src/debugger/debugger_location.dart
+++ b/runtime/observatory/lib/src/debugger/debugger_location.dart
@@ -97,7 +97,8 @@
         return new DebuggerLocation.file(scripts[0], line, col);
       } else {
         // TODO(turnidge): Allow the user to disambiguate.
-        return new DebuggerLocation.error("Script '${scriptName}' is ambigous");
+        return
+            new DebuggerLocation.error("Script '${scriptName}' is ambiguous");
       }
     } else {
       // No script provided.  Default to top of stack for now.
@@ -253,7 +254,7 @@
       } else {
         // TODO(turnidge): Allow the user to disambiguate.
         return new DebuggerLocation.error(
-            "Function '${match.group(0)}' is ambigous");
+            "Function '${match.group(0)}' is ambiguous");
       }
       return new DebuggerLocation.error('foo');
     });
diff --git a/runtime/observatory/lib/src/elements/code_view.dart b/runtime/observatory/lib/src/elements/code_view.dart
index 7c6ddef..9234164 100644
--- a/runtime/observatory/lib/src/elements/code_view.dart
+++ b/runtime/observatory/lib/src/elements/code_view.dart
@@ -7,6 +7,7 @@
 import 'dart:async';
 import 'dart:html';
 import 'observatory_element.dart';
+import 'service_ref.dart';
 import 'package:observatory/app.dart';
 import 'package:observatory/service.dart';
 import 'package:observatory/cpu_profile.dart';
@@ -34,6 +35,7 @@
         new SortedTableColumn('Inclusive'),
         new SortedTableColumn('Exclusive'),
         new SortedTableColumn('Disassembly'),
+        new SortedTableColumn('Objects'),
     ];
     disassemblyTable = new DisassemblyTable(columns);
     columns = [
@@ -171,7 +173,8 @@
       var row = [formattedAddress(instruction),
                  formattedInclusive(instruction),
                  formattedExclusive(instruction),
-                 instruction.human];
+                 instruction.human,
+                 instruction.object];
       disassemblyTable.addRow(new SortedTableRow(row));
     }
   }
@@ -192,6 +195,8 @@
     cell.classes.add('monospace');
     cell = tr.insertCell(-1);
     cell.classes.add('monospace');
+    cell = tr.insertCell(-1);
+    cell.classes.add('monospace');
 
     tableBody.children.add(tr);
   }
@@ -201,8 +206,14 @@
     final n = row.values.length;
     for (var i = 0; i < n; i++) {
       final cell = tr.children[i];
-      cell.title = row.values[i].toString();
-      cell.text = row.values[i].toString();
+      final content = row.values[i];
+      if (content is ServiceObject) {
+        ServiceRefElement element = new Element.tag('any-service-ref');
+        element.ref = content;
+        cell.append(element);
+      } else if (content != null) {
+        cell.text = content.toString();
+      }
     }
   }
 
@@ -294,7 +305,6 @@
 
     for (var i = addressRangeColumn + 1; i < columns - 1; i++) {
       var cell = tr.children[i];
-      cell.title = row.values[i].toString();
       cell.text = row.values[i].toString();
     }
     var functions = row.values[functionsColumn];
diff --git a/runtime/observatory/lib/src/elements/code_view.html b/runtime/observatory/lib/src/elements/code_view.html
index 7b1c057..ba4cac0 100644
--- a/runtime/observatory/lib/src/elements/code_view.html
+++ b/runtime/observatory/lib/src/elements/code_view.html
@@ -20,19 +20,25 @@
       }
 
       th:nth-of-type(2), td:nth-of-type(2) {
-        min-width: 10em;
+        min-width: 8em;
         text-align: left;
       }
 
       th:nth-of-type(3), td:nth-of-type(3) {
-        padding-right: 3em;
+        min-width: 8em;
+        text-align: left;
       }
 
       th:nth-of-type(4), td:nth-of-type(4) {
-        padding-left: 3em;
+        text-align: left;
         overflow: visible;
         white-space: pre;
-        display: block;
+        padding-right: 1em;
+      }
+
+      th:nth-of-type(5), td:nth-of-type(5) {
+        text-align: left;
+        overflow: visible;
       }
 
       tr:hover > td {
@@ -86,7 +92,7 @@
           <div class="memberValue">{{ code.profile.formattedExclusiveTicks }}</div>
         </div>
         <div class="memberItem">
-          <div class="memberName">Constant object pool</div>
+          <div class="memberName">Object pool</div>
           <div class="memberValue">
             <any-service-ref ref="{{ code.objectPool }}"></any-service-ref>
           </div>
@@ -116,10 +122,10 @@
       <table id="inlineRangeTable" class="table">
         <thead id="inlineRangeTableHead">
           <tr>
-            <th class="address" title="Address range">Address Range</th>
-            <th class="tick" title="Inclusive">Inclusive</th>
-            <th class="tick" title="Exclusive">Exclusive</th>
-            <th title="Functions">Functions</th>
+            <th class="address">Address Range</th>
+            <th class="tick">Inclusive</th>
+            <th class="tick">Exclusive</th>
+            <th>Functions</th>
           </tr>
         </thead>
         <tbody class="monospace" id="inlineRangeTableBody">
@@ -129,10 +135,11 @@
       <table id="disassemblyTable" class="table">
         <thead id="disassemblyTableHead">
           <tr>
-            <th class="address" title="Address">Address</th>
-            <th class="tick" title="Inclusive">Inclusive</th>
-            <th class="tick" title="Exclusive">Exclusive</th>
-            <th class="disassembly" title="Disassembly">Disassembly</th>
+            <th class="address">Address</th>
+            <th class="tick" title="Ticks with PC on the stack">Inclusive</th>
+            <th class="tick" title="Ticks with PC at top of stack">Exclusive</th>
+            <th class="disassembly">Disassembly</th>
+            <th class="object">Object</th>
           </tr>
         </thead>
         <tbody class="monospace" id="disassemblyTableBody">
diff --git a/runtime/observatory/lib/src/elements/cpu_profile.dart b/runtime/observatory/lib/src/elements/cpu_profile.dart
index 087daa5..c026d7c 100644
--- a/runtime/observatory/lib/src/elements/cpu_profile.dart
+++ b/runtime/observatory/lib/src/elements/cpu_profile.dart
@@ -76,6 +76,8 @@
     'optimized' : const ['O', null, 'Optimized'],
     'unoptimized' : const ['U', null, 'Unoptimized'],
     'inlined' : const ['I', null, 'Inlined'],
+    'intrinsic' : const ['It', null, 'Intrinsic'],
+    'ffi' : const ['F', null, 'FFI'],
     'dart' : const ['D', null, 'Dart'],
     'tag' : const ['T', null, 'Tag'],
     'native' : const ['N', null, 'Native'],
diff --git a/runtime/observatory/lib/src/elements/debugger.dart b/runtime/observatory/lib/src/elements/debugger.dart
index 4310075..f464581 100644
--- a/runtime/observatory/lib/src/elements/debugger.dart
+++ b/runtime/observatory/lib/src/elements/debugger.dart
@@ -1724,7 +1724,7 @@
         // Unambiguous completion.
         return completions[0];
       } else {
-        // Ambigous completion.
+        // Ambiguous completion.
         completions = completions.map((s) => s.trimRight()).toList();
         console.printBold(completions.toString());
         return _foldCompletions(completions);
@@ -1914,6 +1914,7 @@
       // TODO(turnidge): How do we want to handle this in general?
       _stdoutSubscriptionFuture.catchError((e, st) {
         Logger.root.info('Failed to subscribe to stdout: $e\n$st\n');
+        _stdoutSubscriptionFuture = null;
       });
     }
     _stderrSubscriptionFuture =
@@ -1922,6 +1923,7 @@
       // TODO(turnidge): How do we want to handle this in general?
       _stderrSubscriptionFuture.catchError((e, st) {
         Logger.root.info('Failed to subscribe to stderr: $e\n$st\n');
+        _stderrSubscriptionFuture = null;
       });
     }
     _logSubscriptionFuture =
diff --git a/runtime/observatory/lib/src/elements/function_view.html b/runtime/observatory/lib/src/elements/function_view.html
index 2119fa8..57e2c8c 100644
--- a/runtime/observatory/lib/src/elements/function_view.html
+++ b/runtime/observatory/lib/src/elements/function_view.html
@@ -46,6 +46,14 @@
             <any-service-ref ref="{{ function.dartOwner }}"></any-service-ref>
           </div>
         </div>
+        <template if="{{ function.field != null }}">
+          <div class="memberItem">
+            <div class="memberName">field</div>
+            <div class="memberValue">
+              <any-service-ref ref="{{ function.field }}"></any-service-ref>
+            </div>
+          </div>
+        </template>
         <div class="memberItem">
           <div class="memberName">script</div>
           <div class="memberValue">
@@ -94,6 +102,18 @@
            <div class="memberName">inlinable</div>
            <div class="memberValue">{{ function.isInlinable }}</div>
          </div>
+         <div class="memberItem">
+           <div class="memberName">intrinsic</div>
+           <div class="memberValue">{{ function.hasIntrinsic }}</div>
+         </div>
+         <div class="memberItem">
+           <div class="memberName">recognized</div>
+           <div class="memberValue">{{ function.isRecognized }}</div>
+         </div>
+         <div class="memberItem">
+           <div class="memberName">native</div>
+           <div class="memberValue">{{ function.isNative }}</div>
+         </div>
          <template if="{{ function.name != function.vmName }}">
            <div class="memberItem">
              <div class="memberName">vm name</div>
diff --git a/runtime/observatory/lib/src/elements/megamorphiccache_view.html b/runtime/observatory/lib/src/elements/megamorphiccache_view.html
index db073e6..0454e0d 100644
--- a/runtime/observatory/lib/src/elements/megamorphiccache_view.html
+++ b/runtime/observatory/lib/src/elements/megamorphiccache_view.html
@@ -28,6 +28,18 @@
 
       <div class="memberList">
         <div class="memberItem">
+          <div class="memberName">selector</div>
+          <div class="memberValue">
+            {{ megamorphicCache.selector }}
+          </div>
+        </div>
+        <div class="memberItem">
+          <div class="memberName">argumentsDescriptor</div>
+          <div class="memberValue">
+            <any-service-ref ref="{{ megamorphicCache.argumentsDescriptor }}"></any-service-ref>
+          </div>
+        </div>
+        <div class="memberItem">
           <div class="memberName">mask</div>
           <div class="memberValue"> 
             {{ megamorphicCache.mask }}
diff --git a/runtime/observatory/lib/src/elements/script_inset.dart b/runtime/observatory/lib/src/elements/script_inset.dart
index 92930a9..9988ec9 100644
--- a/runtime/observatory/lib/src/elements/script_inset.dart
+++ b/runtime/observatory/lib/src/elements/script_inset.dart
@@ -663,12 +663,24 @@
   }
 
   Library resolveDependency(String relativeUri) {
+    // This isn't really correct: we need to ask the embedder to do the
+    // uri canonicalization for us, but Observatory isn't in a position
+    // to invoke the library tag handler. Handle the most common cases.
     var targetUri = Uri.parse(script.library.uri).resolve(relativeUri);
     for (Library l in script.isolate.libraries) {
       if (targetUri.toString() == l.uri) {
         return l;
       }
     }
+    if (targetUri.scheme == 'package') {
+      targetUri = "packages/${targetUri.path}";
+      for (Library l in script.isolate.libraries) {
+        if (targetUri.toString() == l.uri) {
+          return l;
+        }
+      }
+    }
+
     Logger.root.info("Could not resolve library dependency: $relativeUri");
     return null;
   }
@@ -824,6 +836,11 @@
       return table;
     }
 
+    var endLine = (endPos != null
+                   ? script.tokenToLine(endPos)
+                   : script.lines.length + script.lineOffset);
+    var lineNumPad = endLine.toString().length;
+
     annotationsCursor = 0;
 
     int blankLineCount = 0;
@@ -840,17 +857,17 @@
           if (blankLineCount < 4) {
             // Too few blank lines for an elipsis.
             for (int j = firstBlank; j  <= lastBlank; j++) {
-              table.append(lineElement(script.getLine(j)));
+              table.append(lineElement(script.getLine(j), lineNumPad));
             }
           } else {
             // Add an elipsis for the skipped region.
-            table.append(lineElement(script.getLine(firstBlank)));
-            table.append(lineElement(null));
-            table.append(lineElement(script.getLine(lastBlank)));
+            table.append(lineElement(script.getLine(firstBlank), lineNumPad));
+            table.append(lineElement(null, lineNumPad));
+            table.append(lineElement(script.getLine(lastBlank), lineNumPad));
           }
           blankLineCount = 0;
         }
-        table.append(lineElement(line));
+        table.append(lineElement(line, lineNumPad));
       }
     }
 
@@ -876,11 +893,11 @@
     return annotation;
   }
 
-  Element lineElement(ScriptLine line) {
+  Element lineElement(ScriptLine line, int lineNumPad) {
     var e = new DivElement();
     e.classes.add("sourceRow");
     e.append(lineBreakpointElement(line));
-    e.append(lineNumberElement(line));
+    e.append(lineNumberElement(line, lineNumPad));
     e.append(lineSourceElement(line));
     return e;
   }
@@ -952,9 +969,9 @@
     return e;
   }
 
-  Element lineNumberElement(ScriptLine line) {
+  Element lineNumberElement(ScriptLine line, int lineNumPad) {
     var lineNumber = line == null ? "..." : line.line;
-    var e = span("$nbsp$lineNumber$nbsp");
+    var e = span("$nbsp${lineNumber.toString().padLeft(lineNumPad,nbsp)}$nbsp");
     e.classes.add('noCopy');
 
     if (lineNumber == _currentLine) {
diff --git a/runtime/observatory/lib/src/elements/service_ref.dart b/runtime/observatory/lib/src/elements/service_ref.dart
index d823b86..9798795 100644
--- a/runtime/observatory/lib/src/elements/service_ref.dart
+++ b/runtime/observatory/lib/src/elements/service_ref.dart
@@ -56,6 +56,24 @@
   bool get nameIsEmpty {
     return (name == null) || name.isEmpty;
   }
+
+
+  @published bool expanded = false;
+  dynamic expander() {
+    return expandEvent;
+  }
+  void expandEvent(bool expand, Function onDone) {
+    if (expand) {
+      ref.reload().then((result) {
+        ref = result;
+        notifyPropertyChange(#ref, 0, 1);
+        expanded = true;
+      }).whenComplete(onDone);
+    } else {
+      expanded = false;
+      onDone();
+    }
+  }
 }
 
 
diff --git a/runtime/observatory/lib/src/elements/service_ref.html b/runtime/observatory/lib/src/elements/service_ref.html
index 839b4c5..17ce4c5 100644
--- a/runtime/observatory/lib/src/elements/service_ref.html
+++ b/runtime/observatory/lib/src/elements/service_ref.html
@@ -14,8 +14,31 @@
       <a on-click="{{ goto }}" _href="{{ url }}">
         <em>{{ ref.vmType }}</em> ({{ ref.length }})
       </a>
+      <curly-block callback="{{ expander() }}" expandKey="{{ expandKey }}">
+        <template if="{{ expanded }}">
+        <div class="indented">
+          <template repeat="{{ entry in ref.entries }}">
+            <div class="memberItem">
+              <div class="memberName">[PP+0x{{ entry['offset'].toRadixString(16) }}]</div>
+              <div class="memberValue">
+                <template if="{{ entry['kind'] == 'Object' }}">
+                  <any-service-ref ref="{{ entry['value'] }}">
+                  </any-service-ref>
+                </template>
+                <template if="{{ entry['kind'] == 'Immediate' }}">
+                  Immediate 0x{{ entry['value'].toRadixString(16) }}
+                </template>
+                <template if="{{ entry['kind'] == 'NativeEntry' }}">
+                  NativeEntry 0x{{ entry['value'].toRadixString(16) }}
+                </template>
+              </div>
+            </div>
+          </template>
+        </div>
+        </template>
+      </curly-block>
     </template>
-    <template if="{{ ref.isICData }}">
+    <template if="{{ ref.isICData || ref.isMegamorphicCache }}">
       <a on-click="{{ goto }}" _href="{{ url }}">
         <em>{{ ref.vmType }}</em> ({{ ref.selector }})
       </a>
@@ -25,7 +48,7 @@
         <em>{{ ref.vmType }}</em> ({{ ref.code.name }})
       </a>
     </template>
-    <template if="{{ !(ref.isObjectPool || ref.isICData || ref.isInstructions) }}">
+    <template if="{{ !(ref.isObjectPool || ref.isICData || ref.isMegamorphicCache || ref.isInstructions) }}">
       <template if="{{ nameIsEmpty }}">
         <a on-click="{{ goto }}" _href="{{ url }}"><em>{{ ref.vmType }}</em></a>
       </template>
diff --git a/runtime/observatory/lib/src/elements/timeline_page.dart b/runtime/observatory/lib/src/elements/timeline_page.dart
new file mode 100644
index 0000000..2d7049f
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/timeline_page.dart
@@ -0,0 +1,78 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library timeline_page_element;
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:html';
+import 'observatory_element.dart';
+import 'package:observatory/app.dart';
+import 'package:observatory/service_html.dart';
+import 'package:polymer/polymer.dart';
+
+
+@CustomTag('timeline-page')
+class TimelinePageElement extends ObservatoryElement {
+  TimelinePageElement.created() : super.created();
+
+  attached() {
+    super.attached();
+    _resizeSubscription = window.onResize.listen((_) => _updateSize());
+    _updateSize();
+  }
+
+  detached() {
+    super.detached();
+    if (_resizeSubscription != null) {
+      _resizeSubscription.cancel();
+    }
+  }
+
+  Future postMessage(String method) {
+    IFrameElement e = $['root'];
+    var message = {
+      'method': method,
+      'params': {
+        'vmAddress': (app.vm as WebSocketVM).target.networkAddress
+      }
+    };
+    e.contentWindow.postMessage(JSON.encode(message), window.location.href);
+    return null;
+  }
+
+  Future refresh() async {
+    return postMessage('refresh');
+  }
+
+  Future clear() async {
+    await app.vm.invokeRpc('_clearVMTimeline', {});
+    return postMessage('clear');
+  }
+
+  Future recordOn() async {
+    return app.vm.invokeRpc('_setVMTimelineFlag', {
+      '_record': 'all',
+    });
+  }
+
+  Future recordOff() async {
+    return app.vm.invokeRpc('_setVMTimelineFlag', {
+      '_record': 'none',
+    });
+  }
+
+  _updateSize() {
+    IFrameElement e = $['root'];
+    final totalHeight = window.innerHeight;
+    final top = e.offset.top;
+    final bottomMargin = 32;
+    final mainHeight = totalHeight - top - bottomMargin;
+    e.style.setProperty('height', '${mainHeight}px');
+    e.style.setProperty('width', '100%');
+  }
+
+
+  StreamSubscription _resizeSubscription;
+}
diff --git a/runtime/observatory/lib/src/elements/timeline_page.html b/runtime/observatory/lib/src/elements/timeline_page.html
new file mode 100644
index 0000000..95764ea
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/timeline_page.html
@@ -0,0 +1,21 @@
+<link rel="import" href="../../../../packages/polymer/polymer.html">
+<link rel="import" href="nav_bar.html">
+<link rel="import" href="observatory_element.html">
+
+<polymer-element name="timeline-page" extends="observatory-element">
+	<template>
+		<link rel="stylesheet" href="css/shared.css">
+		<style>
+		</style>
+		<nav-bar>
+			<top-nav-menu></top-nav-menu>
+			<nav-menu link="{{ makeLink('/timeline') }}" anchor="timeline" last="{{ true }}"></nav-menu>
+			<nav-refresh callback="{{ refresh }}"></nav-refresh>
+			<nav-refresh callback="{{ clear }}" label="Clear"></nav-refresh>
+			<nav-refresh callback="{{ recordOn }}" label="Start recording"></nav-refresh>
+			<nav-refresh callback="{{ recordOff }}" label="Stop recording"></nav-refresh>
+		</nav-bar>
+		<iframe id="root" frameborder="0" src="../../../../timeline.html"></iframe>
+	</template>
+</polymer-element>
+<script type="application/dart" src="timeline_page.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/vm_view.html b/runtime/observatory/lib/src/elements/vm_view.html
index 55fc712..2934009 100644
--- a/runtime/observatory/lib/src/elements/vm_view.html
+++ b/runtime/observatory/lib/src/elements/vm_view.html
@@ -56,6 +56,9 @@
           <div class="memberValue">
             See <a on-click="{{ goto }}" _href="{{ gotoLink('/flags') }}">flags</a>
           </div>
+          <div class="memberValue">
+            View <a on-click="{{ goto }}" _href="{{ gotoLink('/timeline') }}">timeline</a>
+          </div>
         </div>
       </div>
       <br>
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index acb3edf..f7775c1 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -114,6 +114,7 @@
   String _vmType;
 
   bool get isICData => vmType == 'ICData';
+  bool get isMegamorphicCache => vmType == 'MegamorphicCache';
   bool get isInstructions => vmType == 'Instructions';
   bool get isObjectPool => vmType == 'ObjectPool';
   bool get isContext => type == 'Context';
@@ -828,10 +829,14 @@
     if (!loaded) {
       // The vm service relies on these events to keep the VM and
       // Isolate types up to date.
-      await listenEventStream(kVMStream, _dispatchEventToIsolate);
-      await listenEventStream(kIsolateStream, _dispatchEventToIsolate);
-      await listenEventStream(kDebugStream, _dispatchEventToIsolate);
-      await listenEventStream(_kGraphStream, _dispatchEventToIsolate);
+      try {
+        await listenEventStream(kVMStream, _dispatchEventToIsolate);
+        await listenEventStream(kIsolateStream, _dispatchEventToIsolate);
+        await listenEventStream(kDebugStream, _dispatchEventToIsolate);
+        await listenEventStream(_kGraphStream, _dispatchEventToIsolate);
+      } on FakeVMRpcException catch (_) {
+        // ignore FakeVMRpcExceptions here.
+      }
     }
     return await invokeRpcNoUpgrade('getVM', {});
   }
@@ -1966,7 +1971,7 @@
       exceptions = map['_debuggerSettings']['_exceptions'];
     }
     if (map['bytes'] != null) {
-      var bytes = decodeBase64(map['bytes']);
+      var bytes = BASE64.decode(map['bytes']);
       bytesAsString = UTF8.decode(bytes);
     }
     if (map['logRecord'] != null) {
@@ -2408,7 +2413,7 @@
     elements = map['elements'];
     associations = map['associations'];
     if (map['bytes'] != null) {
-      var bytes = decodeBase64(map['bytes']);
+      var bytes = BASE64.decode(map['bytes']);
       switch (map['kind']) {
         case "Uint8ClampedList":
           typedElements = bytes.buffer.asUint8ClampedList(); break;
@@ -2563,6 +2568,9 @@
   @observable Code unoptimizedCode;
   @observable bool isOptimizable;
   @observable bool isInlinable;
+  @observable bool hasIntrinsic;
+  @observable bool isRecognized;
+  @observable bool isNative;
   @observable FunctionKind kind;
   @observable int deoptimizations;
   @observable String qualifiedName;
@@ -2570,6 +2578,7 @@
   @observable bool isDart;
   @observable ProfileFunction profile;
   @observable Instance icDataArray;
+  @observable Field field;
 
   bool get canCache => true;
   bool get immutable => false;
@@ -2602,6 +2611,9 @@
       qualifiedName = name;
     }
 
+    hasIntrinsic = map['_intrinsic'];
+    isNative = map['_native'];
+
     if (mapIsRef) {
       return;
     }
@@ -2613,10 +2625,12 @@
     code = map['code'];
     isOptimizable = map['_optimizable'];
     isInlinable = map['_inlinable'];
+    isRecognized = map['_recognized'];
     unoptimizedCode = map['_unoptimizedCode'];
     deoptimizations = map['_deoptimizations'];
     usageCounter = map['_usageCounter'];
     icDataArray = map['_icDataArray'];
+    field = map['_field'];
   }
 }
 
@@ -3338,6 +3352,8 @@
 class MegamorphicCache extends HeapObject {
   @observable int mask;
   @observable Instance buckets;
+  @observable String selector;
+  @observable Instance argumentsDescriptor;
 
   bool get canCache => false;
   bool get immutable => false;
@@ -3348,12 +3364,14 @@
     _upgradeCollection(map, isolate);
     super._update(map, mapIsRef);
 
+    selector = map['_selector'];
     if (mapIsRef) {
       return;
     }
 
     mask = map['_mask'];
     buckets = map['_buckets'];
+    argumentsDescriptor = map['_argumentsDescriptor'];
   }
 }
 
@@ -3402,11 +3420,16 @@
   @observable final int pcOffset;
   @observable final String machine;
   @observable final String human;
+  @observable final ServiceObject object;
   @observable CodeInstruction jumpTarget;
   @reflectable List<PcDescriptor> descriptors =
       new ObservableList<PcDescriptor>();
 
-  CodeInstruction(this.address, this.pcOffset, this.machine, this.human);
+  CodeInstruction(this.address,
+                  this.pcOffset,
+                  this.machine,
+                  this.human,
+                  this.object);
 
   @reflectable bool get isComment => address == 0;
   @reflectable bool get hasDescriptors => descriptors.length > 0;
@@ -3497,7 +3520,10 @@
   @observable ServiceObject objectPool;
   @observable ServiceFunction function;
   @observable Script script;
-  @observable bool isOptimized = false;
+  @observable bool isOptimized;
+  @observable bool hasIntrinsic;
+  @observable bool isNative;
+
   @reflectable int startAddress = 0;
   @reflectable int endAddress = 0;
   @reflectable final instructions = new ObservableList<CodeInstruction>();
@@ -3567,6 +3593,8 @@
     vmName = (m.containsKey('_vmName') ? m['_vmName'] : name);
     isOptimized = m['_optimized'];
     kind = CodeKind.fromString(m['kind']);
+    hasIntrinsic = m['_intrinsic'];
+    isNative = m['_native'];
     if (mapIsRef) {
       return;
     }
@@ -3646,20 +3674,25 @@
     instructions.clear();
     instructionsByAddressOffset = new List(endAddress - startAddress);
 
-    assert((disassembly.length % 3) == 0);
-    for (var i = 0; i < disassembly.length; i += 3) {
+    assert((disassembly.length % 4) == 0);
+    for (var i = 0; i < disassembly.length; i += 4) {
       var address = 0;  // Assume code comment.
       var machine = disassembly[i + 1];
       var human = disassembly[i + 2];
+      var object = disassembly[i + 3];
+      if (object != null) {
+        object = new ServiceObject._fromMap(owner, object);
+      }
       var pcOffset = 0;
-      if (disassembly[i] != '') {
+      if (disassembly[i] != null) {
         // Not a code comment, extract address.
         address = int.parse(disassembly[i], radix:16);
         pcOffset = address - startAddress;
       }
-      var instruction = new CodeInstruction(address, pcOffset, machine, human);
+      var instruction =
+          new CodeInstruction(address, pcOffset, machine, human, object);
       instructions.add(instruction);
-      if (disassembly[i] != '') {
+      if (disassembly[i] != null) {
         // Not a code comment.
         instructionsByAddressOffset[pcOffset] = instruction;
       }
diff --git a/runtime/observatory/observatory_sources.gypi b/runtime/observatory/observatory_sources.gypi
index 630ca4c..865f140 100644
--- a/runtime/observatory/observatory_sources.gypi
+++ b/runtime/observatory/observatory_sources.gypi
@@ -6,7 +6,6 @@
 {
   'sources': [
     'lib/app.dart',
-    'lib/base64.dart',
     'lib/cli.dart',
     'lib/cpu_profile.dart',
     'lib/debugger.dart',
@@ -134,6 +133,8 @@
     'lib/src/elements/service_view.html',
     'lib/src/elements/sliding_checkbox.dart',
     'lib/src/elements/sliding_checkbox.html',
+    'lib/src/elements/timeline_page.dart',
+    'lib/src/elements/timeline_page.html',
     'lib/src/elements/view_footer.dart',
     'lib/src/elements/view_footer.html',
     'lib/src/elements/vm_connect.dart',
@@ -152,5 +153,8 @@
     'web/index.html',
     'web/main.dart',
     'web/favicon.ico',
+    'web/third_party/trace_viewer_full.html',
+    'web/timeline.js',
+    'web/timeline.html',
   ],
 }
diff --git a/runtime/observatory/pubspec.yaml b/runtime/observatory/pubspec.yaml
index ade59b1..59ec18c 100644
--- a/runtime/observatory/pubspec.yaml
+++ b/runtime/observatory/pubspec.yaml
@@ -8,6 +8,7 @@
     inline_stylesheets:
       lib/src/elements/css/shared.css: false
       packages/charted/charts/themes/quantum_theme.css: false
+    $exclude: [web/third_party/*.html, web/timeline.html]
 - $dart2js:
     $include: "**/*.polymer.bootstrap.dart"
     suppressWarnings: false
diff --git a/runtime/observatory/run.sh b/runtime/observatory/run.sh
deleted file mode 100755
index 35fecbb..0000000
--- a/runtime/observatory/run.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/sh -e
-
-if [ ! -d "web" ]; then
-  echo "Error: you must run this script from the client directory."
-  exit
-fi
-
-PUB_PATH=pub
-PUB_ARGS="serve --hostname 127.0.0.1 --port 9191"
-DART_PATH=dart
-DART_ARGS="bin/server.dart --host 127.0.0.1 --port 9090"
-DART_ARGS="$DART_ARGS --pub-host 127.0.0.1 --pub-port 9191"
-
-# Kill any child processes on exit.
-trap 'kill $(jobs -pr)' SIGINT SIGTERM EXIT
-
-echo "This script assumes that both *pub* and *dart* are in your PATH."
-echo "Launching Observatory server."
-echo "Launching pub."
-echo ""
-echo ""
-echo ""
-$DART_PATH $DART_ARGS &
-$PUB_PATH $PUB_ARGS
-
diff --git a/runtime/observatory/tests/service/coverage_test.dart b/runtime/observatory/tests/service/coverage_test.dart
index 5223092..b558c46 100644
--- a/runtime/observatory/tests/service/coverage_test.dart
+++ b/runtime/observatory/tests/service/coverage_test.dart
@@ -75,7 +75,7 @@
   coverage = await isolate.invokeRpcNoUpgrade('_getCoverage',
                                               { 'targetId': lib.id });
   expect(coverage['type'], equals('CodeCoverage'));
-  expect(coverage['coverage'].length, equals(3));
+  expect(coverage['coverage'].length, equals(4));
   expect(coverage['coverage'][0]['hits'],
          equals([15, 1, 16, 0, 18, 1, 20, 1,
                  24, 1, 25, 1, 27, 0]));
@@ -87,7 +87,7 @@
   coverage = await isolate.invokeRpcNoUpgrade('_getCoverage',
                                        { 'targetId': cls.location.script.id });
   expect(coverage['type'], equals('CodeCoverage'));
-  expect(coverage['coverage'].length, equals(3));
+  expect(coverage['coverage'].length, equals(4));
   expect(coverage['coverage'][0]['hits'],
          equals([15, 1, 16, 0, 18, 1, 20, 1,
                  24, 1, 25, 1, 27, 0]));
diff --git a/runtime/observatory/tests/service/get_object_rpc_test.dart b/runtime/observatory/tests/service/get_object_rpc_test.dart
index fdcbaa1..882b016 100644
--- a/runtime/observatory/tests/service/get_object_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_object_rpc_test.dart
@@ -5,9 +5,10 @@
 
 library get_object_rpc_test;
 
+import 'dart:typed_data';
+import 'dart:convert' show BASE64;
 import 'package:observatory/service_io.dart';
 import 'package:unittest/unittest.dart';
-
 import 'test_helper.dart';
 
 class _DummyClass {
@@ -33,6 +34,9 @@
   return await isolate.invokeRpcNoUpgrade('evaluate', params);
 }
 
+var uint8List = new Uint8List.fromList([3, 2, 1]);
+var uint64List = new Uint64List.fromList([3, 2, 1]);
+
 var tests = [
   // null object.
   (Isolate isolate) async {
@@ -99,16 +103,108 @@
     expect(result['class']['name'], equals('_GrowableList'));
     expect(result['size'], isPositive);
     expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], isNull);
+    expect(result['count'], isNull);
     expect(result['elements'].length, equals(3));
     expect(result['elements'][0]['type'], equals('@Instance'));
     expect(result['elements'][0]['kind'], equals('Int'));
     expect(result['elements'][0]['valueAsString'], equals('3'));
+    expect(result['elements'][1]['type'], equals('@Instance'));
+    expect(result['elements'][1]['kind'], equals('Int'));
+    expect(result['elements'][1]['valueAsString'], equals('2'));
+    expect(result['elements'][2]['type'], equals('@Instance'));
+    expect(result['elements'][2]['kind'], equals('Int'));
+    expect(result['elements'][2]['valueAsString'], equals('1'));
+  },
+
+  // List prefix.
+  (Isolate isolate) async {
+    // Call eval to get a Dart list.
+    var evalResult = await eval(isolate, '[3, 2, 1]');
+    var params = {
+      'objectId': evalResult['id'],
+      'count': 2,
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('List'));
+    expect(result['_vmType'], equals('GrowableObjectArray'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], isNull);
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_GrowableList'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], isNull);
+    expect(result['count'], equals(2));
+    expect(result['elements'].length, equals(2));
+    expect(result['elements'][0]['type'], equals('@Instance'));
+    expect(result['elements'][0]['kind'], equals('Int'));
+    expect(result['elements'][0]['valueAsString'], equals('3'));
+    expect(result['elements'][1]['type'], equals('@Instance'));
+    expect(result['elements'][1]['kind'], equals('Int'));
+    expect(result['elements'][1]['valueAsString'], equals('2'));
+  },
+
+  // List suffix.
+  (Isolate isolate) async {
+    // Call eval to get a Dart list.
+    var evalResult = await eval(isolate, '[3, 2, 1]');
+    var params = {
+      'objectId': evalResult['id'],
+      'offset': 2,
+      'count': 2,
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('List'));
+    expect(result['_vmType'], equals('GrowableObjectArray'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], isNull);
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_GrowableList'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], equals(2));
+    expect(result['count'], equals(1));
+    expect(result['elements'].length, equals(1));
+    expect(result['elements'][0]['type'], equals('@Instance'));
+    expect(result['elements'][0]['kind'], equals('Int'));
+    expect(result['elements'][0]['valueAsString'], equals('1'));
+  },
+
+  // List with wacky offset.
+  (Isolate isolate) async {
+    // Call eval to get a Dart list.
+    var evalResult = await eval(isolate, '[3, 2, 1]');
+    var params = {
+      'objectId': evalResult['id'],
+      'offset': 100,
+      'count': 2,
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('List'));
+    expect(result['_vmType'], equals('GrowableObjectArray'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], isNull);
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_GrowableList'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], equals(3));
+    expect(result['count'], equals(0));
+    expect(result['elements'], isEmpty);
   },
 
   // A built-in Map.
   (Isolate isolate) async {
     // Call eval to get a Dart map.
-    var evalResult = await eval(isolate, '{"x": 3, "y": 4}');
+    var evalResult = await eval(isolate, '{"x": 3, "y": 4, "z": 5}');
     var params = {
       'objectId': evalResult['id'],
     };
@@ -122,6 +218,51 @@
     expect(result['class']['name'], equals('_InternalLinkedHashMap'));
     expect(result['size'], isPositive);
     expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], isNull);
+    expect(result['count'], isNull);
+    expect(result['associations'].length, equals(3));
+    expect(result['associations'][0]['key']['type'], equals('@Instance'));
+    expect(result['associations'][0]['key']['kind'], equals('String'));
+    expect(result['associations'][0]['key']['valueAsString'], equals('x'));
+    expect(result['associations'][0]['value']['type'], equals('@Instance'));
+    expect(result['associations'][0]['value']['kind'], equals('Int'));
+    expect(result['associations'][0]['value']['valueAsString'], equals('3'));
+    expect(result['associations'][1]['key']['type'], equals('@Instance'));
+    expect(result['associations'][1]['key']['kind'], equals('String'));
+    expect(result['associations'][1]['key']['valueAsString'], equals('y'));
+    expect(result['associations'][1]['value']['type'], equals('@Instance'));
+    expect(result['associations'][1]['value']['kind'], equals('Int'));
+    expect(result['associations'][1]['value']['valueAsString'], equals('4'));
+    expect(result['associations'][2]['key']['type'], equals('@Instance'));
+    expect(result['associations'][2]['key']['kind'], equals('String'));
+    expect(result['associations'][2]['key']['valueAsString'], equals('z'));
+    expect(result['associations'][2]['value']['type'], equals('@Instance'));
+    expect(result['associations'][2]['value']['kind'], equals('Int'));
+    expect(result['associations'][2]['value']['valueAsString'], equals('5'));
+  },
+
+  // Map prefix.
+  (Isolate isolate) async {
+    // Call eval to get a Dart map.
+    var evalResult = await eval(isolate, '{"x": 3, "y": 4, "z": 5}');
+    var params = {
+      'objectId': evalResult['id'],
+      'count': 2,
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('Map'));
+    expect(result['_vmType'], equals('LinkedHashMap'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], isNull);
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_InternalLinkedHashMap'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], isNull);
+    expect(result['count'], equals(2));
     expect(result['associations'].length, equals(2));
     expect(result['associations'][0]['key']['type'], equals('@Instance'));
     expect(result['associations'][0]['key']['kind'], equals('String'));
@@ -137,6 +278,268 @@
     expect(result['associations'][1]['value']['valueAsString'], equals('4'));
   },
 
+  // Map suffix.
+  (Isolate isolate) async {
+    // Call eval to get a Dart map.
+    var evalResult = await eval(isolate, '{"x": 3, "y": 4, "z": 5}');
+    var params = {
+      'objectId': evalResult['id'],
+      'offset': 2,
+      'count': 2,
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('Map'));
+    expect(result['_vmType'], equals('LinkedHashMap'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], isNull);
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_InternalLinkedHashMap'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], equals(2));
+    expect(result['count'], equals(1));
+    expect(result['associations'].length, equals(1));
+    expect(result['associations'][0]['key']['type'], equals('@Instance'));
+    expect(result['associations'][0]['key']['kind'], equals('String'));
+    expect(result['associations'][0]['key']['valueAsString'], equals('z'));
+    expect(result['associations'][0]['value']['type'], equals('@Instance'));
+    expect(result['associations'][0]['value']['kind'], equals('Int'));
+    expect(result['associations'][0]['value']['valueAsString'], equals('5'));
+  },
+
+  // Map with wacky offset
+  (Isolate isolate) async {
+    // Call eval to get a Dart map.
+    var evalResult = await eval(isolate, '{"x": 3, "y": 4, "z": 5}');
+    var params = {
+      'objectId': evalResult['id'],
+      'offset': 100,
+      'count': 2,
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('Map'));
+    expect(result['_vmType'], equals('LinkedHashMap'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], isNull);
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_InternalLinkedHashMap'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], equals(3));
+    expect(result['count'], equals(0));
+    expect(result['associations'], isEmpty);
+  },
+
+  // Uint8List.
+  (Isolate isolate) async {
+    // Call eval to get a Dart list.
+    var evalResult = await eval(isolate, 'uint8List');
+    var params = {
+      'objectId': evalResult['id'],
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('Uint8List'));
+    expect(result['_vmType'], equals('TypedData'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], isNull);
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_Uint8Array'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], isNull);
+    expect(result['count'], isNull);
+    expect(result['bytes'], equals('AwIB'));
+    var bytes = BASE64.decode(result['bytes']);
+    expect(bytes.buffer.asUint8List().toString(), equals('[3, 2, 1]'));
+  },
+
+  // Uint8List prefix.
+  (Isolate isolate) async {
+    // Call eval to get a Dart list.
+    var evalResult = await eval(isolate, 'uint8List');
+    var params = {
+      'objectId': evalResult['id'],
+      'count' : 2,
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('Uint8List'));
+    expect(result['_vmType'], equals('TypedData'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], isNull);
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_Uint8Array'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], isNull);
+    expect(result['count'], equals(2));
+    expect(result['bytes'], equals('AwI='));
+    var bytes = BASE64.decode(result['bytes']);
+    expect(bytes.buffer.asUint8List().toString(), equals('[3, 2]'));
+  },
+
+  // Uint8List suffix.
+  (Isolate isolate) async {
+    // Call eval to get a Dart list.
+    var evalResult = await eval(isolate, 'uint8List');
+    var params = {
+      'objectId': evalResult['id'],
+      'offset' : 2,
+      'count' : 2,
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('Uint8List'));
+    expect(result['_vmType'], equals('TypedData'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], isNull);
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_Uint8Array'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], equals(2));
+    expect(result['count'], equals(1));
+    expect(result['bytes'], equals('AQ=='));
+    var bytes = BASE64.decode(result['bytes']);
+    expect(bytes.buffer.asUint8List().toString(), equals('[1]'));
+  },
+
+  // Uint8List with wacky offset.
+  (Isolate isolate) async {
+    // Call eval to get a Dart list.
+    var evalResult = await eval(isolate, 'uint8List');
+    var params = {
+      'objectId': evalResult['id'],
+      'offset' : 100,
+      'count' : 2,
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('Uint8List'));
+    expect(result['_vmType'], equals('TypedData'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], isNull);
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_Uint8Array'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], equals(3));
+    expect(result['count'], equals(0));
+    expect(result['bytes'], equals(''));
+  },
+
+  // Uint64List.
+  (Isolate isolate) async {
+    // Call eval to get a Dart list.
+    var evalResult = await eval(isolate, 'uint64List');
+    var params = {
+      'objectId': evalResult['id'],
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('Uint64List'));
+    expect(result['_vmType'], equals('TypedData'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], isNull);
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_Uint64Array'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], isNull);
+    expect(result['count'], isNull);
+    expect(result['bytes'], equals('AwAAAAAAAAACAAAAAAAAAAEAAAAAAAAA'));
+    var bytes = BASE64.decode(result['bytes']);
+    expect(bytes.buffer.asUint64List().toString(), equals('[3, 2, 1]'));
+  },
+
+  // Uint64List prefix.
+  (Isolate isolate) async {
+    // Call eval to get a Dart list.
+    var evalResult = await eval(isolate, 'uint64List');
+    var params = {
+      'objectId': evalResult['id'],
+      'count' : 2,
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('Uint64List'));
+    expect(result['_vmType'], equals('TypedData'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], isNull);
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_Uint64Array'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], isNull);
+    expect(result['count'], equals(2));
+    expect(result['bytes'], equals('AwAAAAAAAAACAAAAAAAAAA=='));
+    var bytes = BASE64.decode(result['bytes']);
+    expect(bytes.buffer.asUint64List().toString(), equals('[3, 2]'));
+  },
+
+  // Uint64List suffix.
+  (Isolate isolate) async {
+    // Call eval to get a Dart list.
+    var evalResult = await eval(isolate, 'uint64List');
+    var params = {
+      'objectId': evalResult['id'],
+      'offset' : 2,
+      'count' : 2,
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('Uint64List'));
+    expect(result['_vmType'], equals('TypedData'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], isNull);
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_Uint64Array'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], equals(2));
+    expect(result['count'], equals(1));
+    expect(result['bytes'], equals('AQAAAAAAAAA='));
+    var bytes = BASE64.decode(result['bytes']);
+    expect(bytes.buffer.asUint64List().toString(), equals('[1]'));
+  },
+
+  // Uint64List with wacky offset.
+  (Isolate isolate) async {
+    // Call eval to get a Dart list.
+    var evalResult = await eval(isolate, 'uint64List');
+    var params = {
+      'objectId': evalResult['id'],
+      'offset' : 100,
+      'count' : 2,
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('Uint64List'));
+    expect(result['_vmType'], equals('TypedData'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], isNull);
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_Uint64Array'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], equals(3));
+    expect(result['count'], equals(0));
+    expect(result['bytes'], equals(''));
+  },
+
   // An expired object.
   (Isolate isolate) async {
     var params = {
diff --git a/runtime/observatory/tests/service/get_vm_timeline_rpc_test.dart b/runtime/observatory/tests/service/get_vm_timeline_rpc_test.dart
new file mode 100644
index 0000000..a1f4806
--- /dev/null
+++ b/runtime/observatory/tests/service/get_vm_timeline_rpc_test.dart
@@ -0,0 +1,73 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--error_on_bad_type --error_on_bad_override --complete_timeline
+
+import 'dart:developer';
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+
+import 'test_helper.dart';
+
+primeTimeline() {
+  Timeline.startSync('apple');
+  Timeline.instantSync('ISYNC', arguments: {'fruit': 'banana'});
+  Timeline.finishSync();
+  TimelineTask task = new TimelineTask();
+  task.start('TASK1');
+  task.instant('ITASK');
+  task.finish();
+}
+
+List<Map> filterForDartEvents(List<Map> events) {
+  return events.where((event) => event['cat'] == 'Dart').toList();
+}
+
+bool eventsContains(List<Map> events, String phase, String name) {
+  for (Map event in events) {
+    if ((event['ph'] == phase) && (event['name'] == name)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+void allEventsHaveIsolateNumber(List<Map> events) {
+  for (Map event in events) {
+    if (event['ph'] == 'M') {
+      // Skip meta-data events.
+      continue;
+    }
+    if (event['name'] == 'Runnable' && event['ph'] == 'i') {
+      // Skip Runnable events which don't have an isolate.
+      continue;
+    }
+    if (event['cat'] == 'VM') {
+      // Skip VM category events which don't have an isolate.
+      continue;
+    }
+    Map arguments = event['args'];
+    expect(arguments, new isInstanceOf<Map>());
+    expect(arguments['isolateNumber'], new isInstanceOf<String>());
+  }
+}
+
+var tests = [
+  (VM vm) async {
+    Map result = await vm.invokeRpcNoUpgrade('_getVMTimeline', {});
+    expect(result['type'], equals('_Timeline'));
+    expect(result['traceEvents'], new isInstanceOf<List>());
+    List<Map> dartEvents = filterForDartEvents(result['traceEvents']);
+    expect(dartEvents.length, equals(5));
+    allEventsHaveIsolateNumber(dartEvents);
+    allEventsHaveIsolateNumber(result['traceEvents']);
+    expect(eventsContains(dartEvents, 'I', 'ISYNC'), isTrue);
+    expect(eventsContains(dartEvents, 'X', 'apple'), isTrue);
+    expect(eventsContains(dartEvents, 'b', 'TASK1'), isTrue);
+    expect(eventsContains(dartEvents, 'e', 'TASK1'), isTrue);
+    expect(eventsContains(dartEvents, 'n', 'ITASK'), isTrue);
+    expect(eventsContains(dartEvents, 'q', 'ITASK'), isFalse);
+  },
+];
+
+main(args) async => runVMTests(args, tests, testeeBefore: primeTimeline);
diff --git a/runtime/observatory/tests/service/implicit_getter_setter_test.dart b/runtime/observatory/tests/service/implicit_getter_setter_test.dart
new file mode 100644
index 0000000..dbf4487
--- /dev/null
+++ b/runtime/observatory/tests/service/implicit_getter_setter_test.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library implicit_getter_setter_test;
+
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+import 'test_helper.dart';
+
+class A {
+  double field = 0.0;
+}
+
+script() {
+  for (int i = 0; i < 10; i++) {
+    new A();
+  }
+}
+
+testGetter(Isolate isolate) async {
+  Library rootLibrary = await isolate.rootLibrary.load();
+  expect(rootLibrary.classes.length, equals(1));
+  Class classA = await rootLibrary.classes[0].load();
+  expect(classA.name, equals('A'));
+  // Find getter.
+  ServiceFunction getterFunc;
+  for (ServiceFunction function in classA.functions) {
+    if (function.name == 'field') {
+      getterFunc = function;
+      break;
+    }
+  }
+  expect(getterFunc, isNotNull);
+  await getterFunc.load();
+  Field field = await getterFunc.field.load();
+  expect(field, isNotNull);
+  expect(field.name, equals('field'));
+  Class classDouble = await field.guardClass.load();
+  expect(classDouble.name, equals('_Double'));
+}
+
+
+testSetter(Isolate isolate) async {
+  Library rootLibrary = await isolate.rootLibrary.load();
+  expect(rootLibrary.classes.length, equals(1));
+  Class classA = await rootLibrary.classes[0].load();
+  expect(classA.name, equals('A'));
+  // Find setter.
+  ServiceFunction setterFunc;
+  for (ServiceFunction function in classA.functions) {
+    if (function.name == 'field=') {
+      setterFunc = function;
+      break;
+    }
+  }
+  expect(setterFunc, isNotNull);
+  await setterFunc.load();
+  Field field = await setterFunc.field.load();
+  expect(field, isNotNull);
+  expect(field.name, equals('field'));
+  Class classDouble = await field.guardClass.load();
+  expect(classDouble.name, equals('_Double'));
+}
+
+
+var tests = [testGetter, testSetter];
+
+main(args) => runIsolateTests(args, tests, testeeBefore: script);
diff --git a/runtime/observatory/tests/service/service.status b/runtime/observatory/tests/service/service.status
index 1aeac65..84145a3 100644
--- a/runtime/observatory/tests/service/service.status
+++ b/runtime/observatory/tests/service/service.status
@@ -20,3 +20,6 @@
 
 [ $arch == arm ]
 process_service_test: Pass, Fail # Issue 24344
+
+[ $noopt ]
+*: Skip # Issue 24651
\ No newline at end of file
diff --git a/runtime/observatory/web/third_party/README.md b/runtime/observatory/web/third_party/README.md
new file mode 100644
index 0000000..ba94574
--- /dev/null
+++ b/runtime/observatory/web/third_party/README.md
@@ -0,0 +1,4 @@
+This directory contains a vulcanized version of trace-viewer:
+
+https://github.com/catapult-project/catapult/wiki/Embedding-Trace-Viewer
+
diff --git a/runtime/observatory/web/third_party/trace_viewer_full.html b/runtime/observatory/web/third_party/trace_viewer_full.html
new file mode 100644
index 0000000..930312b
--- /dev/null
+++ b/runtime/observatory/web/third_party/trace_viewer_full.html
@@ -0,0 +1,7113 @@
+<!DOCTYPE html>
+<html>
+  <head i18n-values="dir:textdirection;">
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
+<template id="overlay-template">
+  <style>
+    overlay-mask {
+      left: 0;
+      padding: 8px;
+      position: absolute;
+      top: 0;
+      z-index: 1000;
+      font-family: sans-serif;
+      -webkit-justify-content: center;
+      background: rgba(0, 0, 0, 0.8);
+      display: -webkit-flex;
+      height: 100%;
+      left: 0;
+      position: fixed;
+      top: 0;
+      width: 100%;
+    }
+    overlay-mask:focus {
+      outline: none;
+    }
+    overlay-vertical-centering-container {
+      -webkit-justify-content: center;
+      -webkit-flex-direction: column;
+      display: -webkit-flex;
+    }
+    overlay-frame {
+      z-index: 1100;
+      background: rgb(255, 255, 255);
+      border: 1px solid #ccc;
+      margin: 75px;
+      display: -webkit-flex;
+      -webkit-flex-direction: column;
+      min-height: 0;
+    }
+    title-bar {
+      -webkit-align-items: center;
+      -webkit-flex-direction: row;
+      border-bottom: 1px solid #ccc;
+      background-color: #ddd;
+      display: -webkit-flex;
+      padding: 5px;
+      -webkit-flex: 0 0 auto;
+    }
+    title {
+      display: inline;
+      font-weight: bold;
+      -webkit-box-flex: 1;
+      -webkit-flex: 1 1 auto;
+    }
+    close-button {
+      -webkit-align-self: flex-end;
+      border: 1px solid #eee;
+      background-color: #999;
+      font-size: 10pt;
+      font-weight: bold;
+      padding: 2px;
+      text-align: center;
+      width: 16px;
+    }
+    close-button:hover {
+      background-color: #ddd;
+      border-color: black;
+      cursor: pointer;
+    }
+    overlay-content {
+      display: -webkit-flex;
+      -webkit-flex: 1 1 auto;
+      -webkit-flex-direction: column;
+      overflow-y: auto;
+      padding: 10px;
+      min-width: 300px;
+      min-height: 0;
+    }
+    button-bar {
+      -webkit-align-items: baseline;
+      border-top: 1px solid #ccc;
+      display: -webkit-flex;
+      -webkit-flex: 0 0 auto;
+      -webkit-flex-direction: row-reverse;
+      padding: 4px;
+    }
+  </style>
+
+  <overlay-mask>
+    <overlay-vertical-centering-container>
+      <overlay-frame>
+        <title-bar>
+          <title></title>
+          <close-button>✕</close-button>
+        </title-bar>
+        <overlay-content>
+          <content></content>
+        </overlay-content>
+        <button-bar></button-bar>
+      </overlay-frame>
+    </overlay-vertical-centering-container>
+  </overlay-mask>
+</template><polymer-element constructor="TracingAnalysisTabView" name="tr-ui-a-tab-view">
+  <template>
+    <style>
+      :host {
+        display: flex;
+        flex-flow: column nowrap;
+        overflow: hidden;
+        box-sizing: border-box;
+      }
+
+      tab-strip[tabs-hidden] {
+        display: none;
+      }
+
+      tab-strip {
+        background-color: rgb(236, 236, 236);
+        border-bottom: 1px solid #8e8e8e;
+        display: flex;
+        flex: 0 0 auto;
+        flex-flow: row;
+        overflow-x: auto;
+        padding: 0 10px 0 10px;
+        font-size: 12px;
+      }
+
+      tab-button {
+        display: block;
+        flex: 0 0 auto;
+        padding: 4px 15px 1px 15px;
+        margin-top: 2px;
+      }
+
+      tab-button[selected=true] {
+        background-color: white;
+        border: 1px solid rgb(163, 163, 163);
+        border-bottom: none;
+        padding: 3px 14px 1px 14px;
+      }
+
+      tabs-content-container {
+        display: flex;
+        flex: 1 1 auto;
+        overflow: auto;
+        width: 100%;
+      }
+
+      ::content > * {
+        flex: 1 1 auto;
+      }
+
+      ::content > *:not([selected]) {
+        display: none;
+      }
+
+      button-label {
+        display: inline;
+      }
+
+      tab-strip-heading {
+        display: block;
+        flex: 0 0 auto;
+        padding: 4px 15px 1px 15px;
+        margin-top: 2px;
+        margin-before: 20px;
+        margin-after: 10px;
+      }
+      #tsh {
+        display: inline;
+        font-weight: bold;
+      }
+    </style>
+
+    <tab-strip>
+      <tab-strip-heading id="tshh">
+        <span id="tsh"></span>
+      </tab-strip-heading>
+      <template repeat="{{tab in tabs_}}">
+        <tab-button button-id="{{ tab.id }}" on-click="{{ tabButtonSelectHandler_ }}" selected="{{ selectedTab_.id === tab.id }}">
+          <button-label>{{ tab.label ? tab.label : 'No Label'}}</button-label>
+        </tab-button>
+      </template>
+    </tab-strip>
+
+    <tabs-content-container id="content-container">
+        <content></content>
+    </tabs-content-container>
+
+  </template>
+
+  
+</polymer-element><polymer-element name="tr-ui-a-sub-view">
+  
+</polymer-element><style>
+* /deep/ .labeled-checkbox {
+  display: flex;
+  white-space: nowrap;
+}
+</style><polymer-element is="a" name="tr-ui-a-analysis-link" on-click="{{onClicked_}}" on-mouseenter="{{onMouseEnter_}}" on-mouseleave="{{onMouseLeave_}}">
+  <template>
+    <style>
+    :host {
+      display: inline;
+      color: -webkit-link;
+      cursor: pointer;
+      text-decoration: underline;
+      cursor: pointer;
+    }
+    </style>
+    <content></content>
+  </template>
+  
+</polymer-element><polymer-element name="tr-ui-b-table">
+  <template>
+    <style>
+      :host {
+        display: flex;
+        flex-direction: column;
+      }
+
+      table {
+        font-size: 12px;
+
+        flex: 1 1 auto;
+        align-self: stretch;
+        border-collapse: separate;
+        border-spacing: 0;
+        border-width: 0;
+        -webkit-user-select: initial;
+      }
+
+      tr > td {
+        padding: 2px 4px 2px 4px;
+        vertical-align: text-top;
+      }
+
+      tr:focus,
+      td:focus {
+        outline: 1px dotted rgba(0,0,0,0.1);
+        outline-offset: 0;
+      }
+
+      button.toggle-button {
+        height: 15px;
+        line-height: 60%;
+        vertical-align: middle;
+        width: 100%;
+      }
+
+      button > * {
+        height: 15px;
+        vertical-align: middle;
+      }
+
+      td.button-column {
+        width: 30px;
+      }
+
+      table > thead > tr > td.sensitive:hover {
+        background-color: #fcfcfc;
+      }
+
+      table > thead > tr > td {
+        font-weight: bold;
+        text-align: left;
+
+        background-color: #eee;
+        white-space: nowrap;
+        overflow: hidden;
+        text-overflow: ellipsis;
+
+        border-top: 1px solid #ffffff;
+        border-bottom: 1px solid #aaa;
+      }
+
+      table > tfoot {
+        background-color: #eee;
+        font-weight: bold;
+      }
+
+      /* Light row and cell highlight. */
+      table > tbody[row-highlight-style="light"] > tr[selected],
+      table > tbody[cell-highlight-style="light"] > tr > td[selected] {
+        background-color: rgb(213, 236, 229);  /* light turquoise */
+      }
+      table > tbody[row-highlight-style="light"] >
+          tr:not(.empty-row):not([selected]):hover,
+      table > tbody[cell-highlight-style="light"] >
+          tr:not(.empty-row):not([selected]) > td:hover {
+        background-color: #f6f6f6;  /* light grey */
+      }
+
+      /* Dark row and cell highlight. */
+      table > tbody[row-highlight-style="dark"] > tr[selected],
+      table > tbody[cell-highlight-style="dark"] > tr > td[selected] {
+        background-color: rgb(103, 199, 165);  /* turquoise */
+      }
+      table > tbody[row-highlight-style="dark"] >
+          tr:not(.empty-row):not([selected]):hover,
+      table > tbody[cell-highlight-style="dark"] >
+          tr:not(.empty-row):not([selected]) > td:hover {
+        background-color: #e6e6e6;  /* grey */
+      }
+      table > tbody[row-highlight-style="dark"] > tr:hover[selected],
+      table > tbody[cell-highlight-style="dark"] > tr[selected] > td:hover {
+        background-color: rgb(171, 217, 202);  /* semi-light turquoise */
+      }
+
+      table > tbody > tr.empty-row > td {
+        color: #666;
+        font-style: italic;
+        text-align: center;
+      }
+
+      table > tbody.has-footer > tr:last-child > td {
+        border-bottom: 1px solid #aaa;
+      }
+
+      table > tfoot > tr:first-child > td {
+        border-top: 1px solid #ffffff;
+      }
+
+      expand-button {
+        -webkit-user-select: none;
+        display: inline-block;
+        cursor: pointer;
+        font-size: 9px;
+        min-width: 8px;
+        max-width: 8px;
+      }
+
+      .button-expanded {
+        transform: rotate(90deg);
+      }
+    </style>
+    <table>
+      <thead id="head">
+      </thead>
+      <tbody id="body">
+      </tbody>
+      <tfoot id="foot">
+      </tfoot>
+    </table>
+  </template>
+  
+</polymer-element><polymer-element name="tr-ui-b-table-header-cell" on-tap="onTap_">
+  <template>
+  <style>
+    :host {
+      -webkit-user-select: none;
+      display: flex;
+    }
+
+    span {
+      flex: 0 1 auto;
+    }
+
+    side-element {
+      -webkit-user-select: none;
+      flex: 1 0 auto;
+      padding-left: 4px;
+      vertical-align: top;
+      font-size: 15px;
+      font-family: sans-serif;
+      display: inline;
+      line-height: 85%;
+    }
+  </style>
+
+    <span id="title"></span><side-element id="side"></side-element>
+  </template>
+
+  
+</polymer-element><polymer-element name="tr-ui-u-scalar-span">
+  <template>
+    <style>
+    :host {
+      display: block;
+      position: relative;
+    }
+    #content.right-align {
+      text-align: right;
+      position: relative;
+      display: block;
+    }
+    #sparkline {
+      width: 0%;
+      position: absolute;
+      bottom: 0;
+      right: 0;
+      display: none;
+      height: 100%;
+      background-color: hsla(216, 100%, 94.5%, .75);
+      border-left: 1px solid hsl(216, 100%, 89%);
+      box-sizing: border-box;
+    }
+    #warning {
+      margin-left: 4px;
+      font-size: 66%;
+    }
+    </style>
+    <span id="sparkline"></span>
+    <span id="content"></span>
+    <span id="warning" style="display:none">⚠</span>
+  </template>
+  
+</polymer-element><polymer-element extends="tr-ui-u-scalar-span" name="tr-ui-u-time-duration-span">
+  
+</polymer-element><polymer-element extends="tr-ui-u-scalar-span" name="tr-ui-u-time-stamp-span">
+  
+</polymer-element><polymer-element is="HTMLUnknownElement" name="tr-ui-a-generic-object-view">
+  <template>
+    <style>
+    :host {
+      display: block;
+      font-family: monospace;
+    }
+    </style>
+    <div id="content">
+    </div>
+  </template>
+
+  
+</polymer-element><polymer-element is="HTMLUnknownElement" name="tr-ui-a-generic-object-view-with-label">
+  <template>
+    <style>
+    :host {
+      display: block;
+    }
+    </style>
+  </template>
+
+  
+</polymer-element><polymer-element name="tr-ui-a-stack-frame">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+    }
+    </style>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-event-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+    }
+    #table {
+      flex: 1 1 auto;
+      align-self: stretch;
+    }
+    </style>
+    <tr-ui-b-table id="table">
+    </tr-ui-b-table>
+  </template>
+  
+</polymer-element><polymer-element name="tr-ui-a-related-events">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+    }
+    #table {
+      flex: 1 1 auto;
+      align-self: stretch;
+    }
+    </style>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-thread-slice-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: row;
+    }
+    #events {
+      display: flex;
+      flex-direction: column;
+    }
+
+    </style>
+    <tr-ui-a-single-event-sub-view id="content"></tr-ui-a-single-event-sub-view>
+    <div id="events">
+      <tr-ui-a-related-events id="relatedEvents">
+      </tr-ui-a-related-events>
+    </div>
+  </template>
+
+  
+</polymer-element><polymer-element name="tr-ui-a-selection-summary-table">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    #table {
+      flex: 1 1 auto;
+      align-self: stretch;
+    }
+    </style>
+    <tr-ui-b-table id="table">
+    </tr-ui-b-table>
+    
+  </template>
+  
+</polymer-element><polymer-element name="tr-ui-a-multi-event-summary-table">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    #table {
+      flex: 1 1 auto;
+      align-self: stretch;
+    }
+    </style>
+    <tr-ui-b-table id="table">
+    </tr-ui-b-table>
+    
+  </template>
+  
+</polymer-element><polymer-element name="tr-ui-a-multi-event-details-table">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+    }
+    #table {
+      flex: 1 1 auto;
+      align-self: stretch;
+    }
+
+    #titletable {
+      font-weight: bold;
+    }
+
+    #title-info {
+      font-size: 12px;
+    }
+    </style>
+    <tr-ui-b-table id="titletable">
+    </tr-ui-b-table>
+    <tr-ui-b-table id="table">
+    </tr-ui-b-table>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-event-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      overflow: auto;
+    }
+    #content {
+      display: flex;
+      flex-direction: column;
+      flex: 0 1 auto;
+      align-self: stretch;
+    }
+    #content > * {
+      flex: 0 0 auto;
+      align-self: stretch;
+    }
+    tr-ui-a-multi-event-summary-table {
+      border-bottom: 1px solid #aaa;
+    }
+
+    tr-ui-a-selection-summary-table  {
+      margin-top: 1.25em;
+      border-top: 1px solid #aaa;
+      background-color: #eee;
+      font-weight: bold;
+      margin-bottom: 1.25em;
+      border-bottom: 1px solid #aaa;
+    }
+    </style>
+    <div id="content"></div>
+  </template>
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-thread-slice-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    #content {
+      display: flex;
+      flex: 1 1 auto;
+    }
+    #content > tr-ui-a-related-events {
+      margin-left: 8px;
+      flex: 0 1 200px;
+    }
+    </style>
+    <div id="content"></div>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-single-event-sub-view" name="tr-ui-a-single-async-slice-sub-view">
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-async-slice-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    </style>
+    <tr-ui-a-multi-event-sub-view id="content"></tr-ui-a-multi-event-sub-view>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-cpu-slice-sub-view">
+  <template>
+    <style>
+    table {
+      border-collapse: collapse;
+      border-width: 0;
+      margin-bottom: 25px;
+      width: 100%;
+    }
+
+    table tr > td:first-child {
+      padding-left: 2px;
+    }
+
+    table tr > td {
+      padding: 2px 4px 2px 4px;
+      vertical-align: text-top;
+      width: 150px;
+    }
+
+    table td td {
+      padding: 0 0 0 0;
+      width: auto;
+    }
+    tr {
+      vertical-align: top;
+    }
+
+    tr:nth-child(2n+0) {
+      background-color: #e2e2e2;
+    }
+    </style>
+    <table>
+      <tbody><tr>
+        <td>Running process:</td><td id="process-name"></td>
+      </tr>
+      <tr>
+        <td>Running thread:</td><td id="thread-name"></td>
+      </tr>
+      <tr>
+        <td>Start:</td>
+        <td>
+          <tr-ui-u-time-stamp-span id="start">
+          </tr-ui-u-time-stamp-span>
+        </td>
+      </tr>
+      <tr>
+        <td>Duration:</td>
+        <td>
+          <tr-ui-u-time-duration-span id="duration">
+          </tr-ui-u-time-duration-span>
+        </td>
+      </tr>
+      <tr>
+        <td>Active slices:</td><td id="running-thread"></td>
+      </tr>
+      <tr>
+        <td>Args:</td>
+        <td>
+          <tr-ui-a-generic-object-view id="args">
+          </tr-ui-a-generic-object-view>
+        </td>
+      </tr>
+    </tbody></table>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-cpu-slice-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    #content {
+      flex: 1 1 auto;
+    }
+    </style>
+    <tr-ui-a-multi-event-sub-view id="content"></tr-ui-a-multi-event-sub-view>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-thread-time-slice-sub-view">
+  <template>
+    <style>
+    table {
+      border-collapse: collapse;
+      border-width: 0;
+      margin-bottom: 25px;
+      width: 100%;
+    }
+
+    table tr > td:first-child {
+      padding-left: 2px;
+    }
+
+    table tr > td {
+      padding: 2px 4px 2px 4px;
+      vertical-align: text-top;
+      width: 150px;
+    }
+
+    table td td {
+      padding: 0 0 0 0;
+      width: auto;
+    }
+    tr {
+      vertical-align: top;
+    }
+
+    tr:nth-child(2n+0) {
+      background-color: #e2e2e2;
+    }
+    </style>
+    <table>
+      <tbody><tr>
+        <td>Running process:</td><td id="process-name"></td>
+      </tr>
+      <tr>
+        <td>Running thread:</td><td id="thread-name"></td>
+      </tr>
+      <tr>
+        <td>State:</td>
+        <td><b><span id="state"></span></b></td>
+      </tr>
+      <tr>
+        <td>Start:</td>
+        <td>
+          <tr-ui-u-time-stamp-span id="start">
+          </tr-ui-u-time-stamp-span>
+        </td>
+      </tr>
+      <tr>
+        <td>Duration:</td>
+        <td>
+          <tr-ui-u-time-duration-span id="duration">
+          </tr-ui-u-time-duration-span>
+        </td>
+      </tr>
+
+      <tr>
+        <td>On CPU:</td><td id="on-cpu"></td>
+      </tr>
+
+      <tr>
+        <td>Running instead:</td><td id="running-instead"></td>
+      </tr>
+
+      <tr>
+        <td>Args:</td><td id="args"></td>
+      </tr>
+    </tbody></table>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-thread-time-slice-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    #content {
+      flex: 1 1 auto;
+    }
+    </style>
+    <tr-ui-a-multi-event-sub-view id="content"></tr-ui-a-multi-event-sub-view>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-instant-event-sub-view">
+  <template>
+    <style>
+    :host {
+      display: block;
+    }
+    </style>
+    <div id="content"></div>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-instant-event-sub-view">
+  <template>
+    <style>
+    :host {
+      display: block;
+    }
+    </style>
+    <div id="content"></div>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-counter-sample-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+    }
+    </style>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+</polymer-element><polymer-element extends="tr-ui-a-single-event-sub-view" name="tr-ui-a-single-flow-event-sub-view">
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-flow-event-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    </style>
+    <tr-ui-a-multi-event-sub-view id="content"></tr-ui-a-multi-event-sub-view>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-object-instance-sub-view">
+  <template>
+    <style>
+    :host {
+      display: block;
+    }
+
+    #snapshots > * {
+      display: block;
+    }
+
+    :host {
+      overflow: auto;
+      display: block;
+    }
+
+    * {
+      -webkit-user-select: text;
+    }
+
+    .title {
+      border-bottom: 1px solid rgb(128, 128, 128);
+      font-size: 110%;
+      font-weight: bold;
+    }
+
+    td, th {
+      font-family: monospace;
+      vertical-align: top;
+    }
+    </style>
+    <div id="content"></div>
+  </template>
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-object-snapshot-sub-view">
+  <template>
+    <style>
+    #args {
+      white-space: pre;
+    }
+
+    :host {
+      overflow: auto;
+      display: flex;
+    }
+
+    ::content * {
+      -webkit-user-select: text;
+    }
+
+    ::content .title {
+      border-bottom: 1px solid rgb(128, 128, 128);
+      font-size: 110%;
+      font-weight: bold;
+    }
+
+    ::content td, th {
+      font-family: monospace;
+      vertical-align: top;
+    }
+    </style>
+    <content></content>
+  </template>
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-object-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    </style>
+    <tr-ui-b-table id="content"></tr-ui-b-table>
+  </template>
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-sample-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    </style>
+    <tr-ui-b-table id="content"></tr-ui-b-table>
+  </template>
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-sample-sub-view">
+  <template>
+    <style>
+    :host { display: block; }
+    #control {
+      background-color: #e6e6e6;
+      background-image: -webkit-gradient(linear, 0 0, 0 100%,
+                                         from(#E5E5E5), to(#D1D1D1));
+      flex: 0 0 auto;
+      overflow-x: auto;
+    }
+    #control::-webkit-scrollbar { height: 0px; }
+    #control {
+      font-size: 12px;
+      display: flex;
+      flex-direction: row;
+      align-items: stretch;
+      margin: 1px;
+      margin-right: 2px;
+    }
+    </style>
+    <div id="control">
+      Sample View Option
+      <select id="view_selector">
+        <option value="TOPDOWNVIEW">Tree (Top Down)</option>
+        <option value="BOTTOMUPVIEW">Heavy (Bottom Up)</option>
+      </select>
+    </div>
+    <tr-ui-b-table id="table">
+    </tr-ui-b-table>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-interaction-record-sub-view">
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-interaction-record-sub-view">
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-alert-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+    }
+    #table {
+      flex: 1 1 auto;
+      align-self: stretch;
+    }
+    </style>
+    <tr-ui-b-table id="table">
+    </tr-ui-b-table>
+  </template>
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-frame-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+    }
+    #asv {
+      flex: 0 0 auto;
+      align-self: stretch;
+    }
+    </style>
+    <tr-ui-a-alert-sub-view id="asv">
+    </tr-ui-a-alert-sub-view>
+  </template>
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-frame-sub-view">
+  
+</polymer-element><polymer-element name="tr-ui-a-stacked-pane">
+  
+</polymer-element><polymer-element extends="tr-ui-a-stacked-pane" name="tr-ui-a-memory-dump-heap-details-pane">
+  <template>
+    <style>
+      :host {
+        display: flex;
+        flex-direction: column;
+      }
+
+      #header {
+        flex: 0 0 auto;
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+
+        background-color: #eee;
+        border-bottom: 1px solid #8e8e8e;
+        border-top: 1px solid white;
+      }
+
+      #label {
+        flex: 1 1 auto;
+        padding: 8px;
+        font-size:  15px;
+        font-weight: bold;
+      }
+
+      #view_mode_container {
+        display: none;
+        flex: 0 0 auto;
+        padding: 5px;
+        font-size: 15px;
+      }
+
+      #contents {
+        flex: 1 0 auto;
+        align-self: stretch;
+        font-size: 12px;
+      }
+
+      #info_text {
+        padding: 8px;
+        color: #666;
+        font-style: italic;
+        text-align: center;
+      }
+
+      #table {
+        display: none;  /* Hide until memory allocator dumps are set. */
+        flex: 1 0 auto;
+        align-self: stretch;
+      }
+    </style>
+    <div id="header">
+      <div id="label">Heap details</div>
+      <div id="view_mode_container">
+        <span>View mode:</span>
+        
+      </div>
+    </div>
+    <div id="contents">
+      <div id="info_text">No heap dump selected</div>
+      <tr-ui-b-table id="table"></tr-ui-b-table>
+    </div>
+  </template>
+</polymer-element><polymer-element extends="tr-ui-a-stacked-pane" name="tr-ui-a-memory-dump-allocator-details-pane">
+  <template>
+    <style>
+      :host {
+        display: flex;
+        flex-direction: column;
+      }
+
+      #label {
+        flex: 0 0 auto;
+        padding: 8px;
+
+        background-color: #eee;
+        border-bottom: 1px solid #8e8e8e;
+        border-top: 1px solid white;
+
+        font-size:  15px;
+        font-weight: bold;
+      }
+
+      #contents {
+        flex: 1 0 auto;
+        align-self: stretch;
+        font-size: 12px;
+      }
+
+      #info_text {
+        padding: 8px;
+        color: #666;
+        font-style: italic;
+        text-align: center;
+      }
+
+      #table {
+        display: none;  /* Hide until memory allocator dumps are set. */
+        flex: 1 0 auto;
+        align-self: stretch;
+      }
+    </style>
+    <div id="label">Component details</div>
+    <div id="contents">
+      <div id="info_text">No memory allocator dump selected</div>
+      <tr-ui-b-table id="table"></tr-ui-b-table>
+    </div>
+  </template>
+</polymer-element><polymer-element extends="tr-ui-a-stacked-pane" name="tr-ui-a-memory-dump-vm-regions-details-pane">
+  <template>
+    <style>
+      :host {
+        display: flex;
+        flex-direction: column;
+      }
+
+      #label {
+        flex: 0 0 auto;
+        padding: 8px;
+
+        background-color: #eee;
+        border-bottom: 1px solid #8e8e8e;
+        border-top: 1px solid white;
+
+        font-size:  15px;
+        font-weight: bold;
+      }
+
+      #contents {
+        flex: 1 0 auto;
+        align-self: stretch;
+        font-size: 12px;
+      }
+
+      #info_text {
+        padding: 8px;
+        color: #666;
+        font-style: italic;
+        text-align: center;
+      }
+
+      #table {
+        display: none;  /* Hide until memory dumps are set. */
+        flex: 1 0 auto;
+        align-self: stretch;
+      }
+    </style>
+    <div id="label">Memory maps</div>
+    <div id="contents">
+      <div id="info_text">No memory maps selected</div>
+      <tr-ui-b-table id="table"></tr-ui-b-table>
+    </div>
+  </template>
+</polymer-element><polymer-element name="tr-ui-b-color-legend">
+  <template>
+    <style>
+    :host {
+      display: inline-block;
+    }
+
+    #square {
+      font-size: 150%;  /* Make the square bigger. */
+      line-height: 0%;  /* Prevent the square from increasing legend height. */
+    }
+    </style>
+    <span id="square"></span>
+    <span id="label"></span>
+  </template>
+  
+</polymer-element><polymer-element name="tr-ui-b-view-specific-brushing-state">
+  
+</polymer-element><polymer-element extends="tr-ui-a-stacked-pane" name="tr-ui-a-memory-dump-overview-pane">
+  <template>
+    <style>
+      :host {
+        display: flex;
+        flex-direction: column;
+      }
+
+      #label {
+        flex: 0 0 auto;
+        padding: 8px;
+
+        background-color: #eee;
+        border-bottom: 1px solid #8e8e8e;
+        border-top: 1px solid white;
+
+        font-size:  15px;
+        font-weight: bold;
+      }
+
+      #contents {
+        flex: 1 0 auto;
+        align-self: stretch;
+        font-size: 12px;
+      }
+
+      #info_text {
+        padding: 8px;
+        color: #666;
+        font-style: italic;
+        text-align: center;
+      }
+
+      #table {
+        display: none;  /* Hide until memory dumps are set. */
+        flex: 1 0 auto;
+        align-self: stretch;
+      }
+    </style>
+    <tr-ui-b-view-specific-brushing-state id="state" view-id="analysis.memory_dump_overview_pane">
+    </tr-ui-b-view-specific-brushing-state>
+    <div id="label">Overview</div>
+    <div id="contents">
+      <div id="info_text">No memory memory dumps selected</div>
+      <tr-ui-b-table id="table"></tr-ui-b-table>
+    </div>
+  </template>
+</polymer-element><polymer-element extends="tr-ui-a-stacked-pane" name="tr-ui-a-memory-dump-header-pane">
+  <template>
+    <style>
+      :host {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+
+        background-color: #d0d0d0;
+        border-bottom: 1px solid #8e8e8e;
+        border-top: 1px solid white;
+      }
+
+      #label {
+        flex: 1 1 auto;
+        padding: 6px;
+        font-size: 15px;
+      }
+
+      #aggregation_mode_container {
+        display: none;
+        flex: 0 0 auto;
+        padding: 5px;
+        font-size: 15px;
+      }
+    </style>
+    
+    <div id="label"></div>
+    <div id="aggregation_mode_container">
+      <span>Metric aggregation:</span>
+      
+    </div>
+  </template>
+</polymer-element><polymer-element name="tr-ui-a-stacked-pane-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+    }
+
+    #pane_container > * {
+      flex: 0 0 auto;
+    }
+    </style>
+    <div id="pane_container">
+    </div>
+  </template>
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-container-memory-dump-sub-view">
+  <template>
+    <div id="content"></div>
+  </template>
+</polymer-element><polymer-element name="tr-ui-a-power-sample-table">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    </style>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-power-sample-sub-view">
+  <template>
+    <style>
+    :host { display: block; }
+    </style>
+    <tr-ui-a-power-sample-table id="samplesTable">
+    </tr-ui-a-power-sample-table>
+  </template>
+
+  
+</polymer-element><style>
+  * /deep/ .chart-base #title {
+    font-size: 16pt;
+  }
+
+  * /deep/ .chart-base {
+    font-size: 12pt;
+    -webkit-user-select: none;
+    cursor: default;
+  }
+
+  * /deep/ .chart-base .axis path,
+  * /deep/ .chart-base .axis line {
+    fill: none;
+    shape-rendering: crispEdges;
+    stroke: #000;
+  }
+</style><template id="chart-base-template">
+  <svg> 
+    <g id="chart-area" xmlns="http://www.w3.org/2000/svg">
+      <g class="x axis"></g>
+      <g class="y axis"></g>
+      <text id="title"></text>
+    </g>
+  </svg>
+</template><style>
+  * /deep/ .chart-base-2d.updating-brushing-state #brushes > * {
+    fill: rgb(103, 199, 165)
+  }
+
+  * /deep/ .chart-base-2d #brushes {
+    fill: rgb(213, 236, 229)
+  }
+</style><style>
+* /deep/ .line-chart .line{fill:none;stroke-width:1.5px}* /deep/ .line-chart #brushes>rect{fill:rgb(192,192,192)}
+</style><polymer-element name="tr-ui-a-frame-power-usage-chart">
+  <template>
+    <div id="content"></div>
+  </template>
+</polymer-element><polymer-element name="tr-ui-a-power-sample-summary-table">
+  <template>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-power-sample-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: row;
+    }
+    #tables {
+      display: flex;
+      flex-direction: column;
+      width: 50%;
+    }
+    #chart {
+      width: 50%;
+    }
+    </style>
+    <div id="tables">
+      <tr-ui-a-power-sample-summary-table id="summaryTable">
+      </tr-ui-a-power-sample-summary-table>
+      <tr-ui-a-power-sample-table id="samplesTable">
+      </tr-ui-a-power-sample-table>
+    </div>
+    <tr-ui-a-frame-power-usage-chart id="chart">
+    </tr-ui-a-frame-power-usage-chart>
+  </template>
+</polymer-element><polymer-element name="tr-ui-a-analysis-view">
+  <template>
+    <style>
+      :host {
+        background-color: white;
+        display: flex;
+        flex-direction: column;
+        height: 275px;
+        overflow: auto;
+      }
+
+      :host(.tall-mode) {
+        height: 525px;
+      }
+
+      ::content > * {
+        flex: 1 0 auto;
+      }
+    </style>
+    <content></content>
+  </template>
+  
+</polymer-element><style>
+* /deep/ x-drag-handle{-webkit-user-select:none;box-sizing:border-box;display:block}* /deep/ x-drag-handle.horizontal-drag-handle{background-image:-webkit-gradient(linear,0 0,0 100%,from(#E5E5E5),to(#D1D1D1));border-bottom:1px solid #8e8e8e;border-top:1px solid white;cursor:ns-resize;height:7px;position:relative;z-index:10}* /deep/ x-drag-handle.vertical-drag-handle{background-image:-webkit-gradient(linear,0 0,100% 0,from(#E5E5E5),to(#D1D1D1));border-left:1px solid white;border-right:1px solid #8e8e8e;cursor:ew-resize;position:relative;width:7px;z-index:10}
+</style><polymer-element name="tr-ui-b-dropdown">
+  <template>
+    <style>
+    :host {
+      position: relative;
+      display: flex;
+    }
+    #outer {
+      display: flex;
+      flex: 0 0 auto;
+      padding: 1px 4px 1px 4px;
+      -webkit-user-select: none;
+      cursor: default;
+    }
+
+    #state {
+      display: flex;
+      flex: 0 0 auto;
+      margin-left: 2px;
+      margin-right: 0px;
+      flex: 0 0 auto;
+    }
+
+    #icon {
+      display: flex;
+      flex: 0 0 auto;
+      flex: 0 0 auto;
+    }
+    dialog {
+      position: absolute;
+      padding: 0;
+      border: 0;
+      margin: 0;
+    }
+    dialog::backdrop {
+      background: rgba(0,0,0,.05);
+    }
+
+    #dialog-frame {
+      background-color: #fff;
+      display: flex;
+      flex-direction: column;
+      flex: 1 1 auto;
+      padding: 6px;
+      border: 1px solid black;
+      -webkit-user-select: none;
+      cursor: default;
+    }
+    </style>
+    <tr-ui-b-toolbar-button id="outer" on-click="{{ onOuterClick_ }}" on-keydown="{{ onOuterKeyDown_ }}">
+      <div id="icon">⚙</div>
+      <div id="state">▾</div>
+    </tr-ui-b-toolbar-button>
+    <dialog id="dialog" on-cancel="{{ onDialogCancel_ }}" on-click="{{ onDialogClick_ }}">
+      <div id="dialog-frame">
+        <content></content>
+      </div>
+    </dialog>
+  </template>
+  
+</polymer-element><polymer-element name="tv-ui-b-hotkey-controller">
+  
+</polymer-element><polymer-element is="HTMLDivElement" name="tr-ui-b-info-bar">
+  <template>
+    <style>
+    :host {
+      align-items: center;
+      flex: 0 0 auto;
+      background-color: rgb(252, 235, 162);
+      border-bottom: 1px solid #A3A3A3;
+      border-left: 1px solid white;
+      border-right: 1px solid #A3A3A3;
+      border-top: 1px solid white;
+      display: flex;
+      height: 26px;
+      padding: 0 3px 0 3px;
+    }
+
+    :host(.info-bar-hidden) {
+      display: none;
+    }
+
+    #message { flex: 1 1 auto; }
+    </style>
+
+    <span id="message"></span>
+    <span id="buttons"></span>
+  </template>
+
+  
+</polymer-element><polymer-element is="HTMLUnknownElement" name="tr-ui-b-info-bar-group">
+  <template>
+    <style>
+    :host {
+      flex: 0 0 auto;
+      flex-direction: column;
+      display: flex;
+    }
+    </style>
+    <div id="messages"></div>
+  </template>
+
+  
+</polymer-element><polymer-element name="tr-ui-b-toolbar-button" noscript="">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      background-color: #f8f8f8;
+      border: 1px solid rgba(0, 0, 0, 0.5);
+      color: rgba(0,0,0,0.8);
+      justify-content: center;
+      align-self: stretch;
+      min-width: 23px;
+    }
+
+    :host(:hover) {
+      background-color: rgba(255, 255, 255, 1.0);
+      border-color: rgba(0, 0, 0, 0.8);
+      box-shadow: 0 0 .05em rgba(0, 0, 0, 0.4);
+      color: rgba(0, 0, 0, 1);
+    }
+
+    #aligner {
+      display: flex;
+      flex: 0 0 auto;
+      align-self: center;
+    }
+    </style>
+    <div id="aligner">
+      <content></content>
+    </div>
+  </template>
+</polymer-element><polymer-element name="tr-ui-b-mouse-mode-icon">
+  <template>
+    <style>
+    :host {
+      display: block;
+      background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAChCAYAAACbBNzvAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABV0RVh0Q3JlYXRpb24gVGltZQA3LzE2LzEzRNEKUwAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAA9aSURBVHic7V1rTFvl//+UrgUmZWMpbLa6cLErwpYxkqLGkjAG88WSbmumGUllvlmAJctMRtybvlHrLXiJUekMIZuYSCL5gS+EuLIXGEGjqCsllCEW6xQECgzWG7S05/+C/zkp9LTn0gsL6ych9JzznOdzPj19Luf5PN/nCN59913ixRdfRFdXFxLx/2GDgCAIYmpqCoWFhUjE/4cNae+99x4AIFH/Hzak7nDqDu+wOyyw2WzEdl9EMpG23ReQbKQE73Q8coJ3bfcFWK1W/Pbbb/D7/UhLi/37DwaDEIvFKC8vR0lJSdjxbRVstVoxPDyMxx9/HAUFBcjMzIRAIOCdXzAYhNvtht1ux/DwMACEid5WwSMjI3jyySdRXFwMsVgMoVAYk2CCIJCZmYns7GyMjo5iZGQkPoKXl5exd+9e3hdGIhgMIj8/H5mZmRCJRIyCyQ5NJBAEgUAgAKFQiIKCAiwsLISl4VxoHA4H+vv74Xa7uZ4aBqFQiOzsbIhEIojFYojFYohEItq/8fFxXLlyBUtLSxHThOaxZ88eCIXC2AWPj48DAH799deYBaelpUEoFLL6++qrrwAAH3zwAav0YrGYthLkJHh6ehpzc3MAgPn5eUxPT8csWiAQMJbboaEhmM1mAIDFYsHQ0BDvPDkJtlgsYdt+v59LFrxw/fr1sG2Xy8UrL06C6+vrw7bFYjEvYi747rvvwrYlEgmvvDjV0g6HI+p2ohBP3qh32OFwoLe3l1VGvb29sNvtvC8kFCMjI9DpdKzS6nQ6mEwm1nnTPg/7/X6MjY1hcnKS/VX+P/bu3YuysjLk5uYypv36669x8uRJZGRkQCQSwev1oqOjAz09PZx5CwsLcenSJRw+fBh+vx+rq6swmUx46aWXNqWjvcMDAwO8xAIbnZKBgQFeNXhzczMvscBGp6S5uRk//vhj1HS0grVaLYqLi3kRy+Vy1NXVRe0RRcKNGzeg0Wh48apUKnR1daG6ujpqOtpKy+VyQa1Wo6SkBLdv38aFCxeoY5988gn1+fLly9TnL774ApWVlXjiiSfgdDqxtrbG+aJ9Ph/0ej3OnDkDvV6PW7duUceOHDlCfR4dHaU+v/DCC7h27RrUajWcTidWV1ejctAKJggCKysryMzMhE6nw+zsLO3Joft1Oh0ePHiApaUlduqi8BYVFaGvr48Vb19fHyfeqM2Sz+dj3QTEs4lKJC+njsfWJoptkxUrtjZRbJssOnASXFtbG3U7UXjrrbeibnMBJ8FZWVkoKysDABQUFCArK4s3MRcoFArqrlZXV0OhUPDOi5Ngn8+Hw4cPQyqV4tlnn4XP5+NNTIIgmH0An8+HV155BUqlEq+++ior3kAgQLuf84jH2toajh8/jvX1da6n0sLj8SAjI4MxHUEQ+PTTT1nlSRAEHjx4QHtsW8e0RCIR7HY79uzZE/GOcEUgEEAgEMDff/8NkUgUdnxbBR85cgRmsxkCgQD5+fkRh2XYIhAI4P79+5iamoLD4cCxY8fC0myr4KeeegoCgQBWqxVzc3NIS0uLedQyGAxi165dKC8vR1FRUVialHu405ESvNPxyAlOuYfJRMo9fFjdw3iBq3vIBDbu4bYK3uoextKtJEH2yWNyD8nyEG8wuYcffvgha3cxru6h3W5Hf39/QoyzaE6fyWRCQ0MDZ+MsLu7h8vIyent7sby8zIk8VkxNTUGn08Fms8UlP04Nn9/vR39/f9w8JLZwu91obGzk5CFFAq+Wfnh4mDKok4mWlha0trbGlAfvrs3k5CQGBgaSYoiHoqenB1evXk2OIb4VDocDJpMp6eXaYrGgsbGRV7mOufPq8XgwMDCQ9HI9NzeHq1evci7XvDseUqkUWq0W6enpCAaDcDqd8Hq9fLNjDaVSiRs3bkAikfDi5XSHxWIxampqAAALCwsYGhrC7Ows5ufnEypWIpHAYDAAACYmJnD9+nXevJwEnzp1CjKZDBUVFQCAsbGxpJTfjz76CFVVVWhqagIAdHR08G6XWQuuqanB7t274fV6UVpaiuzsbAAbTzyJhMFggEKhgNfrRX19PWQyGQDAaDTyyo+V4JqaGshkMsricLlcOH78OICNCWp8p0cwwWAwoKqqahPvG2+8AWDji+7u7uacJyvBMpksrKxkZWVR0yLGxsY4E7NBVVVVGK9CoaCmRXR0dHDOk5VguorB5/OhoqICYrE4YZ2PSLxXrlyBRCLhNcE1pufh1dVVXLx4EWlpaRGnJzCBjXtId87g4GBU3ri5h1uJ5+fnY8mCtXvIhTflHoYg5R4mEyn3MAl45KyWlOCdjkdOcMo9TCZS7mHKPeSGhLmH5LBOrAGXXN1DcliHrgdFgsk95CzYbrfDbDbD7/ejrKwstpmtNO5hJJhMJrS2tsLtdqOpqQlarTZi2mjuIWvBfr8fZrN50/iz2WzG9PQ0nn/+edonEzZgij10uVwwGo2bxp+NRiOGhobw+uuv005hjtk9JENz6AbbyWCuRESp2Ww2NDc30w62WywW6HQ6zoOIrO5wbm4uzp8/j5WVFXR2dm46VldXh3379mF5eTku86dDUVxcjK6uLthstrClqrq6unDo0CHOvKwE+/1+LC4uUqG0oZiYmIhaicQCkvfu3bthxwYGBnhVmpy6NnSD7kxxQvEA3Zo+fIsQJ8F040j379/nRcwFdF4037FwToLphkUXFxd5EXMB3chkUgQ7nc6wfT6fL+Gm+H///Re2z+Vy8TLFGSut/v5+RsPsm2++AbDR84pXLFNDQwPjelxnz54FsBFK+/nnn7PKl/EOa7VaVmHvYrE4au+HK27evMkq7F0ikeDmzZus82UU7HK5qG8yGs6ePct73gUdfD4f2tvbGdO1t7dzaocZBRMEAaFQSBnhdKipqYFQKORlm0TjzcvLo4xwOhgMBuTl5XHiZVVp+f1+yGQy2iDq4uJiyGSyhFRcfr8fVVVVtEHUGo0GVVVVnHlZ19JerxdqtRpSqZTaJ5VKoVarEzrdwev1Qq/XQ6lUUvuUSiX0ej0vXk7N0srKCjQaDbXmjUajwcrKCmfSULD5Oa6srKCtrQ0SiQQSiQRtbW2MvHFzD0MrsXhUUmzdw9BKjKmSiqt7SBBE3Conru4hOa8kWqBnyj3cgl0EQcQ0cMYWW3kIgkiKe7iVV2C1Won09PSYxLCB1+tFZmYmtb22tobt4E1LBimATaQAkiKWjveR85ZSgnc6Uu5hMpFyD1PuITekYg/ZxB52dXXFTMo2n1D38NSpU7zjDEP/yHzisnJpIsBm5dJ45rntgpONuITTJirctqWlJabjdGAUvNUEp0NouxcvtLa2MgZhmUwmzqKjCrbb7aw9HC5pmWAymVivb2kymTgFe0RslrbeNTa1rtlshkgkQn5+PusL2Iqtd42NdWM0GpGVlYWTJ08ypo14h/nGI8Uax8Q3XJbteREFV1ZW8iLmex6Ja9euJfS8iD9puVyOmpoa3L59G8DmVUq3glzNlAzoimVgvrq6GmlpadDr9QA2r1K6FeRqpmRAFxveiIK9Xi8VZ/jLL78whulUVFTELJbkJeMMjUYjI29TUxNrsQBDX5qMM4w0qE2iuLgYpaWlcXMPyThDphWMNRoN6uvrOfGyskvVanXUNGq1Oq5WKclL/qwjQa/Xc+Zl1dNi8nFi9ZeSyZvqS0erjbmAbT6kT7X1lQp8QeYTyasKE8w3aJJvPh6PBwRBYGZmJi68MzMzqdjDUDx67mEsFxwrUrGHSUCqWdrpSAne6dix7uFzzz1HW0s/FO7h/v37UVBQgMceeyxm99DlcsFut2NwcBACgSDsnTHb7h4ePHgQxcXFcTPTMjIyIJFIcOfOHfz+++8Pl2DSPSTftxQv93DXrl0oKirCnTt3wtIwFhq62aputxtms5maCR8pHROEQiEkEgntew/X1tbC3mu4tLSE9vZ2nD9/njZd6Pn79u3jHoo3OTmJsbExnDlzBsDGWLXdbqcNoent7YVCocChQ4dYh+VFij3s7u5GR0cH9YWaTCbcunVr0yMkmfbChQvQarXQarVUWF4wGER6ejp7wdPT0zCbzfB4PJv2R7NT/H4/rFYrJicnUVZWxnowPtTpGxoagtFoDAsIi2anuN1ufPnll+ju7salS5dw4sQJKk+64hH2FTgcDgwPD4eJZQu/3w+bzcZ5JSSLxYL333+fNvqNDdxuN3p6ehjPDxMsl8tjjkw5ceIENfOVLVQqFd58882YeA0GA7WiWiSECfb5fPjpp58AbKyBx/bCpVIp6urqAADff/895wf6tbU1fPbZZwCAjz/+mPHCSSiVSsr3eueddxh5aWtpMrwuJyeH9cuczp07R5UZvktO/fnnnwCAY8eOoa+vj9U5nZ2d1CsH2fhaUZulwcFB1kGNi4uLjK/gYwuDwcCJ9+2332add9RmyW63w+12Q6FQIC8vD5cvX8bCwgI19VcqlcJms8HhcGBycjJuSz6aTCbMzs5Cq9Xi6NGjGB0dxcTEBJxOJyQSCZRKJUZGRjAyMoL//e9/jBFsoaAVLJfLKZvD4XBQ37ZEItlUph0OB238gVwu5ySQhEqlopo+i8VCtbsymWxTmb579y6t46BSqRg5aAXX1tbi22+/DZvY5XQ6aQMuQyGVSlFbW8trgb6WlhY0NDRgYmJi0/6ZmRnGYVylUomWlhbGeGbaMuzxeKDRaKhVDdkgOzsblZWVOHfuHO82fH19HW1tbWhqamL9ul2ZTIbXXnsNnZ2drN7yFfFFjy6XC6WlpVCpVFhaWsK///5LVfnz8/PIy8sDAOzevRu5ubnIycmBx+OJKZ6YIAj4fD7U19ejsbERf/zxB4aHhykrdHx8HE8//TQAYP/+/VAqlVAoFJx4I1ZapGiyrBw4cAD37t2DXC7HgQMHAGx0QXNycrC+vh63VR5Cecnw3J6eHqhUKpSXlwPY6OI+88wzALiHxnN6PPz555/D9h08eJATIR/Qzd9gE/FKh9SYFlvI5XKqPMUCrlFuKpUKp0+fZkwXDAZp93MSLBaLUVJSgqNHjyIjIwNerzfmOR0ul4sx9lAikeD06dN4+eWXIZVKGXnj5h5evHgRXq8XHo+Hd9MTCpFIhHv37iEnJydqp/+HH36A1+uFy+VirKTi6h7Gug7tVpDuIUEQKCwsjOge/vPPP6zyCwQCWF5exl9//YX5+Xla93DbzTSbzQar1Yr19fW4uoclJSUp9xB4BJullOCdjkdO8P8BGCQ0hnF1DxUAAAAASUVORK5CYII=);
+      width: 27px;
+      height: 30px;
+    }
+    :host.active {
+      cursor: auto;
+    }
+    </style>
+  </template>
+  
+</polymer-element><polymer-element name="tr-ui-b-mouse-mode-selector">
+  <template>
+    <style>
+    :host {
+
+      -webkit-user-drag: element;
+      -webkit-user-select: none;
+
+      background: #DDD;
+      border: 1px solid #BBB;
+      border-radius: 4px;
+      box-shadow: 0 1px 2px rgba(0,0,0,0.2);
+      left: calc(100% - 120px);
+      position: absolute;
+      top: 100px;
+      user-select: none;
+      width: 29px;
+      z-index: 20;
+    }
+
+    .drag-handle {
+      background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAChCAYAAACbBNzvAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABV0RVh0Q3JlYXRpb24gVGltZQA3LzE2LzEzRNEKUwAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAA9aSURBVHic7V1rTFvl//+UrgUmZWMpbLa6cLErwpYxkqLGkjAG88WSbmumGUllvlmAJctMRtybvlHrLXiJUekMIZuYSCL5gS+EuLIXGEGjqCsllCEW6xQECgzWG7S05/+C/zkp9LTn0gsL6ych9JzznOdzPj19Luf5PN/nCN59913ixRdfRFdXFxLx/2GDgCAIYmpqCoWFhUjE/4cNae+99x4AIFH/Hzak7nDqDu+wOyyw2WzEdl9EMpG23ReQbKQE73Q8coJ3bfcFWK1W/Pbbb/D7/UhLi/37DwaDEIvFKC8vR0lJSdjxbRVstVoxPDyMxx9/HAUFBcjMzIRAIOCdXzAYhNvtht1ux/DwMACEid5WwSMjI3jyySdRXFwMsVgMoVAYk2CCIJCZmYns7GyMjo5iZGQkPoKXl5exd+9e3hdGIhgMIj8/H5mZmRCJRIyCyQ5NJBAEgUAgAKFQiIKCAiwsLISl4VxoHA4H+vv74Xa7uZ4aBqFQiOzsbIhEIojFYojFYohEItq/8fFxXLlyBUtLSxHThOaxZ88eCIXC2AWPj48DAH799deYBaelpUEoFLL6++qrrwAAH3zwAav0YrGYthLkJHh6ehpzc3MAgPn5eUxPT8csWiAQMJbboaEhmM1mAIDFYsHQ0BDvPDkJtlgsYdt+v59LFrxw/fr1sG2Xy8UrL06C6+vrw7bFYjEvYi747rvvwrYlEgmvvDjV0g6HI+p2ohBP3qh32OFwoLe3l1VGvb29sNvtvC8kFCMjI9DpdKzS6nQ6mEwm1nnTPg/7/X6MjY1hcnKS/VX+P/bu3YuysjLk5uYypv36669x8uRJZGRkQCQSwev1oqOjAz09PZx5CwsLcenSJRw+fBh+vx+rq6swmUx46aWXNqWjvcMDAwO8xAIbnZKBgQFeNXhzczMvscBGp6S5uRk//vhj1HS0grVaLYqLi3kRy+Vy1NXVRe0RRcKNGzeg0Wh48apUKnR1daG6ujpqOtpKy+VyQa1Wo6SkBLdv38aFCxeoY5988gn1+fLly9TnL774ApWVlXjiiSfgdDqxtrbG+aJ9Ph/0ej3OnDkDvV6PW7duUceOHDlCfR4dHaU+v/DCC7h27RrUajWcTidWV1ejctAKJggCKysryMzMhE6nw+zsLO3Joft1Oh0ePHiApaUlduqi8BYVFaGvr48Vb19fHyfeqM2Sz+dj3QTEs4lKJC+njsfWJoptkxUrtjZRbJssOnASXFtbG3U7UXjrrbeibnMBJ8FZWVkoKysDABQUFCArK4s3MRcoFArqrlZXV0OhUPDOi5Ngn8+Hw4cPQyqV4tlnn4XP5+NNTIIgmH0An8+HV155BUqlEq+++ior3kAgQLuf84jH2toajh8/jvX1da6n0sLj8SAjI4MxHUEQ+PTTT1nlSRAEHjx4QHtsW8e0RCIR7HY79uzZE/GOcEUgEEAgEMDff/8NkUgUdnxbBR85cgRmsxkCgQD5+fkRh2XYIhAI4P79+5iamoLD4cCxY8fC0myr4KeeegoCgQBWqxVzc3NIS0uLedQyGAxi165dKC8vR1FRUVialHu405ESvNPxyAlOuYfJRMo9fFjdw3iBq3vIBDbu4bYK3uoextKtJEH2yWNyD8nyEG8wuYcffvgha3cxru6h3W5Hf39/QoyzaE6fyWRCQ0MDZ+MsLu7h8vIyent7sby8zIk8VkxNTUGn08Fms8UlP04Nn9/vR39/f9w8JLZwu91obGzk5CFFAq+Wfnh4mDKok4mWlha0trbGlAfvrs3k5CQGBgaSYoiHoqenB1evXk2OIb4VDocDJpMp6eXaYrGgsbGRV7mOufPq8XgwMDCQ9HI9NzeHq1evci7XvDseUqkUWq0W6enpCAaDcDqd8Hq9fLNjDaVSiRs3bkAikfDi5XSHxWIxampqAAALCwsYGhrC7Ows5ufnEypWIpHAYDAAACYmJnD9+nXevJwEnzp1CjKZDBUVFQCAsbGxpJTfjz76CFVVVWhqagIAdHR08G6XWQuuqanB7t274fV6UVpaiuzsbAAbTzyJhMFggEKhgNfrRX19PWQyGQDAaDTyyo+V4JqaGshkMsricLlcOH78OICNCWp8p0cwwWAwoKqqahPvG2+8AWDji+7u7uacJyvBMpksrKxkZWVR0yLGxsY4E7NBVVVVGK9CoaCmRXR0dHDOk5VguorB5/OhoqICYrE4YZ2PSLxXrlyBRCLhNcE1pufh1dVVXLx4EWlpaRGnJzCBjXtId87g4GBU3ri5h1uJ5+fnY8mCtXvIhTflHoYg5R4mEyn3MAl45KyWlOCdjkdOcMo9TCZS7mHKPeSGhLmH5LBOrAGXXN1DcliHrgdFgsk95CzYbrfDbDbD7/ejrKwstpmtNO5hJJhMJrS2tsLtdqOpqQlarTZi2mjuIWvBfr8fZrN50/iz2WzG9PQ0nn/+edonEzZgij10uVwwGo2bxp+NRiOGhobw+uuv005hjtk9JENz6AbbyWCuRESp2Ww2NDc30w62WywW6HQ6zoOIrO5wbm4uzp8/j5WVFXR2dm46VldXh3379mF5eTku86dDUVxcjK6uLthstrClqrq6unDo0CHOvKwE+/1+LC4uUqG0oZiYmIhaicQCkvfu3bthxwYGBnhVmpy6NnSD7kxxQvEA3Zo+fIsQJ8F040j379/nRcwFdF4037FwToLphkUXFxd5EXMB3chkUgQ7nc6wfT6fL+Gm+H///Re2z+Vy8TLFGSut/v5+RsPsm2++AbDR84pXLFNDQwPjelxnz54FsBFK+/nnn7PKl/EOa7VaVmHvYrE4au+HK27evMkq7F0ikeDmzZus82UU7HK5qG8yGs6ePct73gUdfD4f2tvbGdO1t7dzaocZBRMEAaFQSBnhdKipqYFQKORlm0TjzcvLo4xwOhgMBuTl5XHiZVVp+f1+yGQy2iDq4uJiyGSyhFRcfr8fVVVVtEHUGo0GVVVVnHlZ19JerxdqtRpSqZTaJ5VKoVarEzrdwev1Qq/XQ6lUUvuUSiX0ej0vXk7N0srKCjQaDbXmjUajwcrKCmfSULD5Oa6srKCtrQ0SiQQSiQRtbW2MvHFzD0MrsXhUUmzdw9BKjKmSiqt7SBBE3Conru4hOa8kWqBnyj3cgl0EQcQ0cMYWW3kIgkiKe7iVV2C1Won09PSYxLCB1+tFZmYmtb22tobt4E1LBimATaQAkiKWjveR85ZSgnc6Uu5hMpFyD1PuITekYg/ZxB52dXXFTMo2n1D38NSpU7zjDEP/yHzisnJpIsBm5dJ45rntgpONuITTJirctqWlJabjdGAUvNUEp0NouxcvtLa2MgZhmUwmzqKjCrbb7aw9HC5pmWAymVivb2kymTgFe0RslrbeNTa1rtlshkgkQn5+PusL2Iqtd42NdWM0GpGVlYWTJ08ypo14h/nGI8Uax8Q3XJbteREFV1ZW8iLmex6Ja9euJfS8iD9puVyOmpoa3L59G8DmVUq3glzNlAzoimVgvrq6GmlpadDr9QA2r1K6FeRqpmRAFxveiIK9Xi8VZ/jLL78whulUVFTELJbkJeMMjUYjI29TUxNrsQBDX5qMM4w0qE2iuLgYpaWlcXMPyThDphWMNRoN6uvrOfGyskvVanXUNGq1Oq5WKclL/qwjQa/Xc+Zl1dNi8nFi9ZeSyZvqS0erjbmAbT6kT7X1lQp8QeYTyasKE8w3aJJvPh6PBwRBYGZmJi68MzMzqdjDUDx67mEsFxwrUrGHSUCqWdrpSAne6dix7uFzzz1HW0s/FO7h/v37UVBQgMceeyxm99DlcsFut2NwcBACgSDsnTHb7h4ePHgQxcXFcTPTMjIyIJFIcOfOHfz+++8Pl2DSPSTftxQv93DXrl0oKirCnTt3wtIwFhq62aputxtms5maCR8pHROEQiEkEgntew/X1tbC3mu4tLSE9vZ2nD9/njZd6Pn79u3jHoo3OTmJsbExnDlzBsDGWLXdbqcNoent7YVCocChQ4dYh+VFij3s7u5GR0cH9YWaTCbcunVr0yMkmfbChQvQarXQarVUWF4wGER6ejp7wdPT0zCbzfB4PJv2R7NT/H4/rFYrJicnUVZWxnowPtTpGxoagtFoDAsIi2anuN1ufPnll+ju7salS5dw4sQJKk+64hH2FTgcDgwPD4eJZQu/3w+bzcZ5JSSLxYL333+fNvqNDdxuN3p6ehjPDxMsl8tjjkw5ceIENfOVLVQqFd58882YeA0GA7WiWiSECfb5fPjpp58AbKyBx/bCpVIp6urqAADff/895wf6tbU1fPbZZwCAjz/+mPHCSSiVSsr3eueddxh5aWtpMrwuJyeH9cuczp07R5UZvktO/fnnnwCAY8eOoa+vj9U5nZ2d1CsH2fhaUZulwcFB1kGNi4uLjK/gYwuDwcCJ9+2332add9RmyW63w+12Q6FQIC8vD5cvX8bCwgI19VcqlcJms8HhcGBycjJuSz6aTCbMzs5Cq9Xi6NGjGB0dxcTEBJxOJyQSCZRKJUZGRjAyMoL//e9/jBFsoaAVLJfLKZvD4XBQ37ZEItlUph0OB238gVwu5ySQhEqlopo+i8VCtbsymWxTmb579y6t46BSqRg5aAXX1tbi22+/DZvY5XQ6aQMuQyGVSlFbW8trgb6WlhY0NDRgYmJi0/6ZmRnGYVylUomWlhbGeGbaMuzxeKDRaKhVDdkgOzsblZWVOHfuHO82fH19HW1tbWhqamL9ul2ZTIbXXnsNnZ2drN7yFfFFjy6XC6WlpVCpVFhaWsK///5LVfnz8/PIy8sDAOzevRu5ubnIycmBx+OJKZ6YIAj4fD7U19ejsbERf/zxB4aHhykrdHx8HE8//TQAYP/+/VAqlVAoFJx4I1ZapGiyrBw4cAD37t2DXC7HgQMHAGx0QXNycrC+vh63VR5Cecnw3J6eHqhUKpSXlwPY6OI+88wzALiHxnN6PPz555/D9h08eJATIR/Qzd9gE/FKh9SYFlvI5XKqPMUCrlFuKpUKp0+fZkwXDAZp93MSLBaLUVJSgqNHjyIjIwNerzfmOR0ul4sx9lAikeD06dN4+eWXIZVKGXnj5h5evHgRXq8XHo+Hd9MTCpFIhHv37iEnJydqp/+HH36A1+uFy+VirKTi6h7Gug7tVpDuIUEQKCwsjOge/vPPP6zyCwQCWF5exl9//YX5+Xla93DbzTSbzQar1Yr19fW4uoclJSUp9xB4BJullOCdjkdO8P8BGCQ0hnF1DxUAAAAASUVORK5CYII=) 2px 3px no-repeat;
+      background-repeat: no-repeat;
+      border-bottom: 1px solid #BCBCBC;
+      cursor: move;
+      display: block;
+      height: 13px;
+      width: 27px;
+    }
+
+    .tool-button {
+      background-position: center center;
+      background-repeat: no-repeat;
+      border-bottom: 1px solid #BCBCBC;
+      border-top: 1px solid #F1F1F1;
+      cursor: pointer;
+    }
+
+    .buttons > .tool-button:last-child {
+      border-bottom: none;
+    }
+
+    </style>
+    <div class="drag-handle"></div>
+    <div class="buttons">
+    </div>
+  </template>
+</polymer-element><style>
+.track-button{background-color:rgba(255,255,255,0.5);border:1px solid rgba(0,0,0,0.1);color:rgba(0,0,0,0.2);font-size:10px;height:12px;text-align:center;width:12px}.track-button:hover{background-color:rgba(255,255,255,1.0);border:1px solid rgba(0,0,0,0.5);box-shadow:0 0 .05em rgba(0,0,0,0.4);color:rgba(0,0,0,1)}.track-close-button{left:2px;position:absolute;top:2px}.track-collapse-button{left:3px;position:absolute;top:2px}
+</style><style>
+.drawing-container{-webkit-box-flex:1;display:inline;overflow:auto;overflow-x:hidden;position:relative}.drawing-container-canvas{-webkit-box-flex:1;display:block;pointer-events:none;position:absolute;top:0}
+</style><polymer-element name="tr-ui-heading">
+  <template>
+    <style>
+    :host {
+      background-color: rgb(243, 245, 247);
+      border-right: 1px solid #8e8e8e;
+      display: block;
+      height: 100%;
+      margin: 0;
+      padding: 0 5px 0 0;
+    }
+
+    heading {
+      display: block;
+      overflow-x: hidden;
+      text-align: left;
+      text-overflow: ellipsis;
+      white-space: nowrap;
+    }
+
+    #arrow {
+      -webkit-flex: 0 0 auto;
+      font-family: sans-serif;
+      margin-left: 5px;
+      margin-right: 5px;
+      width: 8px;
+    }
+
+    #link, #heading_content {
+      display: none;
+    }
+    </style>
+    <heading id="heading" on-click="{{onHeadingDivClicked_}}">
+      <span id="arrow"></span>
+      <span id="heading_content"></span>
+      <tr-ui-a-analysis-link id="link"></tr-ui-a-analysis-link>
+    </heading>
+  </template>
+
+  
+</polymer-element><style>
+.letter-dot-track {
+  height: 18px;
+}
+</style><style>
+.chart-track {
+  height: 30px;
+  position: relative;
+}
+</style><style>
+.power-series-track {
+  height: 90px;
+}
+</style><style>
+.spacing-track{height:4px}
+</style><style>
+.object-instance-track{height:18px}
+</style><style>
+.rect-track{height:18px}
+</style><style>
+.thread-track{-webkit-box-orient:vertical;display:-webkit-box;position:relative}
+</style><style>
+.process-track-header{-webkit-flex:0 0 auto;background-image:-webkit-gradient(linear,0 0,100% 0,from(#E5E5E5),to(#D1D1D1));border-bottom:1px solid #8e8e8e;border-top:1px solid white;font-size:75%}.process-track-name:before{content:'\25B8';padding:0 5px}.process-track-base.expanded .process-track-name:before{content:'\25BE'}
+</style><style>
+.model-track {
+  -webkit-box-flex: 1;
+}
+</style><style>
+.ruler-track{height:12px}.ruler-track.tall-mode{height:30px}
+</style><polymer-element name="tr-ui-timeline-track-view">
+  <template>
+    <style>
+    :host {
+      -webkit-box-orient: vertical;
+      display: -webkit-box;
+      position: relative;
+    }
+
+    :host ::content * {
+      -webkit-user-select: none;
+      cursor: default;
+    }
+
+    #drag_box {
+      background-color: rgba(0, 0, 255, 0.25);
+      border: 1px solid rgb(0, 0, 96);
+      font-size: 75%;
+      position: fixed;
+    }
+
+    #hint_text {
+      position: absolute;
+      bottom: 6px;
+      right: 6px;
+      font-size: 8pt;
+    }
+    </style>
+    <content></content>
+
+    <div id="drag_box"></div>
+    <div id="hint_text"></div>
+
+    <tv-ui-b-hotkey-controller id="hotkey_controller">
+    </tv-ui-b-hotkey-controller>
+  </template>
+
+  
+</polymer-element><polymer-element name="tr-ui-find-control">
+  <template>
+    <style>
+      :host {
+        -webkit-user-select: none;
+        display: -webkit-flex;
+        position: relative;
+      }
+      input {
+        -webkit-user-select: auto;
+        background-color: #f8f8f8;
+        border: 1px solid rgba(0, 0, 0, 0.5);
+        box-sizing: border-box;
+        margin: 0;
+        padding: 0;
+        width: 170px;
+      }
+      input:focus {
+        background-color: white;
+      }
+      tr-ui-b-toolbar-button {
+        border-left: none;
+        margin: 0;
+      }
+      #hitCount {
+        left: 0;
+        opacity: 0.25;
+        pointer-events: none;
+        position: absolute;
+        text-align: right;
+        top: 2px;
+        width: 167px;
+        z-index: 1;
+      }
+      #spinner {
+        visibility: hidden;
+        width: 8px;
+        height: 8px;
+        left: 154px;
+        pointer-events: none;
+        position: absolute;
+        top: 4px;
+        z-index: 1;
+
+        border: 2px solid transparent;
+        border-bottom: 2px solid rgba(0, 0, 0, 0.5);
+        border-right: 2px solid rgba(0, 0, 0, 0.5);
+        border-radius: 50%;
+
+        animation: spin 1s linear infinite;
+      }
+      @keyframes spin { 100% { transform: rotate(360deg); } }
+    </style>
+
+    <input id="filter" on-blur="{{ filterBlur }}" on-focus="{{ filterFocus }}" on-input="{{ filterTextChanged }}" on-keydown="{{ filterKeyDown }}" on-mouseup="{{ filterMouseUp }}" type="text"/>
+    <div id="spinner"></div>
+    <tr-ui-b-toolbar-button on-click="{{ findPrevious }}">
+      ←
+    </tr-ui-b-toolbar-button>
+    <tr-ui-b-toolbar-button on-click="{{ findNext }}">
+      →
+    </tr-ui-b-toolbar-button>
+    <div id="hitCount">0 of 0</div>
+  </template>
+
+  
+</polymer-element><polymer-element name="tr-ui-scripting-control">
+  <template>
+    <style>
+      :host {
+        flex: 1 1 auto;
+      }
+      .root {
+        font-family: monospace;
+        cursor: text;
+
+        padding: 2px;
+        margin: 2px;
+        border: 1px solid rgba(0, 0, 0, 0.5);
+        background: white;
+
+        height: 100px;
+        overflow-y: auto;
+
+        transition-property: opacity, height, padding, margin;
+        transition-duration: .2s;
+        transition-timing-function: ease-out;
+      }
+      .hidden {
+        margin-top: 0px;
+        margin-bottom: 0px;
+        padding-top: 0px;
+        padding-bottom: 0px;
+        height: 0px;
+        opacity: 0;
+      }
+      .focused {
+        outline: auto 5px -webkit-focus-ring-color;
+      }
+      #history {
+        -webkit-user-select: text;
+        color: #777;
+      }
+      #prompt {
+        -webkit-user-select: text;
+        -webkit-user-modify: read-write-plaintext-only;
+        text-overflow: clip !important;
+        text-decoration: none !important;
+      }
+      #prompt:focus {
+        outline: none;
+      }
+      #prompt br {
+        display: none;
+      }
+      #prompt ::before {
+        content: ">";
+        color: #468;
+      }
+    </style>
+
+    <div class="root hidden" id="root" on-focus="{{ onConsoleFocus }}" tabindex="0">
+      <div id="history"></div>
+      <div id="prompt" on-blur="{{ onConsoleBlur }}" on-keydown="{{ promptKeyDown }}" on-keypress="{{ promptKeyPress }}">
+  
+
+  
+
+</div></div></template></polymer-element><polymer-element name="tr-ui-side-panel">
+  
+</polymer-element><polymer-element is="HTMLUnknownElement" name="tr-ui-side-panel-container">
+  <template>
+    <style>
+    :host {
+      align-items: stretch;
+      display: -webkit-flex;
+    }
+
+    :host([expanded]) > active-panel-container {
+      -webkit-flex: 1 1 auto;
+      border-left: 1px solid black;
+      display: -webkit-flex;
+    }
+
+    :host(:not([expanded])) > active-panel-container {
+      display: none;
+    }
+
+    active-panel-container {
+      display: flex;
+    }
+
+    tab-strip {
+      -webkit-flex: 0 0 auto;
+      -webkit-flex-direction: column;
+      -webkit-user-select: none;
+      background-color: rgb(236, 236, 236);
+      border-left: 1px solid black;
+      cursor: default;
+      display: -webkit-flex;
+      min-width: 18px; /* workaround for flexbox and writing-mode mixing bug */
+      padding: 10px 0 10px 0;
+      font-size: 12px;
+    }
+
+    tab-strip > tab-strip-label {
+      -webkit-writing-mode: vertical-rl;
+      display: inline;
+      margin-right: 1px;
+      min-height: 20px;
+      padding: 15px 3px 15px 1px;
+    }
+
+    tab-strip >
+        tab-strip-label:not([enabled]) {
+      color: rgb(128, 128, 128);
+    }
+
+    tab-strip > tab-strip-label[selected] {
+      background-color: white;
+      border: 1px solid rgb(163, 163, 163);
+      border-left: none;
+      padding: 14px 2px 14px 1px;
+    }
+    </style>
+
+    <active-panel-container id="active_panel_container">
+    </active-panel-container>
+    <tab-strip id="tab_strip"></tab-strip>
+  </template>
+
+  
+</polymer-element><polymer-element name="tr-ui-timeline-view-help-overlay">
+  <template>
+    <style>
+    :host {
+      -webkit-flex: 1 1 auto;
+      -webkit-flex-direction: row;
+      display: -webkit-flex;
+      width: 700px;
+    }
+    .column {
+      width: 50%;
+    }
+    h2 {
+      font-size: 1.2em;
+      margin: 0;
+      margin-top: 5px;
+      text-align: center;
+    }
+    h3 {
+      margin: 0;
+      margin-left: 126px;
+      margin-top: 10px;
+    }
+    .pair {
+      -webkit-flex: 1 1 auto;
+      -webkit-flex-direction: row;
+      display: -webkit-flex;
+    }
+    .command {
+      font-family: monospace;
+      margin-right: 5px;
+      text-align: right;
+      width: 150px;
+    }
+    .action {
+      font-size: 0.9em;
+      text-align: left;
+      width: 200px;
+    }
+    tr-ui-b-mouse-mode-icon {
+      border: 1px solid #888;
+      border-radius: 3px;
+      box-shadow: inset 0 0 2px rgba(0,0,0,0.3);
+      display: inline-block;
+      margin-right: 1px;
+      position: relative;
+      top: 4px;
+    }
+    .mouse-mode-icon.pan-mode {
+      background-position: -1px -11px;
+    }
+    .mouse-mode-icon.select-mode {
+      background-position: -1px -41px;
+    }
+    .mouse-mode-icon.zoom-mode {
+      background-position: -1px -71px;
+    }
+    .mouse-mode-icon.timing-mode {
+      background-position: -1px -101px;
+    }
+    </style>
+    <div class="column left">
+      <h2>Navigation</h2>
+      <div class="pair">
+        <div class="command">w/s</div>
+        <div class="action">Zoom in/out (+shift: faster)</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">a/d</div>
+        <div class="action">Pan left/right (+shift: faster)</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">→/shift-TAB</div>
+        <div class="action">Select previous event</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">←/TAB</div>
+        <div class="action">Select next event</div>
+      </div>
+
+      <h2>Mouse Controls</h2>
+      <div class="pair">
+        <div class="command">click</div>
+        <div class="action">Select event</div>
+      </div>
+      <div class="pair">
+        <div class="command">alt-mousewheel</div>
+        <div class="action">Zoom in/out</div>
+      </div>
+
+      <h3>
+        <tr-ui-b-mouse-mode-icon modename="SELECTION"></tr-ui-b-mouse-mode-icon>
+        Select mode
+      </h3>
+      <div class="pair">
+        <div class="command">drag</div>
+        <div class="action">Box select</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">double click</div>
+        <div class="action">Select all events with same title</div>
+      </div>
+
+      <h3>
+        <tr-ui-b-mouse-mode-icon modename="PANSCAN"></tr-ui-b-mouse-mode-icon>
+        Pan mode
+      </h3>
+      <div class="pair">
+        <div class="command">drag</div>
+        <div class="action">Pan the view</div>
+      </div>
+
+      <h3>
+        <tr-ui-b-mouse-mode-icon modename="ZOOM"></tr-ui-b-mouse-mode-icon>
+        Zoom mode
+      </h3>
+      <div class="pair">
+        <div class="command">drag</div>
+        <div class="action">Zoom in/out by dragging up/down</div>
+      </div>
+
+      <h3>
+        <tr-ui-b-mouse-mode-icon modename="TIMING"></tr-ui-b-mouse-mode-icon>
+        Timing mode
+      </h3>
+      <div class="pair">
+        <div class="command">drag</div>
+        <div class="action">Create or move markers</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">double click</div>
+        <div class="action">Set marker range to slice</div>
+      </div>
+    </div>
+
+    <div class="column right">
+      <h2>General</h2>
+      <div class="pair">
+        <div class="command">1-4</div>
+        <div class="action">Switch mouse mode</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">shift</div>
+        <div class="action">Hold for temporary select</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">space</div>
+        <div class="action">Hold for temporary pan</div>
+      </div>
+
+      <div class="pair">
+        <div class="command"><span class="mod"></span></div>
+        <div class="action">Hold for temporary zoom</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">/</div>
+        <div class="action">Search</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">enter</div>
+        <div class="action">Step through search results</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">f</div>
+        <div class="action">Zoom into selection</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">z/0</div>
+        <div class="action">Reset zoom and pan</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">g/G</div>
+        <div class="action">Toggle 60hz grid</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">v</div>
+        <div class="action">Highlight VSync</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">h</div>
+        <div class="action">Toggle low/high details</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">m</div>
+        <div class="action">Mark current selection</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">`</div>
+        <div class="action">Show or hide the scripting console</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">?</div>
+        <div class="action">Show help</div>
+      </div>
+    </div>
+  </template>
+
+  
+</polymer-element><polymer-element name="tr-ui-u-array-of-numbers-span">
+  <template>
+  </template>
+  
+</polymer-element><polymer-element name="tr-ui-u-generic-table-view">
+  <template>
+    <style>
+    :host {
+    display: flex;
+    }
+    #table {
+      flex: 1 1 auto;
+      align-self: stretch;
+    }
+    </style>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+</polymer-element><polymer-element name="tr-ui-timeline-view-metadata-overlay">
+  <template>
+    <style>
+    :host {
+      width: 700px;
+
+      overflow: auto;
+    }
+    </style>
+    <tr-ui-u-generic-table-view id="gtv"></tr-ui-u-generic-table-view>
+  </template>
+
+  
+</polymer-element><polymer-element name="tr-ui-u-preferred-display-unit">
+  
+</polymer-element><polymer-element name="tr-ui-timeline-view">
+  <template>
+    <style>
+    :host {
+      flex-direction: column;
+      cursor: default;
+      display: flex;
+      font-family: sans-serif;
+      padding: 0;
+    }
+
+    #control {
+      background-color: #e6e6e6;
+      background-image: -webkit-gradient(linear, 0 0, 0 100%,
+          from(#E5E5E5), to(#D1D1D1));
+      flex: 0 0 auto;
+      overflow-x: auto;
+    }
+
+    #control::-webkit-scrollbar { height: 0px; }
+
+    #control > #bar {
+      font-size: 12px;
+      display: flex;
+      flex-direction: row;
+      margin: 1px;
+    }
+
+    #control > #bar > #title {
+      display: flex;
+      align-items: center;
+      padding-left: 8px;
+      padding-right: 8px;
+      flex: 1 1 auto;
+    }
+
+    #control > #bar > #left_controls,
+    #control > #bar > #right_controls {
+      display: flex;
+      flex-direction: row;
+      align-items: stretch;
+    }
+
+    #control > #bar > #left_controls > * { margin-right: 2px; }
+    #control > #bar > #right_controls > * { margin-left: 2px; }
+    #control > #collapsing_controls { display: flex; }
+
+    middle-container {
+      flex: 1 1 auto;
+      flex-direction: row;
+      border-bottom: 1px solid #8e8e8e;
+      display: flex;
+      min-height: 0;
+    }
+
+    middle-container ::content track-view-container {
+      flex: 1 1 auto;
+      display: flex;
+      min-height: 0;
+      min-width: 0;
+    }
+
+    middle-container ::content track-view-container > * { flex: 1 1 auto; }
+    middle-container > x-timeline-view-side-panel-container { flex: 0 0 auto; }
+    x-drag-handle { flex: 0 0 auto; }
+    tr-ui-a-analysis-view { flex: 0 0 auto; }
+    </style>
+
+    <tv-ui-b-hotkey-controller id="hkc"></tv-ui-b-hotkey-controller>
+    <div id="control">
+      <div id="bar">
+        <div id="left_controls"></div>
+        <div id="title">^_^</div>
+        <div id="right_controls">
+          <tr-ui-b-toolbar-button id="view_metadata_button">
+            M
+          </tr-ui-b-toolbar-button>
+          <tr-ui-b-dropdown id="view_options_dropdown"></tr-ui-b-dropdown>
+          <tr-ui-find-control id="view_find_control"></tr-ui-find-control>
+          <tr-ui-b-toolbar-button id="view_console_button">
+            »
+          </tr-ui-b-toolbar-button>
+          <tr-ui-b-toolbar-button id="view_help_button">
+            ?
+          </tr-ui-b-toolbar-button>
+        </div>
+      </div>
+      <div id="collapsing_controls"></div>
+      <tr-ui-b-info-bar-group id="import-warnings">
+      </tr-ui-b-info-bar-group>
+    </div>
+    <middle-container>
+      <content></content>
+
+      <tr-ui-side-panel-container id="side_panel_container">
+      </tr-ui-side-panel-container>
+    </middle-container>
+    <x-drag-handle id="drag_handle"></x-drag-handle>
+    <tr-ui-a-analysis-view id="analysis"></tr-ui-a-analysis-view>
+
+    <tr-ui-u-preferred-display-unit id="display_unit">
+    </tr-ui-u-preferred-display-unit>
+  </template>
+
+  
+</polymer-element><style>
+* /deep/ .x-list-view{-webkit-user-select:none;display:block}* /deep/ .x-list-view:focus{outline:none}* /deep/ .x-list-view *{-webkit-user-select:none}* /deep/ .x-list-view>.list-item{padding:2px 4px 2px 4px}* /deep/ .x-list-view:focus>.list-item[selected]{background-color:rgb(171,217,202);outline:1px dotted rgba(0,0,0,0.1);outline-offset:0}* /deep/ .x-list-view>.list-item[selected]{background-color:rgb(103,199,165)}
+</style><style>
+* * /deep/ tr-ui-e-chrome-cc-picture-ops-list-view{-webkit-flex-direction:column;border-top:1px solid grey;display:-webkit-flex}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view{-webkit-flex:1 1 auto;overflow:auto}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item{border-bottom:1px solid #555;font-size:small;font-weight:bold;padding-bottom:5px;padding-left:5px}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item:hover{background-color:#f0f0f0;cursor:pointer}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item>*{color:#777;font-size:x-small;font-weight:normal;margin-left:1em;max-width:300px}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item>.elementInfo{color:purple;font-size:small;font-weight:bold}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item>.time{color:rgb(136,0,0)}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view .x-list-view:focus>.list-item[beforeSelection]{background-color:rgb(171,217,202);outline:1px dotted rgba(0,0,0,0.1);outline-offset:0}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view .x-list-view>.list-item[beforeSelection]{background-color:rgb(103,199,165)}
+</style><template id="tr-ui-e-chrome-cc-display-item-debugger-template">
+  <style>
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger {
+    -webkit-flex: 1 1 auto;
+    display: -webkit-flex;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel {
+    -webkit-flex-direction: column;
+    display: -webkit-flex;
+    min-width: 300px;
+    overflow-y: auto;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
+        display-item-info {
+    -webkit-flex: 1 1 auto;
+    padding-top: 2px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
+        display-item-info .title {
+    font-weight: bold;
+    margin-left: 5px;
+    margin-right: 5px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
+        display-item-info .export {
+    margin: 5px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > x-drag-handle {
+    -webkit-flex: 0 0 auto;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel {
+    -webkit-flex: 1 1 auto;
+    display: -webkit-flex;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
+      display-item-info > header {
+    border-bottom: 1px solid #555;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
+      display-item-info > .x-list-view > div {
+    border-bottom: 1px solid #555;
+    padding-top: 3px;
+    padding-bottom: 3px;
+    padding-left: 5px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
+      display-item-info > .x-list-view > div:hover {
+    background-color: #f0f0f0;
+    cursor: pointer;
+  }
+
+  /*************************************************/
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel >
+      tr-ui-e-chrome-cc-picture-ops-list-view.hasPictureOps {
+    display: block;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel >
+        x-drag-handle.hasPictureOps {
+    display: block;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel >
+        tr-ui-e-chrome-cc-picture-ops-list-view {
+    display: none;
+    overflow-y: auto;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel >
+        x-drag-handle {
+    display: none;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger raster-area {
+    -webkit-flex: 1 1 auto;
+    background-color: #ddd;
+    min-height: 200px;
+    min-width: 200px;
+    overflow-y: auto;
+    padding-left: 5px;
+  }
+  </style>
+
+  <left-panel>
+    <display-item-info>
+      <header>
+        <span class="title">Display Item List</span>
+        <span class="size"></span>
+        <div class="export">
+          <input class="dlfilename" type="text" value="displayitemlist.json"/>
+          <button class="dlexport">Export display item list</button>
+        </div>
+        <div class="export">
+          <input class="skpfilename" type="text" value="skpicture.skp"/>
+          <button class="skpexport">Export list as SkPicture</button>
+        </div>
+      </header>
+    </display-item-info>
+  </left-panel>
+  <right-panel>
+    <raster-area><canvas></canvas></raster-area>
+  </right-panel>
+</template><style>
+* /deep/ .tr-ui-e-chrome-cc-display-item-list-view{-webkit-flex:1 1 auto!important;display:-webkit-flex}
+</style><style>
+* /deep/ tr-ui-e-chrome-cc-layer-picker{-webkit-flex-direction:column;display:-webkit-flex}* /deep/ tr-ui-e-chrome-cc-layer-picker>top-controls{-webkit-flex:0 0 auto;background-image:-webkit-gradient(linear,0 0,100% 0,from(#E5E5E5),to(#D1D1D1));border-bottom:1px solid #8e8e8e;border-top:1px solid white;display:inline;font-size:14px;padding-left:2px}* /deep/ tr-ui-e-chrome-cc-layer-picker>top-controls input[type='checkbox']{vertical-align:-2px}* /deep/ tr-ui-e-chrome-cc-layer-picker>.x-list-view{-webkit-flex:1 1 auto;font-family:monospace;overflow:auto}* /deep/ tr-ui-e-chrome-cc-layer-picker>tr-ui-a-generic-object-view{-webkit-flex:0 0 auto;height:200px;overflow:auto}* /deep/ tr-ui-e-chrome-cc-layer-picker>tr-ui-a-generic-object-view *{-webkit-user-select:text!important;cursor:text}
+</style><style>
+* /deep/ quad-stack-view {
+  display: block;
+  float: left;
+  height: 100%;
+  overflow: hidden;
+  position: relative; /* For the absolute positioned mouse-mode-selector */
+  width: 100%;
+}
+
+* /deep/ quad-stack-view > #header {
+  position: absolute;
+  font-size: 70%;
+  top: 10px;
+  left: 10px;
+  width: 800px;
+}
+* /deep/ quad-stack-view > #stacking-distance-slider {
+  position: absolute;
+  font-size: 70%;
+  top: 10px;
+  right: 10px;
+}
+
+* /deep/ quad-stack-view > #chrome-left {
+  content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMcAAABICAYAAABC4+HLAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAB3RJTUUH3QcNFyMmV/Pm9QAAIABJREFUeNrtvXmwXdd13vlbe9/7BgzEQAIcQAIEQYKjSAokLVlOW5Fk2nLKmqx0J2Wp0k652h13uiy5XYqdwU7sSnckpZ1yV3U75apU4kos27Elu9NlyRXZjiiRomSTIiWZs0hwHsABJIY33rPX6j/W2ueed3DvAyDKKoGFW0UCeO/ec/fZZ+29v7XWt74lAIuLi7tXV1f/raq+zcy2AogIZsbpvrqfMzNE5IS/1/fVn5sZKaUTrtX9/v7nT+fn9e/1e052X/3r1THWa3R/37+miKCq7c+mjW/a+F/P57vj6/45bayn+wzXs4n+794Q9nP8+PHdS0tL31LVmfpGVQU4YSInGUb/YfZvpn+zp/LQu4Y27X31d933nurkq+qaa08yotO55npG0v2O+r1/XZ9fb2FMWoD9Oe5+pju//e+fdP3u83+j2I+89NJLn11dXf1bdSCTJnnSSpz2+/VWZ/8m+w+g/zD616yT2P9733BOZ5f4dhbCevPQHet63zVtV3y9n1/v/k9nZ562SNY7Gd5o9iPPP//8qxVKrQdL+hOy3qqdNEnTjv1JA+vuRpMGvd7kn8oCqded9B2THuJ6u/Kk7+vuiNOgQH8OX+/np813/376O/CkU2EavDwVWPiGsp9nn33WJt3ItF2ne2xOe2jTHuTJMOS0He1UcG33791JmWQYkzB6dyfp7tynsktPG8/Jdv2TGcLpfH7Sc5m0EKZBsPV+tp4PMe39bwj7efrpp229G5u2O3WPplN1cE/XQZsENybtnNN2pv4x3N1Fpu2S/SO6j6fXgz6n4gRPGmMfR7/ez/cXd/1798Tsfr4PMU52Oq4Hp95I9jPor7ZJ+G7STlEnvN7gesfXpB2tH5lZzynrO07Txtb92aQTY9rv+3i1v4jqv5umOSEq0r9O3/iqEUx6MPXnqjpxrk73812oMQmP968zyUj68zPp+U1bxG80+5GnnnrKpkVxTiWUuN4q7+96/YFXp6pvANN8hD7MmRbF6O7200KR9ed9CDbpSF4v6jIJtnQjQdPGOylK9p34/HowaFL0Z73IUNex7Z5Gk3bkN6L9yBNPPGHdY3fayu3uSP0dqH62uyP0w4XrDWo957gPEfqf78e4p4U8+0Y86R6711pvAUyL3vTvd9ou238Q/Xn4dj4/Cd6d7BlMC532534S9OnO8xvVfuTxxx+39RJlk/DtpAGc6k6hquScp+7EkyIn0+LV60Ufpu2q05zN/sOYFIfvP8CT5VEmGWN/h5w0zm/38+sl7/r3drLntt58rzdXbyT7kccee8z6O2b3JnLO6zpjk47nkyVg1pu07muas9b3CaZh4f5uPMn4Sikn7Jj9RTEJMnQfVHdck4x3Wt5i0qL6dj8/6WQ5GcSYBiEn+STrhT/fqPYzmJYxrRcopax5eH18Oi38WI2ulLImYTPNMavv716z/93rRXUmOZXVgZ5kePX7+hPeN5xJTmx3MdXf9zHyM888w8LCwgn30IUQ0xzWSYvhVD4/LarTzpWBpOl+zqRQ9lqjE2DCtbH2x9MW3XA45JxzzmHnzp0njYp9r9jPoH75Gkekc8SZ2ZpjrH/Ez8wMSSmHMY4YjZp2MDnniVGT/sPvRhxmZ2fJOWHmxj0ajU7AtvV6k4727gSklMg5M4jdq6iyuro69bv799fNptYF0X3vJKjz8MMPMz+/gWuvuYatW7eScgIEwTADEwEUAZDkBgtuYONlCCJgAuZ/N5QkCcP8avFzUH8fsZgNEoJJLAakc+2TjENi90RQjGSCJm1/hwlmgmRFFIwEYoiNxyPxvYZ07gVKUzh8+DD333cfRZXLLrvsBLxfjbl76pyO/ZRS1thq325O137k4YcftvUSOf1Ufdco/uwLX+LOv7ibZ194EYBdF+zkB956C+98+99ARE64ue6XqyqDwaDdGZqm4Qtf/DK3f+UveO7QS2uu944f/IH2WpNwdp2U/oT8+W23c8dX7+K5GN9FF+zkb7zlZt71jh9cswNPw8uTsPU0h19VeeSRR7j55lvYumUzK6MCpqTs9p2AAiRLmChWBBIIiqZEMkVUMAQTJZtQSCCKkDE0/h+7twkKpCSYxrhVMTGyCYogohRLCGvHoYD0xyGKScIUpC5AVSQl/0ACaxeCkJJhakDCTJEEiKAmDMx8XSdAY6lZQjHmZoa89NLL3Pv1r3PVVVeesDH3T+FTtZ/uguhu8v3o36naj4ggjzzyiPXhwtRjOf6+tLjEP//4r3HOuRfw5psPsOeSXQA8+dQz3Pu1ezl2+BC//I9+jvn5uXWjDfW1uLjIr37y19m8/fzJ13vlBf75L/48c3Oza3aWadSP5eUVfuUT/2bd6/3yL/xvbNgwv2Y3qbtOF0J2MfN6ka7nnnuOvZfuZcfO8xitKnloFBXEBHGLc4MTQwVEDeIkyAqa/Pdh9z5vaqgkUuz8akYGVATEHOYYiCSUQtJqkCDJsJJIvXFYNRIzLGWQQqqLEiOhqKS6gnzhqJ9cJplsiiXBSnfBJF957TEoJBKYYskwFUSgWCKnBkmZp59+mpdfepmdO3eu2USn+V/r2c/JWAX9CN/J7KdNiD744IO2nqM0Cff+01/9P7js6gP8d29/C5detJNtmzYC8OrxBZ547kVu/+JfcPDBe/iXv/xPkCnkvHalm/HPTvV6v/SP25vs3mB3fKurI37pX36cfdesf73HHriH//2X/3Fr/NOSTZMyzn0n0sx47LHH+JEf+REWFhd8pzcliRtyBVbFYlcTN0bfpoWEYiaxENTtjOQwByOZ7+r+b/zacY5YICvH/iDmBurjmzQOKMlIWkPThpohkuN0iwWI+YrNGkdeQswwcbhlWEAzw8wXazZDJfsYMP84ghXzxSHip5rB/IY5/sv/+0dc96Y3rdmA2uz0YDA1EHIqDNv1KDAVvk2yn64vOujHlqdlJ+vv/+wLX2JuywVcfOkeXj2ywGtHn0C1Hov+uUsu3cNzzz/Hf7vtdm5959snRknq6wtfvOOUr/fnX7yDH37n29fccBdG5Zy57fYvs2HrqV7vdm59x9vXJeqtx6WqD+T555/nyiv3s7y8TMLhSgLMElkURx+KENi+7uzi0EgtIUCi+OmSwIpjmYTSAIN6uiSDkkAKQgp/IgON+yaGnxIBz/rjcPckj30LU5I5rCsJsiYsafgjCbXEUIwiiqq4e1J9FjVfNCioYMlPC/eJIFuisTiN0oBkhllBcmJlaYnL9+/n0KFD7Nixg5xza6hPP/00S0tLzM7Mho/lfpGicW/hyyCQAv75Nuw+UOwi/o7WmXLfClhYOMaWLVvZtWtXG7TpRibrMx/0V1j34XcdT4DBYMA933yQnRdeymhUOHZsCZFEqrurORRZHRV2XrCLr33jft596zsZjUbtiuzGqQeDAXd//T52Xrj3lK53zzce4G/d+k6WlpfXOF5jSAhf+8YD7DjF8d3zjQf50VvfRdM0LYzqv/pHcH9napqGF154gb/59rdz7PhxTPCdNSliisYuK5rjIRsWPyeJQyGhWhyNCEn9sbrPIGRJmBRfeCb+kEXQwDZG49AFIYmh4kvmhHGYISTEGl9YBimPoZypvx8VJA3R5IurMcdrSTrjLuGjGJCNpJnGlCwWp6CRMLIoMCBhFJPYIAxNxjVXX83v//7vs337dnLONE1DzpmXX36Zt73tB1g8fhwzh3OIObyrp60IWp9XNlBfRtkCPqWIM9T5x+GhDIQN8/O88srLfPWrX+WWW245IeLVPvvubt49biZRMTDj6MISGzdt9i81YTjIzM/OMjc7w3AwANwp27hpM0cWln0iOt9RowruSAlHFpZP43pLJxAB68lnZuSUOXJa41tCIuQ7jYBWf9fnP5kZo9GIlZUVLrzwQpaXVzxihGHJEE1ucdlIkgOwKMncj5Ds0SjfZd2R9re7AeWkGOFUhuOrrd+jFDPMEkJ1XGPhxdY+cRzZARPJfR9Jiqm/P2wONKHJwJRs6jt0Su5nWHJfQj2IYBQIp14xBkI47OE/BVyUFI6/KCk5zJOSGY1W2bFjB03TrOGtzQyHNKNRnTGQghWjWInxGI0phvtyNOZg0GAU86hmlMYw9c9qMYyCjgpHjx9ndmYD3//Wt3LPPfdM9FtUlYGqUko5IbzVdUi7WHw4M8vc3CxzczNsmnejq6HSphSWVlYBWF2ZY2Z2tt2tuwuw/ruUwszs6V2vuxi6TlYd48zM6V+vC8/qYqgnZT861Y+dP/bYo/zoj/4Yo3o8u1PgoVRJiPqJBRkRo6C+oxchSaGIxC5uJHEfwDdqN3xTg+wRKXd2EyRIBppjy/fLY02CWCzTxuHX91MAEfdPNJESqBopFcwyJurAqg3jWpx6DqkExVIiNwIDQa1BAWRAQiE5XExJ/URCyQgFIZlB9rk8cOAAt912G/v3728jiMOZGVQDEShoSUhuEM2U5CecFHWIGbAzlwZJghRDs0AJ2FVdu2wUMxI+XyqFpjF27drF0aNH2bRpU7txt455fcjVuCrE6Ds6DkdW2bF9C1lg49wsG+ZmOWfjHNu3bGL7lk1s2TjPpvlZNszOkMTYsW0LWvSEHbhraDu2nfr1ztu6haa3uLqn0qhpOO+0rncOTWcy+vmMesLVxVgXdimFpmligWbmZgZtLN8vFmFZbbBGHfdSwo9whxot8ZAdMydzTG9aUDGKGlZ8QaiGU6wGVtDSUChIY6j6gqOBTHPScZj5qVHUoAg0DaYlIIWhlj2qFUhBDUwLNH4tMCgKZqRSGMwO+PM//VOGgznPe2jDYGbIvfd8g5mZAapCMcEEv6cK8RpFLLFp06Z2Lqvt7dmzh4cfeRBTQ1E04GXBEG187pLSqNKYbyBm0IQda6MoDUbB1DwQUvyE1tJgKFqM1dJw6Z5Lefzxx1vb7B4EqbtSJjmmXYjVNIXrr7mCI68dZmaQmJ8dsu2cTezYtpkd2zaz9ZyNzM8OmRlkjr52mBuu2c/qaHRCZGcMSxpuuGb/qV/v2isYxfW6GdFqtE3TcMNpjq8mGbs+xyRSX520GhMvpfDC889z7XXXsdKsYMV8t7fA3ChYJmWgGKkIlh3SWeQEwJDkp0UJKKIioGNXW9R3PnKKEK+E32BYDlxvUMTQzEnHIREQSCQaMSRn9+dlvKOmMUr3aFRKcco43JIUicWU+G+3fYHf/c+/x6c+9R+ZGQ6ZmZ3jtz/1Kf7PX/vX3HPvvTHaQsYgKUnFo9C5oBirKytcdeVVvPjii+1zEBGOHTvGxk0bfXGabyxGQ1GHmaYB4YqRLDYIIXyw4vDQ/HoJQ61BTHyPKeZ3aMbxhQXm5+dPSDCaGamPt7pQZRJL8qYbrmP56KscPnwYEZgZJAbZ/5sZZMA4fPgVlo++yoEbrqXCtq4Bdv2bm9/8JpaPvXZq17v+2hNgTXcxN03DzQeuP+Xx3XLg+hNoGN1Togsxu4umnijPv/AC+6/YTxlZZIo1YJIf5yLmBpeFMhCwEg67J8QkVacyRe66eLg1aRtcUVFSgmzFsx3uWSKSkWIUibiSpcD1648DMU/ggTvP6r5PskhrmEMfRFEJKBcZfJPkjq4nQTA13vk338mHfuJDfOXOr/J7v/t7/M7v/A53fvlOfuqnfoqbbjhA8di1/2nZr5kU0YQlhz7XvukannrqqTW2snXrVpYXFrBmBH5+OBnA/CRxP0NJVjySZoo2DrLcbhu0eDTORONnxde3FUQLqoVmtMreS/fwzDPPnOBe5J/+6Z/+F/1dvZ9V7BqHiHDDtVdy51f/ktVRw9ZzNpMkMRo1HD16jAce/hbPPv0k/+N//941Wcr1CoNuvO4q7vjKetd7gr/3t98zkXJ8QpTJjBuuu5IvTxnf/Q9/i+effpIPf/DHJiqO9EPX/Yhd9UuWl5fZMD/ProsupJhDBEniOzaCWMakuNMsjp0znhzTSv0wRbL4yYCQyWgliJhTMzKZRty3cNhDJNgMY0ACz66H333ScRSHVSnCrZbdfzFpc4okFLHsvkEkBE0E6YSPfXxQrHDF/suZnZ3jttu+wHPPPcv73vdefuiHfpiVZrlNbLYJy4Hfm9uSn4jaFF47coScUuvnbd26lccOPsa27eehxXd/JO7LQAZgJRZ84+epZM8JeYwtIaKIRZpGxXNFLTvMIuye2LRxE48++ig7d+5c48/KPffcY5O4+11nvOsj1N/Pz2/ggYe/xaNPPUcTGHc4GLBvz0Vcc8U+VlZXpkrgTCrPrNf71pPPnnC9a6+8gqWlxTUOUx1T/VmfGbphw0buf+gRHn3yudavaMe3/3JWVpZPYOXW+6vX7CYcu9GUpmm47777+OAHP+h4NxYlSdr8gOGOY45TwCpIsRQwxkjqxi7iECCJY3MBj91L8viXKSlFrN7iG6SyrOp1OaVxEAlB1EPFyTzSVCkjmgSp2XGNPALBO2kMy0JW8YhW8VNpODvLp//g03zjG/diCDfeeAN/+8c/yOrqClgOLpZgA8NGKU6vOI0QhMzK8iL/9fOf58orr2QwGJBz5v777+etb/l+jh096rAzCNApbhMqRItTRVKHGBmcF6CYkSUjWlr+pNNrIodiwlNPP8WuXbvWJKoHXew+GAwYjUYnxPS78d9q3EtLi+zfdym3HLiBuVlP1qyurPLakSMsryxPrNfuhnL7hLKFhePs33cpN9/4Jubm58BgeWWFI0eOsLBwfM3i7BrytLrlhYXjXL1/H993043MzsyAwMrKKseOHWNxcWEq6a3PzO0nSFWV0WjE7OwsMzOzLC8teagTQ5w8FVljZ8B6bD/Ig2YkUaz4I1Tx06Sh+E4cxuIZcHdAU8Ak0+T2ihtWzYSj1NThScfhYM4dbne6fVcV8bCx5zpicanvvO2qix+bepSrFMgizM7O8h8/9Z/46p1f4f0f+HEA/ugP/5CVpRU+/KEPsTxa8XAxhpRUM6C+IFViDgqbNp3Tnso153HhhRfyyuGXyGmGOjtJxfliqYbFPX+hpiQKWIoNB1CFQYrTsqGIRLTKT+xk0ChA4Yr9+3ng/vvZu3dvaw+D7mmxsrLCYDBY44TWf3eNsJsPeeWVV9aVdekvvm7Uql88tLq6yksvvzy1sH+aSkh9NU3T+k0iwuLiIouLi+0J2K8zmERP7+Z2qvPdz3EcOnSI6667jtXVZTQZ0pgf81KZrNWgAuNWrlJSSolEWPL9WqWGOt2eJSlaguJhvusnEc/yV0ygRkkpiH+QRSnCScfhnCl1smM44BVIdVnBnnFOEfpMiBVUnMxYeWFZ3FP6/z77x9x5x528//0f4F3vfAdigpbCZ/7wM1yyezdveetbnL8lCbNC5cAUJ7d4SFoSS6Nlrrnmap555ll27tzJcDjk3HPP5eDBg1x2+RU0qytgQol5dNaDopactoLFCVyQLKhCSua+hQTzWD33YwKpcUaA/8ztbBRRs/bk6OPsLkTRoHj3C/Yn1Rv0/ZJJBSarq6troEr3c/XPmvnuQ7FJmfu+sMAkI+/WpPQTndMURGqCr8/6rD8/dOgQ73nPezh27HhEYzzk6Md6pX8bFbAIhonDJKhoxWLXTwFp1NdPY8EgFzT8Dv+AOwbOrjWPgKXKbfLo1CmNo15HPHFmUhgTVQh+lOOWLM641aCFWEtbj+cgyo/+yLvZtnUb3//Wt7G6OkIwfviHb2Xnzgu48c3Xs7K86idNzTGUoLlLxUdOiMwI1159NX/5l3exbdu29jkuLi4yPzvL8dUVSoNDtDjJLKBRI0YmkqXOcEQSFI2cShKkLowSSUlLkU+CZMbi4iLnbt/O8vIyMzMzbkt33nmnTaqK6lZx1aOuX7vcx+yTanq7MKpbfNR1quvu3F8wfQp5d7ev4+v6Al3o0/eX1hMHm1aLPEl8YWFhgZWVZd7+gz/IatOEPzDwya8bdXLoQwnqglR6OBFNcqhDOLbq22dEIiM513iUR8woyZ32XJ3sFDukuPtSKhnxFMbRJgZjx0ymIIM2CWkBO6xS4FNk7cVQC1jia6UNh1rOfgKotgnLFGOWDkFRTZyuUmodSaX1BNoYCF+548vMDGeYn59nZmYGVeXwK4fZef4FqFkEH2owISElnil+X77Ak/PQLBYzYNKQbNDys2rEziJQkFDO2bKVu+6+i71797q9dxNp/d247yfUnMC00Gw3kdNNltXPTitb7VZ91YRQn6zY/96+L1TDq30nvY6l+2fNldSxdU/Mfji3C+1WVlZ45JFHeOtb3sZodTWIbL4raTAKa8UFxTlOTlfxZJRU34DkcXuLRG6p4VdAszu+QZZTBSkOY6zu/MUJWaYRTTuNcfhxlaIOQ+Ik8ARhqZBNPOyMJFLkFDTGX0wpJUCYiI+ztaHY7ASsGRuemS+iZCCqEbiKMKv6ovRxKbccuIWDBw+2lBIR4YVDLzAzHJLQCF1bhzZSPKnZEjiDvqLmi5sCyfMeJpU640466uPT5Pe4PFohDTLD4dARQ3e3rYbdzRB3F0mfqj0pD9CFL12sXiM+1ZDrd9WfdSejv+C6pMWukXezmv3/uhCpe63uoqvjrYuq6WHOetp1v3N+fp65+TnMMpTShjOt3QE9ROvYPI5/83oKlRL1FIrzNSRyAJXFamBNLexzjJ78mqq+YFJxACZ4dvB0xqFBFycpUMhmlBw0k6CxWnJDdlqKnwR+gezcrmD+WkR+tN1/jUJARRM/tSg+1mSU8K80KCGkgiEeoFAfkqkyt2kD8/PzLVlVVbn22mu57YtfYLUUNm7cgBYfmgUb2BduHJfFKBRnAqRIXBZnKIuCNMWTirFo0eKUEwEdGcuLy2MbuP32260LfU6m0zRNm3Q9XdZazDIajRgOh+2C6Auk9X2e9dQpJtU+96HSYDA4IYk5TVh4Te1w+Br9U+PFF1/kyquuYu/eS50KkiQoHtLmCHJEhGosnRrPD6IgOaIl5rAJ8YSYJoWSUSnk5Bwqq5gjJUyLR4tybhm8vkA4rXFIMmiEkqSlswseyclSTxL3XzyRCGLF5QaiZLZSw2t+JuHObaJuAuo8KLF6i/V/Dgu1pk+C1hEOcRLP8D/1zFM89NBDnH/++QyHQy91Hgx44IEHKKUwPz9PaZq4txpVq5WINZIXLoJGwZa4RyZtrNzvQVGSed3LzOwsKQm7du0aEw+7jmyfaDiJRtENuU2Td+z/vMvd6i6++u8uhOpHlyoEqousr3LXvYd+sq7eU9c3miSjWRdJ9WO6i7DuYIcOHeLHP/B+ji0skSWyA6kWKKU2x13LUn3HcuydUoSjgk6NJqwUkNziYMtK1hTwSONKvggk+WJJgbFNGswyScopj6MN+yZjkEAbQwYNlMwwfKKSPN8S9u9JNcmIRj1HkByliEfGRoKm5KzxONMkxpCjTEDw7L1FWUESpWgIX2SLkoKoGMzC/iuu4Mtf/jI7duxobWJ5eZnLLrusjXh2Swb69tO3iYpQuqWw1fftRkyHw+GaIM2gL0ZQv7juntN0nLoZ9a5D3GXdttTfyHr2F0QdcH8xdk+P6kt0F0w3RNyv0OtH37rXn8TA7YsorK6unlBPXEphYWGByy+7jMWlZa+YK8kd5sDqKejfRkNmgBaPubvwgNKUQYxRIZnvxil2VC3+WREnFOILysSDrKoCNAgShU/J687l9MeRygCNYqriTA7PyquzcX0z953fiIRMtnEJbQ7elnrQQHMhaaIBp8cHLPOKkUqV0VYvQsy8ZiVqQ8Tpu2OonmBlZYX9+/dz5MgRtmzZsqaMtm8bw+FwzabaZ23X1+zs7Bok008kT5JYSl0j74ZtR6PRGojV3fFreLOLxfs+S5f+XXfe6mtMKputi6DrVPfpIX1fon5n15/o+g2T9GHrOJaXl9fkbUoprTJJHWddwE3T8MQTT/COH3oXpSmRqnP6tyexvKRUUMQG7luY1GgqiSF5UDynkSzwdZSamkQxj4dXsyWyQE7uvFrUwWrKEIVPOqgV36c/Do3TS6VGsiLWr2PlkAxYKo5zaiYcozHncGlAGEsgJUUdObhn4ZAmp2Acx2JHpBO50tZvMrE2ny1RHKXA277/bRw8eHCNXX237Sd1C4e6cKceMd2sdI3ydJ31SYXsdYDd1djdyfuwqgt3BoPBCSJjNRFZrzccDtes+vWUUvqJwvr+4XC4Jsxcd4+6+6SUGI1GHD16lAcffJD/4e/8HZaPL3nVWXCSPLTpLB1LbqopZGsQT4aliB5pyaTAtwWQQfAhtJCDqaqRlCtBabBhwnKJIiOLTDfQSOQrTn8czsNIHhUL6J0HOGwzJxUWEZJKsDIEy4ZJ9ipDrUojGg67JwuCKxwejuc1LIfJB8YXEY9WRZGXImQN1i+GpuSnWTGWV5b48Ic/zNfvvZejR4+uQTffLfuR27/0pdhCiAL6MUmM4J7Uyq5WmiU0kmqEo2oj1Z9JyLVU3GqRFfU5Cp+ge52uDx+7UJ3kVgFJWPO++pska+Vqqq+FdcbT+S4i4tJqRdXQUCSU3JeTljM1HA64+qorWS4N2VJ8jQYBLpMoQUWHAUKDix9U+ptj/cBI4nymAEvxQBwe+XXjHlJBtdIQ05hwh6JZSPo6xtFm68f3i4IFnZycQhBhnJF3H1yD4hIlsCpjxq6M6+NpqTIhAySKFKfiD5K11A93xI0qFlRTqV42HLkhEyQJDz74wASxD9pn1SGutQteqM+acRBhLBI2wZ7Hw2+t6/lDh2woQhG8drkaazUUBI00ewpqDClR1EXGqiZRq2IR0jE5HM+avZWITzsTMqInEb2oC0BDoCxJ8IoiopCCy+OsS6c1iPiR7xFFI6dQvqhiCjHlLfwQN6Lx/Xssp5iQrBpK5JJbdqrXSYiF1kegDM8ZBDkvplIl5igHLSMoH9XZFIOSa2WdeXVbZGpdWMfxuVRHH39fLFvPVai87nH4JsDaZ6WG5SBFVl6X1PmHsV5QhEQcCZcsAAAWiUlEQVTN/3S+VfIipBosE0FLzWRnf1Z4Vtp9J/WAXcpRvBVUrprIi/vGxpG2yOWf5FkJRdx+Bh6DeN32nCRKFyV2No1Yd12ViguMpZRiB/AEVor4u0VM2+LYN/Hj2LO6cXhGFVjoVDjetnqsBMUnDuVURS1IpOw7TqP12K8Lw5Nm7vA5dUDVs8MSnl8hwpKhzKfqIgWu3RScHgtjSw4l6s6SgtWKuhqHU9OkzbYWMyx1ggPm7FZJyZ1UBIsyToschguG+HcXxZN+kdmuQVdNJRJw1jlVtS2W+k6MQ8W8bDcMMhWjSfgmY8Vza6o+P8Hd0wjFWlQG1mNc8OfqGWev2WgipKzqBuf+T4kyFB9f0TzOktdEqLoWlpl4HQaN86LsVJ+VeaTvO2jPg6B6erRDIIdR13oD/02s+uQTSJvrdfwpUTBjA2sTR9IINlCkyWiuzM/sD0DMSS0mTkqzhKbiANpo2aClEXLc2LhYP7Kfgb/rSSvWtMk2y7G7hbSHVUigtcjIKMUX60iEQQOWa/DU0BIs2ahRdqLOd2aOihZee+UwRYsbQ3a2qmbIxb1hC1U3oQ1ZjRm7GnkFEXKLIYmEn4zRRYp6kXofFYIEydHLB4OK0RmHf5eChOYVY2q81edWhdrCc3B4GBC3as3Fs0rFoaDXllQYowEVfcMiiJh10Yt2TqzkTGE/GeS7OkeDFD5CSfFnOFxSAjRKwKIUxklGvC4TGRSk8aIXk8bLO1NyxuQgao6roYaRWlSEWZhiIlFaAw+tpMANKeHx8Ip5Ww5NPDj1YnpPPDmFuoqMWRz1VfAMgvgnhpVwxIrn5Er2IqEkvjMnySjFT6SUnX/0HZij44tHWVkdccnu3Zx9fe+/Btr4DuvUBW1hjiTfL1IpNAKDyNiqFefN+Kbv8Wp1LaVKoSdi89Iq7/lRlc0jKJqsfW9JNi7cJ3mMPRwlrUzTtoYldokorjZxcKniO4e6DIWvfMVLSXODufU7wcE8yVZq2FDHO3xj1SeSVr0jWUE1ofL65shILC6tsG/fZW3M/ezre/uVkBJVZo5HCacxyDruuJkTzqzSHrK4WFqFKWLkyOWk6kTWLHllZhYP3UXZekRliFj4uHorBSFMzOPdFllaB8w4F0Y8sqJVXdzEaxnCaTXxMkpxBVn/uqSh9FcimuEOutQQRUrOdkU8vBo+kNcCvP45SiI0zejswjiTFodLODaUCJ21YbzgpKSICnn9rbSliCYRprOE5OTOoLg2kJHIUQYq2aMKOVVpRtpoeKoymVLpy0FbSA66UjinxRLJ7RfLGUWcyyMOzCLC6pg4uUaTmKDZa4fropFU2miNk3BaXgdSwqlLige1amVdcvr2654j9zfOvs4gWEVxVW2rNc2iHg7P7qiJiDujppTqtBSw1CDmcXRWidqA8LOtuAYTTlOQKOUZkwIrv8ZFugbqWqzSOulxZBQNOU+HLSkcNi3GAEHzyIPDGkxRF0cKCqpiKaT7i7rwWBX6ipNINbtoQHJGJjmFbEsVFNOWkWq8zjkadRzDs68zBVa5wQ2DgpAkObOsRFSiCsdJxdgZyKHm4OFbBhG4SZW373FzHUR7lKBGWIT2UieLOtTIaUQtmvsblT7txDUlkzRXIqUnk5LnHyQWBknIqDvFklxVQ2sCLBYdCcmGWnJJTvFQoRYhDYKBKhGxyQRPKLVhz29njlxMwDVaObs2zjBYFUmdxqzF3yI1l5DaTKSiaEkgrhhHEmaGmc2bNjM7mHF4o5HOi2qvXEJu3/DC/uAQEU53FokkWxDGUtVX9TLHpDkUx+tWPBYTm8kDl6jJngjy/GotAfUQclRTen11VMah47BdUUgpBJ6DFaCUEAwzJGVmN8yxYdM8m+Y3QM7Vg4kkkTE7nJ06R5VHZHEAnV0bZxysiqysefioiDCIWmQstbyYZMllKkMndX5mA//3b/w//MnnPsett97K//qz/wuriwbZd+IaXUo11m8pdFIjc12MJJGbiOIUzFzvtR1P01bOEUS9lDOPPPQQr7z6Kju2n8cVV1zuSStxaUxyiCfXa5iHgEuQ5VxCMORhUE/IVapQUGFTSqwsL/E7v/uf+eY3v86RI0eYGQ65/PLLee973su1N1xPWVnh2OICn/+jz/P+D3wgAgedOTJXRS8mDCIjXSkjZ19nCqyKrKMUT+J5mt4CK9MamAZRKhnMzczyG//2N3jowQe56aab+PrX7yUxJCWLCJLDnMoZwlwNIqc4naQySR1Mlcp5CQl8SSn8F2lT+W5YnpRqSmHvnktJOfHoY4+ShkFYyzkSSNYqjbcyXuKEEq1Z+6iuz4RAcpw6szNz/Pmf/lf+3k/+JN969GG2bd/Gvn37uPiSSzh+fIGPf/IT/Itf+iWOHDvGRz/yc+Q8OHGOYuJUPNTbWGkTY2dfZ9DiKADFG5aIppYe4KJi2qrsIQ2iwuzcLP/+t/4D9993H9u2bUO1cPPNN6Ml5F5qWNZLgl260Wruo6qMp7arllrxgFHtHyFgxeVUUggwN5W8KL7INm3eiKJs2LQRBQ5+63FyErSx4PxUiFfpGR4CdqFwRTUFT6j4Yo6SycEg8cd//F/49Gf+kBuuvx5B2LZ1G9deey2X7N5N0YZ9+/axuLTEz/7sz7Jnz+4WgnbnyKNmrhiokS23s7DqzINViaalbZQcNGXR0AbKThxIgllhbm6WT/32b3P3XXezY8cOzIwtW7byD3/mH7K4shzdiYxG8IRfKzwfLMiiYeAaxfnFI0ollMilbY4HRaNqLXnmXDJWCkVgzyWX8sSTjzOcmWPzhs0cOX6EJ558kt2790TysJCCJtBUVTypQoBGyRp98ELmrHgTl8OHD/MHf/Bp9u3bx2g04qMf/Qh7du9meWWZLENKafh3/+Hf8/xzz3HFFVcE6zeoJDFHLvDhVBlVF1FGcoSlzxrcmeVz2ABSoYTSRAlYoCl7D4eggc8Mh3zmM3/A7bffwfnnnw/Azp07+djHPkajDefMDUNhI1rwBllNVVlcWvRdNFid3quCwP7aGo5ZioYr3gekcnA8cqWklMMHSly+7woee+IgOQ3YumULh189zLPPPsPFF+9qWxRr66iH6oc60SxriBCrO82ShJQGfPozf8TevXs5duwYv/iLv8imTedw7PhxhEQjixxfXOa+b/4V5+04b1xGGwVHqXK7teZSSnTZqnUTejaSe+YtDu82mkU6HYEyYh5gFVNSHvC5P/kTPv/5P+Oiiy5sDeOhhx7i3e9+d0igyLgntYybtm/cuJFf/79+nXM2nxPKEwnJ2tJKUu0BIerZZIWmKdx11x1ITuOWXLjgGSHfLyS2bN3Cls3nUFTZunUbrx0+zPPPvsCFF1zoY8rR6kqcqGgaogiR6fYwrUfWBnOzPPLwg2zffi6X7buM7du2szJaDSq28OLLr/LRj3yEiy++mKNHj3p8S4RmtQkWLeHZV3GxqvAXGFNbZvnZ15myOEwsIq+1j0EmpdKqSKDG7Pw8n/7MZ9izZ8+a6r9zzz2X8847b90vKKXhi1/8Eu99z4+5+28lEhgS7EpXscgpuzyKKK+8dIiLd+9hkMQ1YtMIs2FIygS1pOo6hR9hZLZu386hFw6x6+JdjJrGe3lHEZEnxx37ayTzarPHJmU2JGNpyWVZLrrgQlaa1SBOehRr1wUX8NnPfg60RPbeN4Dl0QrLxxfbXuKo530oNm4qGYIHdhZXnWGLwxVhnJEq4lDDosREjZShrK5y1VVXsbS0dNpfsLo6YveuXWhxDySJdy8ySSRV1LIr1WlpT565jZs5fuwIaWbW9Y0sk5JGHsPFYES974KKMDDH+0X9NGmaEs0nvejHlFbqsu19h4euNdiBRYW5uVnX2F1aIqsXz2jxSpOl0SrLr7ziaRJlXAVnRm6VA6tgW/FkYuuE51pOefZ1Ri0OCrkMKGmsnySB2ZNAo0JZXuEjH/kon/zkJ9bUY59//vlcffVV3tpM2sLTtrZPzNiydQs33ngTy6tLkSj0uolkng/IOHFPa2mjGlu3biJnf2+tx0gdSYFg/XPs+AJZ1DsUkVhZXuDSSy9DKYg5M9ijYt4FqaiQcnFNpWxYyd5ZVYSiDeeffz5NU7j77rv50E98iIWlBVqhm5JdtsYysxtmKKPG+wCKK3VX9JSTM38tNFqrOksKn+fs68x5ydPPPF116sPochSF+C5emyFIRGQ+8YmPt7W8zz77HH//7/8kb37zAe+akw1TbwxZBbUV7yCkVW81HOycDG0kmh5KW8stVVM1VUHxCO9aFMvgnKnXXn2Nlw4dYtu554IVFldX2Lt7D6Vx/ydngvIuURIqQYyM8leSJzsju52ScMcdt/OlL93O4uIiBw68mb/7d3+C5ZXlqGly3+uVl17iV37lV7nxxhv4n/7B/8xoZTWKZizyi937SO6UR4vjFw49z00HbjprdWdKnsOakFUxjQ6exYnehdDmHtdooIWPfexjlJDc2bXrIn7zN3+Tv/rmN5zuPYrrFHXcrRaG6Ht+MYNSEFXKyHMSpp4LMNShkXmyT83afm+VKFi1/I6+eoRnn3uGrdu3oRiLSyvsufgSmlGlo9decNCkWn9hjKJGo4QAcqNOFUmmFFPe8a53ISJs3ryZ2277Iv/q4/+Kl156iY0bNoHC5z77x/yjX/gFzr/gfP7irr9kNg+pnQHaA7VoKwEKhjVB3bez2fEz7uR48qknLJNbdQ9LtaC4qkDUckZvmSXJM9Sf/OQnWxmUgwcP8lu/9VssLi4g5CASWtCVkq+TWmgURfFAiHpVXaZg9YpHtCza9bbyjeIwaSYP+NrXv8auCy6ClFg8vsieS/d4F9bIp2RxkWLNtLXX0Zpi3M8uKPBaO8DEybi0uMSv/ZtfY252luXlZR5//HEWFhYYDAZccsklbN++nYWFBd73vvdx0803U7Q5YY6INsaVGZ+Sy8+8+PwhDhw4cNbqzqSTo2BRqFOiFtuL8FMIFFA0+jQ03p8tZX7+536e5RWP7uw4b4d/Pqjpg2gmoqqIGk2IhlkqFINGjSZOBFXvEJpKQa2BQqhIBPtcFGu8GaIUb86+aX4TBeP48aPs3rMbbUY0USCF+omgRKticzHjohpL1JeHJqUpTl+36HmtpmyY38A/+6f/hAsvuojRaMT+/fu5+aabuf6GG5ifn2eQB/zMz/wDvu+W76OUZuIcWaijazFUCqWRXlHX2dcZcXI88eTjZpJoJYTa5iJjwYFKwo7MhwscZKGMCnd/7S7edMONbJyb94hTkii2DwVwAaxBZNCWt0rkARSviZBilARZw1hTLcgfh4UsKvEkpPEXFo6zcdNm12K1VjmrrfKr2lOefmg1WECdS+b6JjZuqFgpLHhgYn7DPMeOH+eRRx7m6NGjzM7NcsnFl7D3sr0cO7rg2XCxqXOU1JuqJFwsLQ0yh154nptuOutznDmL44knDPHqORt4Ew/VHPUXIeyg4pSLUK3TkHMPcaiqTeFwJVH14d2g1ZyqHmL1Xq0aelUaurBZooVCrdgLmJNrfTmtTlGKL9boA6HiDUwkh8SPiod9XUCD1EQ31VSbqsQCiSYsYhJtvdplBGY0SRhaFc2JTqbqQoGCYqc4RzUhmtOAF188C6vOLFhFzYr7jq5BIdeooZBUQg3PXD+1lOiyGBhe3dFurGqQatvpE6JKLjXeQ6HVEKoOdpwQxXMY3qXHG40UDGk80lTEe+URkvtaqScWPSrCnyBgVJXsMUtobtqGj973O8iUNCGr0zj3KciNqr7gBhqkkLZ3hYXBW0uzP5U5MhOn47SaT2dfZ8zi0Ej21cahRLzes9niESh1yEEJdZCIHCW1tr2UiF+H6Nmg0RWxrbQTV6zTKmxEkPQ6X1xlHNUKAwnZzuR1TqUEEz3V0m9DdeCD01Atz3jVYTSalOLYvwRd3YoLOlSVESxakdnIGzhqRJWiM5IFrUXR1z1HVb3x7OsMSgIGEhmTG6L/AsGXkoznMGosn+QVdC01PYWyRwqZ+mjxS9u1xHddBMvFdYdLaRuyCDky8jXWFO1QrLiUTklRo+Rqikkt1MktZEejM1UIK9RbkFQV1r1iRC17UZVEaxcpURUYcEqhiPsz0nj0rKr6IfK650gH5ezaONNODqnE1xAIIKIsVVXDosmIR1b94edsnUIoGxtRLm1OoVXwVWtVDnNTF03VeM1eUpqsbdjYRKKvsg0zDmUkKSKlI1Zcuw+NW+VWX8ePIRdSbheLjFwNBD8NBiWa1BOOe/gG5rMShUoBM78Dc+Slv+msxZ1RPkfoQbmYQY3qgI4E1QYzx+Zq3uAU9SyzVawfjd2LetMUxXtEW/SK8B50OT4T6iMaHY5QShVIEPH6h+TizVWlRIMoWFTRIjTi/kkJyCYWbFtTirijXlXNVUucHrX/t2vrWiNOlykuueNhZ1opTO/zEi20NNqhvc450qawYX4Df3XffWsoOGdf38PRqscOPmYpFG1ShlSyc5kyUQvurXSlNBGFicBU1F20WlPquk2VLlLFvzUUsVPrRIdvUCKqU6nudY83acNg1tK9MySvIHRIpeTk6iWErGfkMaM/orcPQ1rdbvdtShrXkVeyjCilqrkXVzqR6NtXhcorn+t1z1HxnNIrr77KyspS9LUIXtkayFUZPbV1g7WdWaPXfCsKYViwVySawXTeYIzJjq3av7Tq7bWPNxEKr+OQWrIs2p6I1umjN+011oSvrSfCyOrvpBaGhSp7R4e3+px0tXbbga+9le/WHMljjx70pHg4qSqCyMhLSU1c87XqzVpoCIbUjSuXgKYQcDbI4vKZskauvmrcgmhGJSRzglflSt/RtsBcMsc0t4TDksbibN4ZKSrwxJCiHnatRVFt96DIrkdttySX1K+ZE4v0dTXmFCdUFonmMcEOiJyMiLbq79+xOZJOo4ToAe6+j7WLX6r5mDe7SUGt8QaQHgk0Fd94skb9irR+XKp6KTIOr0t0lR1InKhrxkGba5LiRNRstZeGz1OTooePpjVtjMfPKuar6kNXKqq6ovugfVZEi4BoU2AaWsUhB0vQ1uJ5EJWX3605annVIkKREp1Ds3cBjRZZIeCHiIuU1V3FzBscinn72kQJ/K2RSIwFIJVHFUVNRNutCN820SvDdbAij5E1yIdGrhQMIWTjSyvCTU7MRqjUhZ4tdi6NZF9oZsVNSLZxf47sLYNTZMyl+hrRMyKpRueMyHN8p+coKqBU1GnuGCWVttNq7R8jql6LbnGaRu9AojamCm1HcUtUZDZutBqSQeoVj2hBtbgGcJETx4GXAljxZ+bs6WjtXIxRSLYq6gvDAqKGwkpSIoEM0gQnwSo1SZgp3tO8RBsJgnemMVduG+NnpbUeJ/Fdn6OBVme0hmKJTp9tljlk4iWq8qLfRirxuTJuQqPRJqgemVrPqugYlELbqf62WHSASuIdf1o2cNDMq9+SQqbexp2anKBo0fsiGMSR3EvW0ERfDRkYTSPef1oEHakLrJVEoYE09Aw+CVd/tKCwZ3IqSBn4Qygh+fnXNEeSBt8T4zj7rMZzNPjKV75KbbLT9idogVhIeNZjrdvaqsrsmESuo9Mjq6NCMq61DvwvXdzr35GihUBtKmNRm60hNh05OMfHMZQkqdN2rYtvg9LRJiSqhm0kO10BoZUBSiYtDBtLhNSuFFVwOnlo+K9xjhLfG+M4+6zGc/T/A8/G/snZpSWJAAAAAElFTkSuQmCC);
+  display: none;
+}
+
+* /deep/ quad-stack-view > #chrome-mid {
+  content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAABICAYAAADRa1RpAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAB3RJTUUH3QcNFycE5v9iFQAAAQtJREFUOMvtkjGSWzEMQx/0eYrM3v8k3vgqycalSwlI8Ufyl3OBFMtGIgUCIEd6PB6RBEASqvfONSrJXrDNbNkQ8ywA2y/SmayW+ZIESTsiyQsxo40xmMS2aUmYbheHpCVd0+UqJGGMsey3mUyldoUvlY3D9rIN0K7Wbe/WbZ+y1yWtaVtrp3VJzAEX6ZVjc2p7b2mtnYhNdl6m05rwtfV/ltx7XypJTpXeO7Y5juOlchzHaWxyrJmuhLapqgIJONv05+srThBgiQpBTSRwGOr3rwccgWHUhJ7P5/YNlbd/2XiL78L/WajP240AQUihfnx84EDJjCHKHjTAbkimQDgBjAJ1/3kHAgEk/gL71AHEWVXPGQAAAABJRU5ErkJggg==);
+  display: none;
+}
+
+* /deep/ quad-stack-view > #chrome-right {
+  content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAABICAYAAACaw4eEAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAB3RJTUUH3QcNFyghKmOqnQAADE1JREFUaN6dmsuyZsdRhb/M2uf07bREYDykPeIleAMibNx92i9BgEPBgyB5xlvgtgI8VDNBI41xhGkpQowERgqw3H0ue1cuBlm1T/3Vu4XNiWj9l12XrMyVK1fWL/v6668lCXdHEt/1Z2YnnyUhCTPbX8dn45pmRkR81z7/XUr59Pz8/K8ePnz47/bVV19pnDhu0t+Pmx0Z+Pv8zWv1/eZnZ2dntw8ePPizZXw4bj5/P3vq6G/eePZiX9fd9/Xng6/reg78/dInzxPG9+/auH83GjEbPUahj6m1Hoa6v1/X9c+XPrlP7INqrfuru7+10WzUkUHvOtTojPF1mPdHSzdqPPXo5vm046bdq0fhGr+bvXZk6OgAM2OZBx7hZD7hnCzbtp149Wid0YOjx+eE6t8tMzb659Ebkg5PPY8ZvXpEQWNCzck2M4H3BWeM1Fr31/6+GziPmTefM3tcYzQoIt4a3+cso2EzhsYTzAAdw9M9M3rviPv683dl/Oi9pdZKKeVk4piVRyDu1NI3mCtARFBKeWeGbtt2yHV9HXdnGUMyGjSfZq4K42ajYbPXx836XjO+jsj3rawcFx5dPgK8bzJ6eGbzI8yO3j4yaMToiWF98fl0c4bNSXBEJ/Ozd1HSEY8BLGOIxlONeCqlnHyWtGNoxteRMX38uP44fkyyPnfpp58zqy/s7jsGj0rOEcvPVaMD/sj4I/zWWllmMB/VviOwHumv+dkRGc9EOtOUu6fHZteOGBtDN/+NeJwPNRsxl54RU3PIO4x827a3wNwfdr45kib92WhAf9+fHem1I7FZa31rr+WIr45kzrjZsixvZWHHYcfqXFHGctM9ta7ridcigmVZWNf1DvyllN2wkatmHIxCby7kYzbPOD2qFCN39efrut55rE8YM3I+8VENHPFVa2VZlkOSdXe2bTuhmHdl+W5ox8T8YCbD/l2t9YQqRiNGjx8l1JEamVXKri56doyTuzfGhWd+OyLJjsNRlo+eHaX63Iy8ldnjQn3hbmA/yagGusfG7JwrxZytcxMyjpnH77VyPEEP65iVs5tntp4ldp8zlrG+x8z2Y9L1f91Jy+zeccGZn0Zv9nFHTH500BGbM6HOojMiWEZQf1cN7Aut68qyLCdeGFN+xuRYJ7tXu5fetU9EZCiPOp8xm8bTzLqpe2jkoDnzxjCOa8/VZByzzG7t8gQ4eT+GdO4Be0kZDTgq5kea/0g0RgS+rushNkbg93o6aqeejUeNR/fcUWmaqWLbtn39MdGWGcRHUrcb17E1jhszq3tvxNCsJuaE6VGZMbeMKTrL6LGelVL2k41jx6zuRbknSS9BI7WMdDRTxLi3z+VkDl3/7vb29oS3xhoZESdZOm4whrW/7/NHT83UtNze3u6c1I06Ozs7wdjc7PaQzsV8JNSOp7k97IDvtDPDYTdsvts6Pz8/MXCsm2PD2g/Tm+Vx0bHZHTNvjMyRyh2pajk/P0cIZEAHLLgXQLg5ckDCAFsKCwtIeHHAQGAmSnEkMAyZMBkin4lc3jBEM4a7MZgo7mBGhLD/+M1/qiCqDJflIjICYbknjlEtQEl81cBDYIaUi3aDwoEQ7mABuFMjcHOMQHLMRLSDhhlFQk4+k9IhLggZBREeVLN+NNwNCAhRwjGMimGyPJlA3owyIwiKEltWjTBHNchIGpLleIS5ITNKQHVDYRiBGUQI/83X/0XUyorhm2EKAsvT1IqFgwusgglCWARV3SuGmdNchwgiRHWQagcHIqCNJ7whJ6AI20AeUJ3A0ilP/vQJ33zzDdvNDbWkO91oAwphrah7wVGG1cHMqSHkggiwDJthmAcgjIIVg5rfWc1h2AZ7AgBLpMElMpQCUyOSX/3rr/j+9/+EGoEQTgKxKnDADRROmCiWySJBeILbMCxENVhwBISCnldm4EBEeiQRk1AJs/Y5ER2q7BX03v17SQnumDeXRqXgDaSA1cSdIExQDM+UgtoArTyMIjABJUPt4S2hRHEIgbdstV5LI4OusDvDMgMNqw3sHqi0HPcMotyRNqp5ArnmRrkLuBm4kHmjDAeEDMICk2PFMwomqjI2xYSHsJIUUnxoeBO7rdQUJ2qeJk8SLfdLGtgWCouEVzFUG7NXMAXVG1YqyDdMhSDgFuTpabUEiUguUw3AiAafbhoR4EtmpJknKArgytMaBHBmIozEIQ41M1dK7ySGEvxQ8NoI1w2WFh0XlsUaFYilJ5zhpuGKwBxXeygIqxlrE6Ih1wKPgi8L799/QGcJo4M5o9oYDfcKUZJmEFdX12zrikh2xwwrQA2KOeqETRlCGaKaUFXLpjQwy5Elu4dzflb4uw8/5MXP/wEsE6ORVX8hbVRzTVcN4ic/ec4HH3zA7XaTC1sQtZUXAm98Z7I7uvjii8+5ePw4pUiwu7TXuogM3cX7j/jhX/yIJz948gf/NPjll1/yy1/+E//z299RCGrL+AxI8krQfhk5Ab+6LmrGyDA1dvfkqOvXNzy7fMonn7w8umjafabmsDuowPPnz3nz5joLiN9VCwIqJDGHweixV59/weNHF4itZSMJbGq61kg3h3N2fs7D9x7jIdTwIzw3tCxrZo560U5U8frNFdu6URWJS8RmRukto3smv07uxwJrMa9uLDJCG1ZKI87AWJBvhEOsG9WEhSVcWBtu1A615da2kboiPaRW4hSRcBGEClhg0cTDycWdJR1XgUdkrN2hRqslGapydo+fffgRL37+Ir1opzrrJHZDAiB49vySv/3gp9zcRiqLCpsrjSLrnpQ27KH8/ItXPHz4PtRbRMoTajrBw6Hk4o8vLvjhj/6SH/w/wf/xx//I629/u9fPjkxLIZfVwmLwWBhQqUqgU1NZlCrkQVRwGW9urrl89pRPXr78gw27vHzO9dVVI2cIOYVIGHkrYXVDUQaPvXrFo4tHbFV7dnkjzGT+5BjXwnK/cPHovcRLI9hME3ZeM2+HtRwQAVdXb1ivr6ldzfYC3sSnPFAUZHW+HE7WtqamZL07avrcnYgKKtR6m/VKQTR9n0JQjZj7KqD2LCLY2h4quqsKNUWA5BQPatjAY1hTpuAO2iqlGLV1EQJ8C87vnfOzjz7ixS8+5vf93y+sFeZnl5f89K//htttw1bAW5d05rAK90awjOD//BUPHtynblmInXStyUHJR3jw3sV7/PjpU548eXJArvZ/gv/Fx7/g9bfftug4NfVKa7byd8pN9ZT5I9rFSM/wSPFXrOn5Tby5vubp0x/z8uU/t1Jx5/H9v3b3/q4YGJfPLrl+c0Pde8lgEWxN0znG1jG6e+zfXnHvwQNETdmMINqlSEeZJ1Dvn93j4uJiL+6jv8TQO9L6lya9f/fta26228wodVwZboFU2gLbqbqglZLarzTbdpvBEhWxNJI1bq5uuV6/SRCHt35AyAwPo5aKZzlIHRb5SqTR1nRSnitQtC4phNlyqvlTppRUlmZEQJizhCErbYSa57J8SNkLRm3s7RV54AHymjK9cYjUyg+wqV8XRCtfdzea+IZiFIoSsFKBEm1SE26SpXZCeDh7g9P64R4SrU2ZkC1btea5TMDsqCJ5UfUuZwO1BlnZ6tkgrWWWqjOgqhJmsLWa2dowsKZK0nuKlMWokWWBoBIeiJpZF6CqhtnMdHSHW6PdZLfijjISu2HX11dEjURrTza3BtymzaLV5NZwEGQYW4ekaLdCkXSDRCkidr2n/XKGUlOKjxc6oXZN0H4ZefXrVxQ3atTsjD1lkJpIDNEwlSCRZ53rp4zViNiQtqwEStHT1YoUOaclSY1MmmjXCelNz2Q1T5L/7LPPYDEePXqYNa0ENHnd7xeKKUFiAO2HBM97DZMoS1prMmQLrqCE8uZHIgVDNAFpFEW7BnGKWQtnYJ6GOmL54+99D0JEzfT1alRzikHtda+1/4nsxk/VqQZmlXXzJMUiqFu7nrJMe8v2LhteteuAvEcrVqk1m+Owdn9h7ZYSE6WAIrkjPCVIFua8s0jhWHfhZ5YZZ6rZNxoplZp3clg2uUSKAcmwYpgqUs1iFI5Z4rr3mliq3IVqVDbwM9CGkao1rN1IR6F4xepCEFht1wAhIKjRNH0Dv6ym5lHrEQw8JSlUtapghHJ+qiK13OyZ6yyf/sunSYqyVuPavVVq3bvSgrKxcKVGU7/s1U5ovXz1W5v9ftPVet68cbSehRo65ZNfUuB/AWHLchVUWJtFAAAAAElFTkSuQmCC);
+  display: none;
+}
+</style><template id="quad-stack-view-template">
+  <div id="header"></div>
+  <input id="stacking-distance-slider" max="400" min="1" step="1" type="range"/>
+  
+  <canvas id="canvas"></canvas>
+  <img id="chrome-left"/>
+  <img id="chrome-mid"/>
+  <img id="chrome-right"/>
+</template><style>
+* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view {
+  position: relative;
+}
+
+* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view > top-controls {
+  -webkit-flex: 0 0 auto;
+  background-image: -webkit-gradient(linear,
+                                     0 0, 100% 0,
+                                     from(#E5E5E5),
+                                     to(#D1D1D1));
+  border-bottom: 1px solid #8e8e8e;
+  border-top: 1px solid white;
+  display: flex;
+  flex-flow: row wrap;
+  flex-direction: row;
+  font-size:  14px;
+  padding-left: 2px;
+  overflow: hidden;
+}
+
+* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view >
+      top-controls input[type='checkbox'] {
+  vertical-align: -2px;
+}
+
+* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view > .what-rasterized {
+  color: -webkit-link;
+  cursor: pointer;
+  text-decoration: underline;
+  position: absolute;
+  bottom: 10px;
+  left: 10px;
+}
+
+* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view > #input-event {
+  content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMnwAADJ8BPja39wAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAyNSURBVHic7Z1PTCPXHcc/4wWWVbJN2cJSLVqiQJuGpoIGEVWReoBNIlIF5RCRSysOK9EbksUeOHLIIQcULbLEEYk7oqduD6gSRoqUEyK7dCOabOHghCiAE/JntQtesHt4fuM3z2+MZzy2x8ZfaTTjN+Px4/fh9/7Pb6xMJkND4VGk2hloyKkGkJCpASRkagAJmRpAQqYGkJCpASRkaqp2BvzKsizf3w1z38sKc+ZUaQCuAFeB57P7q4AF/Kxsj4GnLrfL+6PDYofQAskCaAJ6gJeB6+QAFOvZpwgwPwOHwCNgN5uu/+H252raJHRALMu6ggDwCtALNAf8E88QUL5AAHqSTVcNUTU4oQBiWVYzMIiA0E3lGhtp4CsEnPtACgFDGqXiYKoKxLKsCPAaMIwojlzV1tZGV1cXHR0ddHR00N7ebh93dHQAcHh4aG/JZNI+3tvb4+jo6LzsPAY+QYA5Ix9KBsoPpmpALMt6BXgTaHe7pre3l5GREUZGRujv7/fdsspkMmxtbRGPx4nH4+zs7BS6/HtgHfgvOW9xeE05bVZxIJZldQNvATf1c5FIhMHBQYaHh7l16xbd3d1lyUMikWBtbY319XU2NzdJp9Omy74B1oAEAoa8yIZTDttVDIhlWZeB94Dfm86Pjo4SjUbLBsFNiUSCWCzG6uqq2yVfAv9CNKHTlNlbKgLEsqxrwF+BX+nnhoaGuHPnDv39/WXPRyFtbW1x9+5dNjY2TKePgBXgOwQUFUyg3lJ2IJZl9QAfAK1qek9PD9PT04yMjJT1970qHo8zPz/P7u6ufuoE+CewQw6Kw2OCsGVZgViW9SdgFNGLBqC1tZWZmRnGx8eJRMI5lJZOp1lZWWFubo7j42P1VAZR4W8gWmJn5KBAAEVYWYBkm7PvIvoWtjo7O1lYWKCvry/w3yyHtre3mZqaYn9/Xz/1EPg3ot+iQslQIpTAgWRh/A0x5GFrYGCAWCxGe7trKzeUSiaTRKNRHjx4oJ/6CvgHoigLDEo5yox30WCMjY2xtLRUczAA2tvbWVpaYmxsTD91E3gbMbTTBFxCFM0WYPntMwXqIdk64x3lM9FolMnJycB+o5paXFwkFovplfcniDrlNLvJXr4vTwnMQ7KtqVE1rZ5gAExOThKNRvXkPyMGQaWXlOQpgQDJ9jM+QGlNjY2N1RUMqcnJSb34shClwnVE8aVCAY9QSi6ysj3wv6N0+gYGBlhaWqKlpaWke4dVqVSK27dv6xX9j8AyYpDyGaL4svsqxdo5CA95DwVGZ2cnsVisbmEAtLS0EIvF6OzsVJNfQIzRlVTJlwQkO1Boj021traysLBQk60pr2pvb2dhYYHWVscAxEuI1pcKJYIHKKV6yFvqh5mZmZrp9AWhvr4+ZmZm9OQ3MAMpSr6BZOcz7CH0np4exsfH/d6uZjU+Pk5Pj6PbdR34LT69xBeQbG/8TTVteno6tGNT5VQkEmF6elpPfh24TK7VFaFIKH4t+BrKTN/Q0FDoRm0rqZGREYaGhtSkXyDqVs9Fl2cg2QUJw2ranTt3vN6m7mSwwR8R68dULzm31eXHQwZRFiSMjo5WfXIpDOrv72d01DFQcQXoQ3hI0V7iB8gr9pcjEdNQwoVVNBrV69EXcanccfEST0Cyi9jsSe/BwcGKz4GHWd3d3QwOOqaAOoDnMFfuRnn1kJfV7wwPD3v8ev1Ls4mF+Ac2FVsW5C8aLxpI9ou/U9Nu3brlOcP1LoNNbuJej+R5ihcPaQJ+Iz/09vY2iiuDuru76e3tVZN+jeiTyFHggsWWFyA9KAufL3K/4zxptrkE3MClYkcDUxQQU3HVAOIug226yHlIXvNXrUe8eEiHPGhra2v0PQqov7+ftrY2NekFzEVWSXWI3Rns6uoq6ZGyepdlWXR1dalJrRTwEFVegFyVB3L5f0Pu0mzUirC1CsPoJcUCuYLyGFkDyPnSbBQhB8VUZNm99nOBZC+8qqZdhBnBUmWw0RXMQHx5iOPpprB5yMbGBp999lm1s+GQwUZXKFBUSRULxOEhYQNy//59Hj58WO1sOOQCpGAfBOoESBhVwENMm61in/cOXRt3f3+f09NTAH766SdaWlrY29sDoLm5mevXr1cze25y9QypYoH8rH44PDwsIU/B6KOPPrLzcXBwQCQS4dNPPwXgxo0bfPzxx9XMnslGJ7h7hkX2GZOaBRKLxezjxcVFLl++zMTERBVz5JTBRseGy3zXIaEDEna5eAgENIX7WP2QTCaL/NrFlcFG0kMKLvIttsh6ilg83ATh85D3338/dGNrmo3SiAXYuvLgeImX9Rj4peHHqq5r165VOwt50mx0gjkqhJT92cvgol2P7O3thSa+VBiVyWTsJnhWsv4wBrZR5QWIjfzo6IitrS0vebxQ2tra0oPdPCbfQ4ze4gXII/VDPB73k9cLIYNtDnACUJ9td8gLkF2UiqkBxF2abc6AJOboD3lQzgWi1BWnCCgA7OzskEgk/Oa5bpVIJPTwT9+RCymoe4jvIkt+8Qs1cW1tzVem61kGm8jiKk1+gIE8eV25+Ihc3CjW19c9fr3+pdkkgwCiwsiL+oDyUKhXIE8QISUA2NzcbBRbihKJBJubm2rSD4h4KLLuOMMQRUiVn9XvdrGVTqcdg3wXXbFYTI9Op3qHuqlQHCoKSNadJNH7KGNbq6urjT4Jou+hRaVLIUoTE4zA6hD5Q5+oCXfv3vVxm/qSwQY7iG6C9BAZByWv6auOevgBIr3ke5mwsbFxofsl8XhcDw34BPgaYXg1KI0p6JlDRQPRiq0zRGQ1W/Pz827RPeta6XSa+fl5Pfl/5LxC3QrCAP9P4WYQcW2/kQm7u7usrKz4vF3tamVlRY/P+CPwLTlvcANiDN/kCYjiJXLv6AXNzc2xvb3t5ZY1re3tbebm5vRk2Vc7JReExgTDqFI8JIMIMvylTDw+PmZqaupCzCgmk0mmpqb0IJkHiLpV9Ypn5MA4oJimMDwD0eqSDCLIsD3WvL+/TzQaJZVKeb11zSiVShGNRvXgmE+Az8kVU8+UrSjvgNKCz8jxmaeIIMNyEoYHDx4wOztbwq3DrdnZWT1W1imi5XmCE0YKlyLLbYLPFxDlZhLKd4ggw/aJe/fusbi46Of2odbi4iL37t1TkzLAfxAzqmc4PcPkIQVVqofIfRrREVpXL4jFYnUFRQbB1PQIMZsqYaSUraiWlaqSQvxlV3rIFd2XEIsm/gL8Qb1ubGyMDz/8sGajzKVSKWZnZ3XPANHs/xxh+BSiyDrObifkirCiiisIDogK5TIwjvY6ijoMpHwEbCJAPCMHQIWhxl4sKmxsEEEwwQmlCQHlbeBV9do6CjX+DbBNDobqHSYYRQfCLDnimKEZfJbN0CpiENLOxf7+PhMTEywvL4d6mCWdTrO8vMzExIQOI4Pod31OPowTzHWHpz80kMjWyqpB6SXSU5oRQYbfARwVSA2+ruIU0ZrSK/ATnEBky8oxqlusnQMLNa4VXRa5Sr4JEYdwDPG8tkM18kKXJ+TmgWQ/Q3qDDsNTJa4r6NjvkA/lEsJTnkdEMX3J9N0Qv/LoAFFEyRaTbFFJGPK4ZBhQntdVgDuUZkTr6w2E1zgUspeC/YjoY3yPczgkZdhk568kGFC+F7qAE4qsU2S90owIpfo6ImCkUVV6bd4TxHzGtzgnmNThEN0rHK0pSngFUtleeeQCRa1XmhHN41eBAcRDka6qwIslU4jRhq/Jn8tQh0HUitttWtb3YvRyv4MKck8MyUeCZRGmeosMGPkiIshNpR72yCCW6hwgFiTI1pE0tDS6abDQ87BIMarEW9rAGUFNNot1MHL/HCIs3k1E8K9LAWfpDDEYepDd5Lopdc5b9Qx9r14nx/EgABhQASCQ109RizAdjApH9vhvIOJNvYCIFyJjhhSjNLlm6WMEgCS5tbbqAjbTlKsKwwTCHmCtmfcY2j/khCL3auwPNXyRGqOwifzQRq2IYk7dwDl8cYwwpjoqrRrSDYYKpdCaqpLrC5Oq8S5c+xCzx+hwTJtbEBdT3aMbUBpVXWvrtsnz+op1CNArVFXlbdEu3mICowJS9+cBsR/Exx2IaQG0af1tHggI1itUVft96vahsi/kOabPxQCRe93IaW3TAVQMhFRVgdiZMIORexOgQiDkXv3DdAObPMYIgAqBkAoFECmtJ+4Gp9Ax2rEORe51w+sQ7OOK17FhAqLKBY567AbBTSY4rsfVsktogagqACfvUpd0tz/SkR4GW9QEEFVBhtAI499ec0DqXf8H8f4X10jf2YAAAAAASUVORK5CYII=);
+  display: none;
+}
+</style><template id="tr-ui-e-chrome-cc-layer-tree-quad-stack-view-template">
+  <img id="input-event"/>
+</template><style>
+* /deep/ tr-ui-e-chrome-cc-layer-view{-webkit-flex-direction:column;display:-webkit-flex;left:0;position:relative;top:0}* /deep/ tr-ui-e-chrome-cc-layer-view>tr-ui-e-chrome-cc-layer-tree-quad-stack-view{-webkit-flex:1 1 100%;-webkit-flex-direction:column;min-height:0;display:-webkit-flex;width:100%}* /deep/tr-ui-e-chrome-cc- layer-view>tr-ui-e-chrome-cc-layer-view-analysis{height:150px;overflow-y:auto}* /deep/ tr-ui-e-chrome-cc-layer-view>tr-ui-e-chrome-cc-layer-view-analysis *{-webkit-user-select:text}
+</style><style>
+* /deep/ .tr-ui-e-chrome-cc-lthi-s-view{-webkit-flex:1 1 auto!important;-webkit-flex-direction:row;display:-webkit-flex}* /deep/ .tr-ui-e-chrome-cc-lthi-s-view>tr-ui-e-chrome-cc-layer-picker{-webkit-flex:1 1 auto}* /deep/ .tr-ui-e-chrome-cc-lthi-s-view>x-drag-handle{-webkit-flex:0 0 auto}
+</style><style>
+* /deep/ tr-ui-e-chrome-cc-picture-ops-chart-summary-view{-webkit-flex:0 0 auto;font-size:0;margin:0;min-height:200px;min-width:200px;overflow:hidden;padding:0}* /deep/ tr-ui-e-chrome-cc-picture-ops-chart-summary-view.hidden{display:none}
+</style><style>
+* /deep/ tr-ui-e-chrome-cc-picture-ops-chart-view{display:block;height:180px;margin:0;padding:0;position:relative}* /deep/ tr-ui-e-chrome-cc-picture-ops-chart-view>.use-percentile-scale{left:0;position:absolute;top:0}
+</style><template id="tr-ui-e-chrome-cc-picture-debugger-template">
+  <style>
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger {
+    -webkit-flex: 1 1 auto;
+    -webkit-flex-direction: row;
+    display: -webkit-flex;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger > tr-ui-a-generic-object-view {
+    -webkit-flex-direction: column;
+    display: -webkit-flex;
+    width: 400px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger > left-panel {
+    -webkit-flex-direction: column;
+    display: -webkit-flex;
+    min-width: 300px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger > left-panel > picture-info {
+    -webkit-flex: 0 0 auto;
+    padding-top: 2px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger > left-panel >
+        picture-info .title {
+    font-weight: bold;
+    margin-left: 5px;
+    margin-right: 5px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger > x-drag-handle {
+    -webkit-flex: 0 0 auto;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger .filename {
+    -webkit-user-select: text;
+    margin-left: 5px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger > right-panel {
+    -webkit-flex: 1 1 auto;
+    -webkit-flex-direction: column;
+    display: -webkit-flex;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger > right-panel >
+        tr-ui-e-chrome-cc-picture-ops-chart-view {
+    min-height: 150px;
+    min-width : 0;
+    overflow-x: auto;
+    overflow-y: hidden;
+  }
+
+  /*************************************************/
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger raster-area {
+    background-color: #ddd;
+    min-height: 200px;
+    min-width: 200px;
+    overflow-y: auto;
+    padding-left: 5px;
+  }
+  </style>
+
+  <left-panel>
+    <picture-info>
+      <div>
+        <span class="title">Skia Picture</span>
+        <span class="size"></span>
+      </div>
+      <div>
+        <input class="filename" type="text" value="skpicture.skp"/>
+        <button class="export">Export</button>
+      </div>
+    </picture-info>
+  </left-panel>
+  <right-panel>
+    <tr-ui-e-chrome-cc-picture-ops-chart-view>
+    </tr-ui-e-chrome-cc-picture-ops-chart-view>
+    <raster-area><canvas></canvas></raster-area>
+  </right-panel>
+</template><style>
+* /deep/ .tr-ui-e-chrome-cc-picture-snapshot-view{-webkit-flex:0 1 auto!important;display:-webkit-flex}
+</style><polymer-element name="tr-ui-e-chrome-cc-raster-task-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+    }
+    #heading {
+      flex: 0 0 auto;
+    }
+    </style>
+
+    <div id="heading">
+      Rasterization costs in
+      <tr-ui-a-analysis-link id="link"></tr-ui-a-analysis-link>
+    </div>
+    <tr-ui-b-table id="content"></tr-ui-b-table>
+  </template>
+
+  
+</polymer-element><style>
+.tr-ui-e-chrome-gpu-state-snapshot-view{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAAZiS0dEAEwATABMYqp3KAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB90JCQsBMCH7ZqYAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAUElEQVRYw+3WwQkAIAiF4Vc0hTO5/wiuURvYIcQOv1cRPhDlDXffSsrMsrYiQi/zU80FAACAVX3nt3lWAABA/x+ovnPyAAAA5AHyAAAA3wMOd34Xd+lsglgAAAAASUVORK5CYII=);display:-webkit-flex;overflow:auto}.tr-ui-e-chrome-gpu-state-snapshot-view img{display:block;margin:16px auto 16px auto}
+</style><style>
+.tr-ui-e-system-stats-snapshot-view .subhead{font-size:small;padding-bottom:10px}.tr-ui-e-system-stats-snapshot-view ul{background-position:0 5px;background-repeat:no-repeat;cursor:pointer;font-family:monospace;list-style:none;margin:0;padding-left:15px}.tr-ui-e-system-stats-snapshot-view li{background-position:0 5px;background-repeat:no-repeat;cursor:pointer;list-style:none;margin:0;padding-left:15px}
+</style><style>
+.tr-ui-e-system-stats-instance-track{height:500px}.tr-ui-e-system-stats-instance-track ul{list-style:none;list-style-position:outside;margin:0;overflow:hidden}
+</style><style>
+.tr-ui-e-tcmalloc-instance-view .subhead{font-size:small;padding-bottom:10px}.tr-ui-e-tcmalloc-instance-view #args{white-space:pre}.tr-ui-e-tcmalloc-instance-view #snapshots>*{display:block}.tr-ui-e-tcmalloc-instance-view{overflow:auto}.tr-ui-e-tcmalloc-instance-view *{-webkit-user-select:text}.tr-ui-e-tcmalloc-instance-view .title{border-bottom:1px solid rgb(128,128,128);font-size:110%;font-weight:bold}.tr-ui-e-tcmalloc-instance-view td,.tr-ui-e-tcmalloc-instance-view th{font-size:small;text-align:right}
+</style><style>
+.tr-ui-e-tcmalloc-heap-snapshot-view .subhead{font-size:small;padding-bottom:10px}.tr-ui-e-tcmalloc-heap-snapshot-view ul{background-position:0 5px;background-repeat:no-repeat;cursor:pointer;font-family:monospace;list-style:none;margin:0;padding-left:15px}.tr-ui-e-tcmalloc-heap-snapshot-view li{background-position:0 5px;background-repeat:no-repeat;cursor:pointer;list-style:none;margin:0;padding-left:15px}.tr-ui-e-tcmalloc-heap-snapshot-view .collapsed{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAMAAADz0U65AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAwBQTFRFAAAAVVVVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASd3+7gAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAZdEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjbQg61aAAAAGklEQVQYV2P4//8/IyOQYMBkMEIBA5yBWzEAD3Mj+VR5R78AAAAASUVORK5CYII=)}.tr-ui-e-tcmalloc-heap-snapshot-view .expanded{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAABl0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuNtCDrVoAAAAoSURBVChTY2CgKggNDVUHYnsUQ4EC//FhBoIKkI0DKlYAYhmqupsBAMwgJH8K5nKoAAAAAElFTkSuQmCC)}.tr-ui-e-tcmalloc-heap-snapshot-view .trace-bytes{display:inline-block;padding-right:10px;text-align:right;width:80px}.tr-ui-e-tcmalloc-heap-snapshot-view .trace-allocs{display:inline-block;padding-right:10px;text-align:right;width:120px}.tr-ui-e-tcmalloc-heap-snapshot-view .trace-name{display:inline-block}
+</style><style>
+.tr-ui-e-tcmalloc-heap-instance-track{height:150px}.tr-ui-e-tcmalloc-heap-instance-track ul{list-style:none;list-style-position:outside;margin:0;overflow:hidden}
+</style><polymer-element extends="tr-ui-side-panel" name="tr-ui-e-s-category-summary-side-panel">
+  <template>
+    <style>
+    :host {
+      display: block;
+      width: 450px;
+      overflow-x: auto;
+    }
+    </style>
+
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-side-panel" name="tr-ui-e-s-input-latency-side-panel">
+  <template>
+    <style>
+    :host {
+      flex-direction: column;
+      display: flex;
+    }
+    toolbar {
+      flex: 0 0 auto;
+      border-bottom: 1px solid black;
+      display: flex;
+    }
+    result-area {
+      flex: 1 1 auto;
+      display: block;
+      min-height: 0;
+      overflow-y: auto;
+    }
+    </style>
+
+    <toolbar id="toolbar"></toolbar>
+    <result-area id="result_area"></result-area>
+  </template>
+
+  
+</polymer-element><style>
+* /deep/ .pie-chart .arc-text{font-size:8pt}* /deep/ .pie-chart .label{font-size:10pt}* /deep/ .pie-chart polyline{fill:none;stroke:black}
+</style><polymer-element extends="tr-ui-side-panel" name="tr-ui-e-s-time-summary-side-panel">
+  <template>
+    <style>
+    :host {
+      flex-direction: column;
+      display: flex;
+    }
+    toolbar {
+      flex: 0 0 auto;
+      border-bottom: 1px solid black;
+      display: flex;
+    }
+    result-area {
+      flex: 1 1 auto;
+      display: block;
+      min-height: 0;
+      overflow-y: auto;
+    }
+    </style>
+
+    <toolbar id="toolbar"></toolbar>
+    <result-area id="result_area"></result-area>
+  </template>
+
+  
+</polymer-element><polymer-element name="tr-ui-e-rail-rail-score-span">
+  <template>
+  <style>
+    :host {
+      display: span;
+    }
+  </style>
+  <span id="content">
+    <span>RAIL Score: </span><span id="score"></span>
+  </span>
+  </template>
+  
+</polymer-element><polymer-element extends="tr-ui-side-panel" name="tr-ui-e-rail-rail-score-side-panel">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+      width: 450px;
+      overflow-x: auto;
+    }
+
+    #score {
+      background-color: rgb(236, 236, 236)
+      flex: 0 0 auto;
+    }
+
+    #content {
+      min-width: 0;
+      flex-direction: column;
+      display: flex;
+      flex: 1 1 auto;
+    }
+
+    #coverage {
+      font-size: 10px;
+    }
+    </style>
+
+    <tr-ui-e-rail-rail-score-span id="score"></tr-ui-e-rail-rail-score-span>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+
+    <div id="coverage">
+      <b>Coverage:</b><br/>
+      <tr-ui-a-analysis-link id="associated-events"></tr-ui-a-analysis-link><br/>
+      <tr-ui-a-analysis-link id="unassociated-events"></tr-ui-a-analysis-link>
+    </div>
+    <button id="test">Create Test</button>
+  </template>
+</polymer-element><polymer-element extends="tr-ui-side-panel" name="tr-ui-e-s-alerts-side-panel">
+  <template>
+    <style>
+    :host {
+      display: block;
+      width: 250px;
+    }
+    #content {
+      flex-direction: column;
+      display: flex;
+    }
+    </style>
+
+    <div id="content">
+      <toolbar id="toolbar"></toolbar>
+      <result-area id="result_area"></result-area>
+    </div>
+  </template>
+
+  
+</polymer-element><script>
+
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/* WARNING: This file is auto generated.
+ *
+ * Do not edit directly.
+ */
+
+/**
+ * @license
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// @version 0.5.5
+window.PolymerGestures={},function(a){var b=!1,c=document.createElement("meta");if(c.createShadowRoot){var d=c.createShadowRoot(),e=document.createElement("span");d.appendChild(e),c.addEventListener("testpath",function(a){a.path&&(b=a.path[0]===e),a.stopPropagation()});var f=new CustomEvent("testpath",{bubbles:!0});document.head.appendChild(c),e.dispatchEvent(f),c.parentNode.removeChild(c),d=e=null}c=null;var g={shadow:function(a){return a?a.shadowRoot||a.webkitShadowRoot:void 0},canTarget:function(a){return a&&Boolean(a.elementFromPoint)},targetingShadow:function(a){var b=this.shadow(a);return this.canTarget(b)?b:void 0},olderShadow:function(a){var b=a.olderShadowRoot;if(!b){var c=a.querySelector("shadow");c&&(b=c.olderShadowRoot)}return b},allShadows:function(a){for(var b=[],c=this.shadow(a);c;)b.push(c),c=this.olderShadow(c);return b},searchRoot:function(a,b,c){var d,e;return a?(d=a.elementFromPoint(b,c),d?e=this.targetingShadow(d):a!==document&&(e=this.olderShadow(a)),this.searchRoot(e,b,c)||d):void 0},owner:function(a){if(!a)return document;for(var b=a;b.parentNode;)b=b.parentNode;return b.nodeType!=Node.DOCUMENT_NODE&&b.nodeType!=Node.DOCUMENT_FRAGMENT_NODE&&(b=document),b},findTarget:function(a){if(b&&a.path&&a.path.length)return a.path[0];var c=a.clientX,d=a.clientY,e=this.owner(a.target);return e.elementFromPoint(c,d)||(e=document),this.searchRoot(e,c,d)},findTouchAction:function(a){var c;if(b&&a.path&&a.path.length){for(var d=a.path,e=0;e<d.length;e++)if(c=d[e],c.nodeType===Node.ELEMENT_NODE&&c.hasAttribute("touch-action"))return c.getAttribute("touch-action")}else for(c=a.target;c;){if(c.nodeType===Node.ELEMENT_NODE&&c.hasAttribute("touch-action"))return c.getAttribute("touch-action");c=c.parentNode||c.host}return"auto"},LCA:function(a,b){if(a===b)return a;if(a&&!b)return a;if(b&&!a)return b;if(!b&&!a)return document;if(a.contains&&a.contains(b))return a;if(b.contains&&b.contains(a))return b;var c=this.depth(a),d=this.depth(b),e=c-d;for(e>=0?a=this.walk(a,e):b=this.walk(b,-e);a&&b&&a!==b;)a=a.parentNode||a.host,b=b.parentNode||b.host;return a},walk:function(a,b){for(var c=0;a&&b>c;c++)a=a.parentNode||a.host;return a},depth:function(a){for(var b=0;a;)b++,a=a.parentNode||a.host;return b},deepContains:function(a,b){var c=this.LCA(a,b);return c===a},insideNode:function(a,b,c){var d=a.getBoundingClientRect();return d.left<=b&&b<=d.right&&d.top<=c&&c<=d.bottom},path:function(a){var c;if(b&&a.path&&a.path.length)c=a.path;else{c=[];for(var d=this.findTarget(a);d;)c.push(d),d=d.parentNode||d.host}return c}};a.targetFinding=g,a.findTarget=g.findTarget.bind(g),a.deepContains=g.deepContains.bind(g),a.insideNode=g.insideNode}(window.PolymerGestures),function(){function a(a){return"html /deep/ "+b(a)}function b(a){return'[touch-action="'+a+'"]'}function c(a){return"{ -ms-touch-action: "+a+"; touch-action: "+a+";}"}var d=["none","auto","pan-x","pan-y",{rule:"pan-x pan-y",selectors:["pan-x pan-y","pan-y pan-x"]},"manipulation"],e="",f="string"==typeof document.head.style.touchAction,g=!window.ShadowDOMPolyfill&&document.head.createShadowRoot;if(f){d.forEach(function(d){String(d)===d?(e+=b(d)+c(d)+"\n",g&&(e+=a(d)+c(d)+"\n")):(e+=d.selectors.map(b)+c(d.rule)+"\n",g&&(e+=d.selectors.map(a)+c(d.rule)+"\n"))});var h=document.createElement("style");h.textContent=e,document.head.appendChild(h)}}(),function(a){var b=["bubbles","cancelable","view","detail","screenX","screenY","clientX","clientY","ctrlKey","altKey","shiftKey","metaKey","button","relatedTarget","pageX","pageY"],c=[!1,!1,null,null,0,0,0,0,!1,!1,!1,!1,0,null,0,0],d=function(){return function(){}},e={preventTap:d,makeBaseEvent:function(a,b){var c=document.createEvent("Event");return c.initEvent(a,b.bubbles||!1,b.cancelable||!1),c.preventTap=e.preventTap(c),c},makeGestureEvent:function(a,b){b=b||Object.create(null);for(var c,d=this.makeBaseEvent(a,b),e=0,f=Object.keys(b);e<f.length;e++)c=f[e],"bubbles"!==c&&"cancelable"!==c&&(d[c]=b[c]);return d},makePointerEvent:function(a,d){d=d||Object.create(null);for(var e,f=this.makeBaseEvent(a,d),g=2;g<b.length;g++)e=b[g],f[e]=d[e]||c[g];f.buttons=d.buttons||0;var h=0;return h=d.pressure?d.pressure:f.buttons?.5:0,f.x=f.clientX,f.y=f.clientY,f.pointerId=d.pointerId||0,f.width=d.width||0,f.height=d.height||0,f.pressure=h,f.tiltX=d.tiltX||0,f.tiltY=d.tiltY||0,f.pointerType=d.pointerType||"",f.hwTimestamp=d.hwTimestamp||0,f.isPrimary=d.isPrimary||!1,f._source=d._source||"",f}};a.eventFactory=e}(window.PolymerGestures),function(a){function b(){if(c){var a=new Map;return a.pointers=d,a}this.keys=[],this.values=[]}var c=window.Map&&window.Map.prototype.forEach,d=function(){return this.size};b.prototype={set:function(a,b){var c=this.keys.indexOf(a);c>-1?this.values[c]=b:(this.keys.push(a),this.values.push(b))},has:function(a){return this.keys.indexOf(a)>-1},"delete":function(a){var b=this.keys.indexOf(a);b>-1&&(this.keys.splice(b,1),this.values.splice(b,1))},get:function(a){var b=this.keys.indexOf(a);return this.values[b]},clear:function(){this.keys.length=0,this.values.length=0},forEach:function(a,b){this.values.forEach(function(c,d){a.call(b,c,this.keys[d],this)},this)},pointers:function(){return this.keys.length}},a.PointerMap=b}(window.PolymerGestures),function(a){var b,c=["bubbles","cancelable","view","detail","screenX","screenY","clientX","clientY","ctrlKey","altKey","shiftKey","metaKey","button","relatedTarget","buttons","pointerId","width","height","pressure","tiltX","tiltY","pointerType","hwTimestamp","isPrimary","type","target","currentTarget","which","pageX","pageY","timeStamp","preventTap","tapPrevented","_source"],d=[!1,!1,null,null,0,0,0,0,!1,!1,!1,!1,0,null,0,0,0,0,0,0,0,"",0,!1,"",null,null,0,0,0,0,function(){},!1],e="undefined"!=typeof SVGElementInstance,f=a.eventFactory,g={IS_IOS:!1,pointermap:new a.PointerMap,requiredGestures:new a.PointerMap,eventMap:Object.create(null),eventSources:Object.create(null),eventSourceList:[],gestures:[],dependencyMap:{down:{listeners:0,index:-1},up:{listeners:0,index:-1}},gestureQueue:[],registerSource:function(a,b){var c=b,d=c.events;d&&(d.forEach(function(a){c[a]&&(this.eventMap[a]=c[a].bind(c))},this),this.eventSources[a]=c,this.eventSourceList.push(c))},registerGesture:function(a,b){var c=Object.create(null);c.listeners=0,c.index=this.gestures.length;for(var d,e=0;e<b.exposes.length;e++)d=b.exposes[e].toLowerCase(),this.dependencyMap[d]=c;this.gestures.push(b)},register:function(a,b){for(var c,d=this.eventSourceList.length,e=0;d>e&&(c=this.eventSourceList[e]);e++)c.register.call(c,a,b)},unregister:function(a){for(var b,c=this.eventSourceList.length,d=0;c>d&&(b=this.eventSourceList[d]);d++)b.unregister.call(b,a)},down:function(a){this.requiredGestures.set(a.pointerId,b),this.fireEvent("down",a)},move:function(a){a.type="move",this.fillGestureQueue(a)},up:function(a){this.fireEvent("up",a),this.requiredGestures["delete"](a.pointerId)},cancel:function(a){a.tapPrevented=!0,this.fireEvent("up",a),this.requiredGestures["delete"](a.pointerId)},addGestureDependency:function(a,b){var c=a._pgEvents;if(c&&b)for(var d,e,f,g=Object.keys(c),h=0;h<g.length;h++)f=g[h],c[f]>0&&(d=this.dependencyMap[f],e=d?d.index:-1,b[e]=!0)},eventHandler:function(c){var d=c.type;if("touchstart"===d||"mousedown"===d||"pointerdown"===d||"MSPointerDown"===d)if(c._handledByPG||(b={}),this.IS_IOS){var e=c;if("touchstart"===d){var f=c.changedTouches[0];e={target:c.target,clientX:f.clientX,clientY:f.clientY,path:c.path}}for(var g,h=c.path||a.targetFinding.path(e),i=0;i<h.length;i++)g=h[i],this.addGestureDependency(g,b)}else this.addGestureDependency(c.currentTarget,b);if(!c._handledByPG){var j=this.eventMap&&this.eventMap[d];j&&j(c),c._handledByPG=!0}},listen:function(a,b){for(var c,d=0,e=b.length;e>d&&(c=b[d]);d++)this.addEvent(a,c)},unlisten:function(a,b){for(var c,d=0,e=b.length;e>d&&(c=b[d]);d++)this.removeEvent(a,c)},addEvent:function(a,b){a.addEventListener(b,this.boundHandler)},removeEvent:function(a,b){a.removeEventListener(b,this.boundHandler)},makeEvent:function(a,b){var c=f.makePointerEvent(a,b);return c.preventDefault=b.preventDefault,c.tapPrevented=b.tapPrevented,c._target=c._target||b.target,c},fireEvent:function(a,b){var c=this.makeEvent(a,b);return this.dispatchEvent(c)},cloneEvent:function(a){for(var b,f=Object.create(null),g=0;g<c.length;g++)b=c[g],f[b]=a[b]||d[g],("target"===b||"relatedTarget"===b)&&e&&f[b]instanceof SVGElementInstance&&(f[b]=f[b].correspondingUseElement);return f.preventDefault=function(){a.preventDefault()},f},dispatchEvent:function(a){var b=a._target;if(b){b.dispatchEvent(a);var c=this.cloneEvent(a);c.target=b,this.fillGestureQueue(c)}},gestureTrigger:function(){for(var a,b,c=0;c<this.gestureQueue.length;c++)if(a=this.gestureQueue[c],b=a._requiredGestures)for(var d,e,f=0;f<this.gestures.length;f++)b[f]&&(d=this.gestures[f],e=d[a.type],e&&e.call(d,a));this.gestureQueue.length=0},fillGestureQueue:function(a){this.gestureQueue.length||requestAnimationFrame(this.boundGestureTrigger),a._requiredGestures=this.requiredGestures.get(a.pointerId),this.gestureQueue.push(a)}};g.boundHandler=g.eventHandler.bind(g),g.boundGestureTrigger=g.gestureTrigger.bind(g),a.dispatcher=g,a.activateGesture=function(a,b){var c=b.toLowerCase(),d=g.dependencyMap[c];if(d){var e=g.gestures[d.index];if(a._pgListeners||(g.register(a),a._pgListeners=0),e){var f,h=e.defaultActions&&e.defaultActions[c];switch(a.nodeType){case Node.ELEMENT_NODE:f=a;break;case Node.DOCUMENT_FRAGMENT_NODE:f=a.host;break;default:f=null}h&&f&&!f.hasAttribute("touch-action")&&f.setAttribute("touch-action",h)}a._pgEvents||(a._pgEvents={}),a._pgEvents[c]=(a._pgEvents[c]||0)+1,a._pgListeners++}return Boolean(d)},a.addEventListener=function(b,c,d,e){d&&(a.activateGesture(b,c),b.addEventListener(c,d,e))},a.deactivateGesture=function(a,b){var c=b.toLowerCase(),d=g.dependencyMap[c];return d&&(a._pgListeners>0&&a._pgListeners--,0===a._pgListeners&&g.unregister(a),a._pgEvents&&(a._pgEvents[c]>0?a._pgEvents[c]--:a._pgEvents[c]=0)),Boolean(d)},a.removeEventListener=function(b,c,d,e){d&&(a.deactivateGesture(b,c),b.removeEventListener(c,d,e))}}(window.PolymerGestures),function(a){var b=a.dispatcher,c=b.pointermap,d=25,e=[0,1,4,2],f=0,g=/Linux.*Firefox\//i,h=function(){if(g.test(navigator.userAgent))return!1;try{return 1===new MouseEvent("test",{buttons:1}).buttons}catch(a){return!1}}(),i={POINTER_ID:1,POINTER_TYPE:"mouse",events:["mousedown","mousemove","mouseup"],exposes:["down","up","move"],register:function(a){b.listen(a,this.events)},unregister:function(a){a.nodeType!==Node.DOCUMENT_NODE&&b.unlisten(a,this.events)},lastTouches:[],isEventSimulatedFromTouch:function(a){for(var b,c=this.lastTouches,e=a.clientX,f=a.clientY,g=0,h=c.length;h>g&&(b=c[g]);g++){var i=Math.abs(e-b.x),j=Math.abs(f-b.y);if(d>=i&&d>=j)return!0}},prepareEvent:function(a){var c=b.cloneEvent(a);if(c.pointerId=this.POINTER_ID,c.isPrimary=!0,c.pointerType=this.POINTER_TYPE,c._source="mouse",!h){var d=a.type,g=e[a.which]||0;"mousedown"===d?f|=g:"mouseup"===d&&(f&=~g),c.buttons=f}return c},mousedown:function(d){if(!this.isEventSimulatedFromTouch(d)){var e=(c.has(this.POINTER_ID),this.prepareEvent(d));e.target=a.findTarget(d),c.set(this.POINTER_ID,e.target),b.down(e)}},mousemove:function(a){if(!this.isEventSimulatedFromTouch(a)){var d=c.get(this.POINTER_ID);if(d){var e=this.prepareEvent(a);e.target=d,0===(h?e.buttons:e.which)?(h||(f=e.buttons=0),b.cancel(e),this.cleanupMouse(e.buttons)):b.move(e)}}},mouseup:function(d){if(!this.isEventSimulatedFromTouch(d)){var e=this.prepareEvent(d);e.relatedTarget=a.findTarget(d),e.target=c.get(this.POINTER_ID),b.up(e),this.cleanupMouse(e.buttons)}},cleanupMouse:function(a){0===a&&c["delete"](this.POINTER_ID)}};a.mouseEvents=i}(window.PolymerGestures),function(a){var b=a.dispatcher,c=(a.targetFinding.allShadows.bind(a.targetFinding),b.pointermap),d=(Array.prototype.map.call.bind(Array.prototype.map),2500),e=25,f=200,g=20,h=!1,i={IS_IOS:!1,events:["touchstart","touchmove","touchend","touchcancel"],exposes:["down","up","move"],register:function(a,c){(this.IS_IOS?c:!c)&&b.listen(a,this.events)},unregister:function(a){this.IS_IOS||b.unlisten(a,this.events)},scrollTypes:{EMITTER:"none",XSCROLLER:"pan-x",YSCROLLER:"pan-y"},touchActionToScrollType:function(a){var b=a,c=this.scrollTypes;return b===c.EMITTER?"none":b===c.XSCROLLER?"X":b===c.YSCROLLER?"Y":"XY"},POINTER_TYPE:"touch",firstTouch:null,isPrimaryTouch:function(a){return this.firstTouch===a.identifier},setPrimaryTouch:function(a){(0===c.pointers()||1===c.pointers()&&c.has(1))&&(this.firstTouch=a.identifier,this.firstXY={X:a.clientX,Y:a.clientY},this.firstTarget=a.target,this.scrolling=null,this.cancelResetClickCount())},removePrimaryPointer:function(a){a.isPrimary&&(this.firstTouch=null,this.firstXY=null,this.resetClickCount())},clickCount:0,resetId:null,resetClickCount:function(){var a=function(){this.clickCount=0,this.resetId=null}.bind(this);this.resetId=setTimeout(a,f)},cancelResetClickCount:function(){this.resetId&&clearTimeout(this.resetId)},typeToButtons:function(a){var b=0;return("touchstart"===a||"touchmove"===a)&&(b=1),b},findTarget:function(b,d){if("touchstart"===this.currentTouchEvent.type){if(this.isPrimaryTouch(b)){var e={clientX:b.clientX,clientY:b.clientY,path:this.currentTouchEvent.path,target:this.currentTouchEvent.target};return a.findTarget(e)}return a.findTarget(b)}return c.get(d)},touchToPointer:function(a){var c=this.currentTouchEvent,d=b.cloneEvent(a),e=d.pointerId=a.identifier+2;d.target=this.findTarget(a,e),d.bubbles=!0,d.cancelable=!0,d.detail=this.clickCount,d.buttons=this.typeToButtons(c.type),d.width=a.webkitRadiusX||a.radiusX||0,d.height=a.webkitRadiusY||a.radiusY||0,d.pressure=a.webkitForce||a.force||.5,d.isPrimary=this.isPrimaryTouch(a),d.pointerType=this.POINTER_TYPE,d._source="touch";var f=this;return d.preventDefault=function(){f.scrolling=!1,f.firstXY=null,c.preventDefault()},d},processTouches:function(a,b){var d=a.changedTouches;this.currentTouchEvent=a;for(var e,f,g=0;g<d.length;g++)e=d[g],f=this.touchToPointer(e),"touchstart"===a.type&&c.set(f.pointerId,f.target),c.has(f.pointerId)&&b.call(this,f),("touchend"===a.type||a._cancel)&&this.cleanUpPointer(f)},shouldScroll:function(b){if(this.firstXY){var c,d=a.targetFinding.findTouchAction(b),e=this.touchActionToScrollType(d);if("none"===e)c=!1;else if("XY"===e)c=!0;else{var f=b.changedTouches[0],g=e,h="Y"===e?"X":"Y",i=Math.abs(f["client"+g]-this.firstXY[g]),j=Math.abs(f["client"+h]-this.firstXY[h]);c=i>=j}return c}},findTouch:function(a,b){for(var c,d=0,e=a.length;e>d&&(c=a[d]);d++)if(c.identifier===b)return!0},vacuumTouches:function(a){var b=a.touches;if(c.pointers()>=b.length){var d=[];c.forEach(function(a,c){if(1!==c&&!this.findTouch(b,c-2)){var e=a;d.push(e)}},this),d.forEach(function(a){this.cancel(a),c["delete"](a.pointerId)},this)}},touchstart:function(a){this.vacuumTouches(a),this.setPrimaryTouch(a.changedTouches[0]),this.dedupSynthMouse(a),this.scrolling||(this.clickCount++,this.processTouches(a,this.down))},down:function(a){b.down(a)},touchmove:function(a){if(h)a.cancelable&&this.processTouches(a,this.move);else if(this.scrolling){if(this.firstXY){var b=a.changedTouches[0],c=b.clientX-this.firstXY.X,d=b.clientY-this.firstXY.Y,e=Math.sqrt(c*c+d*d);e>=g&&(this.touchcancel(a),this.scrolling=!0,this.firstXY=null)}}else null===this.scrolling&&this.shouldScroll(a)?this.scrolling=!0:(this.scrolling=!1,a.preventDefault(),this.processTouches(a,this.move))},move:function(a){b.move(a)},touchend:function(a){this.dedupSynthMouse(a),this.processTouches(a,this.up)},up:function(c){c.relatedTarget=a.findTarget(c),b.up(c)},cancel:function(a){b.cancel(a)},touchcancel:function(a){a._cancel=!0,this.processTouches(a,this.cancel)},cleanUpPointer:function(a){c["delete"](a.pointerId),this.removePrimaryPointer(a)},dedupSynthMouse:function(b){var c=a.mouseEvents.lastTouches,e=b.changedTouches[0];if(this.isPrimaryTouch(e)){var f={x:e.clientX,y:e.clientY};c.push(f);var g=function(a,b){var c=a.indexOf(b);c>-1&&a.splice(c,1)}.bind(null,c,f);setTimeout(g,d)}}},j=Event.prototype.stopImmediatePropagation||Event.prototype.stopPropagation;document.addEventListener("click",function(b){var c=b.clientX,d=b.clientY,f=function(a){var b=Math.abs(c-a.x),f=Math.abs(d-a.y);return e>=b&&e>=f},g=a.mouseEvents.lastTouches.some(f),h=a.targetFinding.path(b);if(g){for(var k=0;k<h.length;k++)if(h[k]===i.firstTarget)return;b.preventDefault(),j.call(b)}},!0),a.touchEvents=i}(window.PolymerGestures),function(a){var b=a.dispatcher,c=b.pointermap,d=window.MSPointerEvent&&"number"==typeof window.MSPointerEvent.MSPOINTER_TYPE_MOUSE,e={events:["MSPointerDown","MSPointerMove","MSPointerUp","MSPointerCancel"],register:function(a){b.listen(a,this.events)},unregister:function(a){a.nodeType!==Node.DOCUMENT_NODE&&b.unlisten(a,this.events)},POINTER_TYPES:["","unavailable","touch","pen","mouse"],prepareEvent:function(a){var c=a;return c=b.cloneEvent(a),d&&(c.pointerType=this.POINTER_TYPES[a.pointerType]),c._source="ms",c},cleanup:function(a){c["delete"](a)},MSPointerDown:function(d){var e=this.prepareEvent(d);e.target=a.findTarget(d),c.set(d.pointerId,e.target),b.down(e)},MSPointerMove:function(a){var d=c.get(a.pointerId);if(d){var e=this.prepareEvent(a);e.target=d,b.move(e)}},MSPointerUp:function(d){var e=this.prepareEvent(d);e.relatedTarget=a.findTarget(d),e.target=c.get(e.pointerId),b.up(e),this.cleanup(d.pointerId)},MSPointerCancel:function(d){var e=this.prepareEvent(d);e.relatedTarget=a.findTarget(d),e.target=c.get(e.pointerId),b.cancel(e),this.cleanup(d.pointerId)}};a.msEvents=e}(window.PolymerGestures),function(a){var b=a.dispatcher,c=b.pointermap,d={events:["pointerdown","pointermove","pointerup","pointercancel"],prepareEvent:function(a){var c=b.cloneEvent(a);return c._source="pointer",c},register:function(a){b.listen(a,this.events)},unregister:function(a){a.nodeType!==Node.DOCUMENT_NODE&&b.unlisten(a,this.events)},cleanup:function(a){c["delete"](a)},pointerdown:function(d){var e=this.prepareEvent(d);e.target=a.findTarget(d),c.set(e.pointerId,e.target),b.down(e)},pointermove:function(a){var d=c.get(a.pointerId);if(d){var e=this.prepareEvent(a);e.target=d,b.move(e)}},pointerup:function(d){var e=this.prepareEvent(d);e.relatedTarget=a.findTarget(d),e.target=c.get(e.pointerId),b.up(e),this.cleanup(d.pointerId)},pointercancel:function(d){var e=this.prepareEvent(d);e.relatedTarget=a.findTarget(d),e.target=c.get(e.pointerId),b.cancel(e),this.cleanup(d.pointerId)}};a.pointerEvents=d}(window.PolymerGestures),function(a){var b=a.dispatcher,c=window.navigator;window.PointerEvent?b.registerSource("pointer",a.pointerEvents):c.msPointerEnabled?b.registerSource("ms",a.msEvents):(b.registerSource("mouse",a.mouseEvents),void 0!==window.ontouchstart&&b.registerSource("touch",a.touchEvents));var d=navigator.userAgent,e=d.match(/iPad|iPhone|iPod/)&&"ontouchstart"in window;b.IS_IOS=e,a.touchEvents.IS_IOS=e,b.register(document,!0)}(window.PolymerGestures),function(a){var b=a.dispatcher,c=a.eventFactory,d=new a.PointerMap,e={events:["down","move","up"],exposes:["trackstart","track","trackx","tracky","trackend"],defaultActions:{track:"none",trackx:"pan-y",tracky:"pan-x"},WIGGLE_THRESHOLD:4,clampDir:function(a){return a>0?1:-1},calcPositionDelta:function(a,b){var c=0,d=0;return a&&b&&(c=b.pageX-a.pageX,d=b.pageY-a.pageY),{x:c,y:d}},fireTrack:function(a,b,d){var e=d,f=this.calcPositionDelta(e.downEvent,b),g=this.calcPositionDelta(e.lastMoveEvent,b);if(g.x)e.xDirection=this.clampDir(g.x);else if("trackx"===a)return;if(g.y)e.yDirection=this.clampDir(g.y);else if("tracky"===a)return;var h={bubbles:!0,cancelable:!0,trackInfo:e.trackInfo,relatedTarget:b.relatedTarget,pointerType:b.pointerType,pointerId:b.pointerId,_source:"track"};"tracky"!==a&&(h.x=b.x,h.dx=f.x,h.ddx=g.x,h.clientX=b.clientX,h.pageX=b.pageX,h.screenX=b.screenX,h.xDirection=e.xDirection),"trackx"!==a&&(h.dy=f.y,h.ddy=g.y,h.y=b.y,h.clientY=b.clientY,h.pageY=b.pageY,h.screenY=b.screenY,h.yDirection=e.yDirection);var i=c.makeGestureEvent(a,h);e.downTarget.dispatchEvent(i)},down:function(a){if(a.isPrimary&&("mouse"===a.pointerType?1===a.buttons:!0)){var b={downEvent:a,downTarget:a.target,trackInfo:{},lastMoveEvent:null,xDirection:0,yDirection:0,tracking:!1};d.set(a.pointerId,b)}},move:function(a){var b=d.get(a.pointerId);if(b){if(!b.tracking){var c=this.calcPositionDelta(b.downEvent,a),e=c.x*c.x+c.y*c.y;e>this.WIGGLE_THRESHOLD&&(b.tracking=!0,b.lastMoveEvent=b.downEvent,this.fireTrack("trackstart",a,b))}b.tracking&&(this.fireTrack("track",a,b),this.fireTrack("trackx",a,b),this.fireTrack("tracky",a,b)),b.lastMoveEvent=a}},up:function(a){var b=d.get(a.pointerId);b&&(b.tracking&&this.fireTrack("trackend",a,b),d["delete"](a.pointerId))}};b.registerGesture("track",e)}(window.PolymerGestures),function(a){var b=a.dispatcher,c=a.eventFactory,d={HOLD_DELAY:200,WIGGLE_THRESHOLD:16,events:["down","move","up"],exposes:["hold","holdpulse","release"],heldPointer:null,holdJob:null,pulse:function(){var a=Date.now()-this.heldPointer.timeStamp,b=this.held?"holdpulse":"hold";this.fireHold(b,a),this.held=!0},cancel:function(){clearInterval(this.holdJob),this.held&&this.fireHold("release"),this.held=!1,this.heldPointer=null,this.target=null,this.holdJob=null},down:function(a){a.isPrimary&&!this.heldPointer&&(this.heldPointer=a,this.target=a.target,this.holdJob=setInterval(this.pulse.bind(this),this.HOLD_DELAY))},up:function(a){this.heldPointer&&this.heldPointer.pointerId===a.pointerId&&this.cancel()},move:function(a){if(this.heldPointer&&this.heldPointer.pointerId===a.pointerId){var b=a.clientX-this.heldPointer.clientX,c=a.clientY-this.heldPointer.clientY;b*b+c*c>this.WIGGLE_THRESHOLD&&this.cancel()}},fireHold:function(a,b){var d={bubbles:!0,cancelable:!0,pointerType:this.heldPointer.pointerType,pointerId:this.heldPointer.pointerId,x:this.heldPointer.clientX,y:this.heldPointer.clientY,_source:"hold"};b&&(d.holdTime=b);var e=c.makeGestureEvent(a,d);this.target.dispatchEvent(e)}};b.registerGesture("hold",d)}(window.PolymerGestures),function(a){var b=a.dispatcher,c=a.eventFactory,d=new a.PointerMap,e={events:["down","up"],exposes:["tap"],down:function(a){a.isPrimary&&!a.tapPrevented&&d.set(a.pointerId,{target:a.target,buttons:a.buttons,x:a.clientX,y:a.clientY})},shouldTap:function(a,b){var c=!0;return"mouse"===a.pointerType&&(c=1^a.buttons&&1&b.buttons),c&&!a.tapPrevented},up:function(b){var e=d.get(b.pointerId);if(e&&this.shouldTap(b,e)){var f=a.targetFinding.LCA(e.target,b.relatedTarget);if(f){var g=c.makeGestureEvent("tap",{bubbles:!0,cancelable:!0,x:b.clientX,y:b.clientY,detail:b.detail,pointerType:b.pointerType,pointerId:b.pointerId,altKey:b.altKey,ctrlKey:b.ctrlKey,metaKey:b.metaKey,shiftKey:b.shiftKey,_source:"tap"});f.dispatchEvent(g)}}d["delete"](b.pointerId)}};c.preventTap=function(a){return function(){a.tapPrevented=!0,d["delete"](a.pointerId)}},b.registerGesture("tap",e)}(window.PolymerGestures),function(a){var b=a.dispatcher,c=a.eventFactory,d=new a.PointerMap,e=180/Math.PI,f={events:["down","up","move","cancel"],exposes:["pinchstart","pinch","pinchend","rotate"],defaultActions:{pinch:"none",rotate:"none"},reference:{},down:function(b){if(d.set(b.pointerId,b),2==d.pointers()){var c=this.calcChord(),e=this.calcAngle(c);this.reference={angle:e,diameter:c.diameter,target:a.targetFinding.LCA(c.a.target,c.b.target)},this.firePinch("pinchstart",c.diameter,c)}},up:function(a){var b=d.get(a.pointerId),c=d.pointers();if(b){if(2===c){var e=this.calcChord();this.firePinch("pinchend",e.diameter,e)}d["delete"](a.pointerId)}},move:function(a){d.has(a.pointerId)&&(d.set(a.pointerId,a),d.pointers()>1&&this.calcPinchRotate())},cancel:function(a){this.up(a)},firePinch:function(a,b,d){var e=b/this.reference.diameter,f=c.makeGestureEvent(a,{bubbles:!0,cancelable:!0,scale:e,centerX:d.center.x,centerY:d.center.y,_source:"pinch"});this.reference.target.dispatchEvent(f)},fireRotate:function(a,b){var d=Math.round((a-this.reference.angle)%360),e=c.makeGestureEvent("rotate",{bubbles:!0,cancelable:!0,angle:d,centerX:b.center.x,centerY:b.center.y,_source:"pinch"});this.reference.target.dispatchEvent(e)},calcPinchRotate:function(){var a=this.calcChord(),b=a.diameter,c=this.calcAngle(a);b!=this.reference.diameter&&this.firePinch("pinch",b,a),c!=this.reference.angle&&this.fireRotate(c,a)},calcChord:function(){var a=[];d.forEach(function(b){a.push(b)});for(var b,c,e,f=0,g={a:a[0],b:a[1]},h=0;h<a.length;h++)for(var i=a[h],j=h+1;j<a.length;j++){var k=a[j];b=Math.abs(i.clientX-k.clientX),c=Math.abs(i.clientY-k.clientY),e=b+c,e>f&&(f=e,g={a:i,b:k})}return b=Math.abs(g.a.clientX+g.b.clientX)/2,c=Math.abs(g.a.clientY+g.b.clientY)/2,g.center={x:b,y:c},g.diameter=f,g},calcAngle:function(a){var b=a.a.clientX-a.b.clientX,c=a.a.clientY-a.b.clientY;return(360+Math.atan2(c,b)*e)%360}};b.registerGesture("pinch",f)}(window.PolymerGestures),function(a){"use strict";function b(a,b){if(!a)throw new Error("ASSERT: "+b)}function c(a){return a>=48&&57>=a}function d(a){return 32===a||9===a||11===a||12===a||160===a||a>=5760&&" ᠎              ".indexOf(String.fromCharCode(a))>0}function e(a){return 10===a||13===a||8232===a||8233===a}function f(a){return 36===a||95===a||a>=65&&90>=a||a>=97&&122>=a}function g(a){return 36===a||95===a||a>=65&&90>=a||a>=97&&122>=a||a>=48&&57>=a}function h(a){return"this"===a}function i(){for(;Y>X&&d(W.charCodeAt(X));)++X}function j(){var a,b;for(a=X++;Y>X&&(b=W.charCodeAt(X),g(b));)++X;return W.slice(a,X)}function k(){var a,b,c;return a=X,b=j(),c=1===b.length?S.Identifier:h(b)?S.Keyword:"null"===b?S.NullLiteral:"true"===b||"false"===b?S.BooleanLiteral:S.Identifier,{type:c,value:b,range:[a,X]}}function l(){var a,b,c=X,d=W.charCodeAt(X),e=W[X];switch(d){case 46:case 40:case 41:case 59:case 44:case 123:case 125:case 91:case 93:case 58:case 63:return++X,{type:S.Punctuator,value:String.fromCharCode(d),range:[c,X]};default:if(a=W.charCodeAt(X+1),61===a)switch(d){case 37:case 38:case 42:case 43:case 45:case 47:case 60:case 62:case 124:return X+=2,{type:S.Punctuator,value:String.fromCharCode(d)+String.fromCharCode(a),range:[c,X]};case 33:case 61:return X+=2,61===W.charCodeAt(X)&&++X,{type:S.Punctuator,value:W.slice(c,X),range:[c,X]}}}return b=W[X+1],e===b&&"&|".indexOf(e)>=0?(X+=2,{type:S.Punctuator,value:e+b,range:[c,X]}):"<>=!+-*%&|^/".indexOf(e)>=0?(++X,{type:S.Punctuator,value:e,range:[c,X]}):void s({},V.UnexpectedToken,"ILLEGAL")}function m(){var a,d,e;if(e=W[X],b(c(e.charCodeAt(0))||"."===e,"Numeric literal must start with a decimal digit or a decimal point"),d=X,a="","."!==e){for(a=W[X++],e=W[X],"0"===a&&e&&c(e.charCodeAt(0))&&s({},V.UnexpectedToken,"ILLEGAL");c(W.charCodeAt(X));)a+=W[X++];e=W[X]}if("."===e){for(a+=W[X++];c(W.charCodeAt(X));)a+=W[X++];e=W[X]}if("e"===e||"E"===e)if(a+=W[X++],e=W[X],("+"===e||"-"===e)&&(a+=W[X++]),c(W.charCodeAt(X)))for(;c(W.charCodeAt(X));)a+=W[X++];else s({},V.UnexpectedToken,"ILLEGAL");return f(W.charCodeAt(X))&&s({},V.UnexpectedToken,"ILLEGAL"),{type:S.NumericLiteral,value:parseFloat(a),range:[d,X]}}function n(){var a,c,d,f="",g=!1;for(a=W[X],b("'"===a||'"'===a,"String literal must starts with a quote"),c=X,++X;Y>X;){if(d=W[X++],d===a){a="";break}if("\\"===d)if(d=W[X++],d&&e(d.charCodeAt(0)))"\r"===d&&"\n"===W[X]&&++X;else switch(d){case"n":f+="\n";break;case"r":f+="\r";break;case"t":f+="	";break;case"b":f+="\b";break;case"f":f+="\f";break;case"v":f+="";break;default:f+=d}else{if(e(d.charCodeAt(0)))break;f+=d}}return""!==a&&s({},V.UnexpectedToken,"ILLEGAL"),{type:S.StringLiteral,value:f,octal:g,range:[c,X]}}function o(a){return a.type===S.Identifier||a.type===S.Keyword||a.type===S.BooleanLiteral||a.type===S.NullLiteral}function p(){var a;return i(),X>=Y?{type:S.EOF,range:[X,X]}:(a=W.charCodeAt(X),40===a||41===a||58===a?l():39===a||34===a?n():f(a)?k():46===a?c(W.charCodeAt(X+1))?m():l():c(a)?m():l())}function q(){var a;return a=$,X=a.range[1],$=p(),X=a.range[1],a}function r(){var a;a=X,$=p(),X=a}function s(a,c){var d,e=Array.prototype.slice.call(arguments,2),f=c.replace(/%(\d)/g,function(a,c){return b(c<e.length,"Message reference must be in range"),e[c]});throw d=new Error(f),d.index=X,d.description=f,d}function t(a){s(a,V.UnexpectedToken,a.value)}function u(a){var b=q();(b.type!==S.Punctuator||b.value!==a)&&t(b)}function v(a){return $.type===S.Punctuator&&$.value===a}function w(a){return $.type===S.Keyword&&$.value===a}function x(){var a=[];for(u("[");!v("]");)v(",")?(q(),a.push(null)):(a.push(bb()),v("]")||u(","));return u("]"),Z.createArrayExpression(a)}function y(){var a;return i(),a=q(),a.type===S.StringLiteral||a.type===S.NumericLiteral?Z.createLiteral(a):Z.createIdentifier(a.value)}function z(){var a,b;return a=$,i(),(a.type===S.EOF||a.type===S.Punctuator)&&t(a),b=y(),u(":"),Z.createProperty("init",b,bb())}function A(){var a=[];for(u("{");!v("}");)a.push(z()),v("}")||u(",");return u("}"),Z.createObjectExpression(a)}function B(){var a;return u("("),a=bb(),u(")"),a}function C(){var a,b,c;return v("(")?B():(a=$.type,a===S.Identifier?c=Z.createIdentifier(q().value):a===S.StringLiteral||a===S.NumericLiteral?c=Z.createLiteral(q()):a===S.Keyword?w("this")&&(q(),c=Z.createThisExpression()):a===S.BooleanLiteral?(b=q(),b.value="true"===b.value,c=Z.createLiteral(b)):a===S.NullLiteral?(b=q(),b.value=null,c=Z.createLiteral(b)):v("[")?c=x():v("{")&&(c=A()),c?c:void t(q()))}function D(){var a=[];if(u("("),!v(")"))for(;Y>X&&(a.push(bb()),!v(")"));)u(",");return u(")"),a}function E(){var a;return a=q(),o(a)||t(a),Z.createIdentifier(a.value)}function F(){return u("."),E()}function G(){var a;return u("["),a=bb(),u("]"),a}function H(){var a,b,c;for(a=C();;)if(v("["))c=G(),a=Z.createMemberExpression("[",a,c);else if(v("."))c=F(),a=Z.createMemberExpression(".",a,c);else{if(!v("("))break;b=D(),a=Z.createCallExpression(a,b)}return a}function I(){var a,b;return $.type!==S.Punctuator&&$.type!==S.Keyword?b=ab():v("+")||v("-")||v("!")?(a=q(),b=I(),b=Z.createUnaryExpression(a.value,b)):w("delete")||w("void")||w("typeof")?s({},V.UnexpectedToken):b=ab(),b}function J(a){var b=0;if(a.type!==S.Punctuator&&a.type!==S.Keyword)return 0;switch(a.value){case"||":b=1;break;case"&&":b=2;break;case"==":case"!=":case"===":case"!==":b=6;break;case"<":case">":case"<=":case">=":case"instanceof":b=7;break;case"in":b=7;break;case"+":case"-":b=9;break;case"*":case"/":case"%":b=11}return b}function K(){var a,b,c,d,e,f,g,h;if(g=I(),b=$,c=J(b),0===c)return g;for(b.prec=c,q(),e=I(),d=[g,b,e];(c=J($))>0;){for(;d.length>2&&c<=d[d.length-2].prec;)e=d.pop(),f=d.pop().value,g=d.pop(),a=Z.createBinaryExpression(f,g,e),d.push(a);b=q(),b.prec=c,d.push(b),a=I(),d.push(a)}for(h=d.length-1,a=d[h];h>1;)a=Z.createBinaryExpression(d[h-1].value,d[h-2],a),h-=2;return a}function L(){var a,b,c;return a=K(),v("?")&&(q(),b=L(),u(":"),c=L(),a=Z.createConditionalExpression(a,b,c)),a}function M(){var a,b;return a=q(),a.type!==S.Identifier&&t(a),b=v("(")?D():[],Z.createFilter(a.value,b)}function N(){for(;v("|");)q(),M()}function O(){i(),r();var a=bb();a&&(","===$.value||"in"==$.value&&a.type===U.Identifier?Q(a):(N(),"as"===$.value?P(a):Z.createTopLevel(a))),$.type!==S.EOF&&t($)}function P(a){q();var b=q().value;Z.createAsExpression(a,b)}function Q(a){var b;","===$.value&&(q(),$.type!==S.Identifier&&t($),b=q().value),q();var c=bb();N(),Z.createInExpression(a.name,b,c)}function R(a,b){return Z=b,W=a,X=0,Y=W.length,$=null,_={labelSet:{}},O()}var S,T,U,V,W,X,Y,Z,$,_;S={BooleanLiteral:1,EOF:2,Identifier:3,Keyword:4,NullLiteral:5,NumericLiteral:6,Punctuator:7,StringLiteral:8},T={},T[S.BooleanLiteral]="Boolean",T[S.EOF]="<end>",T[S.Identifier]="Identifier",T[S.Keyword]="Keyword",T[S.NullLiteral]="Null",T[S.NumericLiteral]="Numeric",T[S.Punctuator]="Punctuator",T[S.StringLiteral]="String",U={ArrayExpression:"ArrayExpression",BinaryExpression:"BinaryExpression",CallExpression:"CallExpression",ConditionalExpression:"ConditionalExpression",EmptyStatement:"EmptyStatement",ExpressionStatement:"ExpressionStatement",Identifier:"Identifier",Literal:"Literal",LabeledStatement:"LabeledStatement",LogicalExpression:"LogicalExpression",MemberExpression:"MemberExpression",ObjectExpression:"ObjectExpression",Program:"Program",Property:"Property",ThisExpression:"ThisExpression",UnaryExpression:"UnaryExpression"},V={UnexpectedToken:"Unexpected token %0",UnknownLabel:"Undefined label '%0'",Redeclaration:"%0 '%1' has already been declared"};
+var ab=H,bb=L;a.esprima={parse:R}}(this),function(a){"use strict";function b(a,b,d,e){var f;try{if(f=c(a),f.scopeIdent&&(d.nodeType!==Node.ELEMENT_NODE||"TEMPLATE"!==d.tagName||"bind"!==b&&"repeat"!==b))throw Error("as and in can only be used within <template bind/repeat>")}catch(g){return void console.error("Invalid expression syntax: "+a,g)}return function(a,b,c){var d=f.getBinding(a,e,c);return f.scopeIdent&&d&&(b.polymerExpressionScopeIdent_=f.scopeIdent,f.indexIdent&&(b.polymerExpressionIndexIdent_=f.indexIdent)),d}}function c(a){var b=q[a];if(!b){var c=new j;esprima.parse(a,c),b=new l(c),q[a]=b}return b}function d(a){this.value=a,this.valueFn_=void 0}function e(a){this.name=a,this.path=Path.get(a)}function f(a,b,c){this.computed="["==c,this.dynamicDeps="function"==typeof a||a.dynamicDeps||this.computed&&!(b instanceof d),this.simplePath=!this.dynamicDeps&&(b instanceof e||b instanceof d)&&(a instanceof f||a instanceof e),this.object=this.simplePath?a:i(a),this.property=!this.computed||this.simplePath?b:i(b)}function g(a,b){this.name=a,this.args=[];for(var c=0;c<b.length;c++)this.args[c]=i(b[c])}function h(){throw Error("Not Implemented")}function i(a){return"function"==typeof a?a:a.valueFn()}function j(){this.expression=null,this.filters=[],this.deps={},this.currentPath=void 0,this.scopeIdent=void 0,this.indexIdent=void 0,this.dynamicDeps=!1}function k(a){this.value_=a}function l(a){if(this.scopeIdent=a.scopeIdent,this.indexIdent=a.indexIdent,!a.expression)throw Error("No expression found.");this.expression=a.expression,i(this.expression),this.filters=a.filters,this.dynamicDeps=a.dynamicDeps}function m(a){return String(a).replace(/[A-Z]/g,function(a){return"-"+a.toLowerCase()})}function n(a,b){for(;a[t]&&!Object.prototype.hasOwnProperty.call(a,b);)a=a[t];return a}function o(a){switch(a){case"":return!1;case"false":case"null":case"true":return!0}return isNaN(Number(a))?!1:!0}function p(){}var q=Object.create(null);d.prototype={valueFn:function(){if(!this.valueFn_){var a=this.value;this.valueFn_=function(){return a}}return this.valueFn_}},e.prototype={valueFn:function(){if(!this.valueFn_){var a=(this.name,this.path);this.valueFn_=function(b,c){return c&&c.addPath(b,a),a.getValueFrom(b)}}return this.valueFn_},setValue:function(a,b){return 1==this.path.length&&(a=n(a,this.path[0])),this.path.setValueFrom(a,b)}},f.prototype={get fullPath(){if(!this.fullPath_){var a=this.object instanceof f?this.object.fullPath.slice():[this.object.name];a.push(this.property instanceof e?this.property.name:this.property.value),this.fullPath_=Path.get(a)}return this.fullPath_},valueFn:function(){if(!this.valueFn_){var a=this.object;if(this.simplePath){var b=this.fullPath;this.valueFn_=function(a,c){return c&&c.addPath(a,b),b.getValueFrom(a)}}else if(this.computed){var c=this.property;this.valueFn_=function(b,d,e){var f=a(b,d,e),g=c(b,d,e);return d&&d.addPath(f,[g]),f?f[g]:void 0}}else{var b=Path.get(this.property.name);this.valueFn_=function(c,d,e){var f=a(c,d,e);return d&&d.addPath(f,b),b.getValueFrom(f)}}}return this.valueFn_},setValue:function(a,b){if(this.simplePath)return this.fullPath.setValueFrom(a,b),b;var c=this.object(a),d=this.property instanceof e?this.property.name:this.property(a);return c[d]=b}},g.prototype={transform:function(a,b,c,d,e){var f=a,g=f[this.name];if(!g&&(g=c[this.name],!g))return void console.error("Cannot find function or filter: "+this.name);if(d?g=g.toModel:"function"==typeof g.toDOM&&(g=g.toDOM),"function"!=typeof g)return void console.error("Cannot find function or filter: "+this.name);for(var h=e||[],j=0;j<this.args.length;j++)h.push(i(this.args[j])(a,b,c));return g.apply(f,h)}};var r={"+":function(a){return+a},"-":function(a){return-a},"!":function(a){return!a}},s={"+":function(a,b){return a+b},"-":function(a,b){return a-b},"*":function(a,b){return a*b},"/":function(a,b){return a/b},"%":function(a,b){return a%b},"<":function(a,b){return b>a},">":function(a,b){return a>b},"<=":function(a,b){return b>=a},">=":function(a,b){return a>=b},"==":function(a,b){return a==b},"!=":function(a,b){return a!=b},"===":function(a,b){return a===b},"!==":function(a,b){return a!==b},"&&":function(a,b){return a&&b},"||":function(a,b){return a||b}};j.prototype={createUnaryExpression:function(a,b){if(!r[a])throw Error("Disallowed operator: "+a);return b=i(b),function(c,d,e){return r[a](b(c,d,e))}},createBinaryExpression:function(a,b,c){if(!s[a])throw Error("Disallowed operator: "+a);switch(b=i(b),c=i(c),a){case"||":return this.dynamicDeps=!0,function(a,d,e){return b(a,d,e)||c(a,d,e)};case"&&":return this.dynamicDeps=!0,function(a,d,e){return b(a,d,e)&&c(a,d,e)}}return function(d,e,f){return s[a](b(d,e,f),c(d,e,f))}},createConditionalExpression:function(a,b,c){return a=i(a),b=i(b),c=i(c),this.dynamicDeps=!0,function(d,e,f){return a(d,e,f)?b(d,e,f):c(d,e,f)}},createIdentifier:function(a){var b=new e(a);return b.type="Identifier",b},createMemberExpression:function(a,b,c){var d=new f(b,c,a);return d.dynamicDeps&&(this.dynamicDeps=!0),d},createCallExpression:function(a,b){if(!(a instanceof e))throw Error("Only identifier function invocations are allowed");var c=new g(a.name,b);return function(a,b,d){return c.transform(a,b,d,!1)}},createLiteral:function(a){return new d(a.value)},createArrayExpression:function(a){for(var b=0;b<a.length;b++)a[b]=i(a[b]);return function(b,c,d){for(var e=[],f=0;f<a.length;f++)e.push(a[f](b,c,d));return e}},createProperty:function(a,b,c){return{key:b instanceof e?b.name:b.value,value:c}},createObjectExpression:function(a){for(var b=0;b<a.length;b++)a[b].value=i(a[b].value);return function(b,c,d){for(var e={},f=0;f<a.length;f++)e[a[f].key]=a[f].value(b,c,d);return e}},createFilter:function(a,b){this.filters.push(new g(a,b))},createAsExpression:function(a,b){this.expression=a,this.scopeIdent=b},createInExpression:function(a,b,c){this.expression=c,this.scopeIdent=a,this.indexIdent=b},createTopLevel:function(a){this.expression=a},createThisExpression:h},k.prototype={open:function(){return this.value_},discardChanges:function(){return this.value_},deliver:function(){},close:function(){}},l.prototype={getBinding:function(a,b,c){function d(){if(h)return h=!1,g;i.dynamicDeps&&f.startReset();var c=i.getValue(a,i.dynamicDeps?f:void 0,b);return i.dynamicDeps&&f.finishReset(),c}function e(c){return i.setValue(a,c,b),c}if(c)return this.getValue(a,void 0,b);var f=new CompoundObserver,g=this.getValue(a,f,b),h=!0,i=this;return new ObserverTransform(f,d,e,!0)},getValue:function(a,b,c){for(var d=i(this.expression)(a,b,c),e=0;e<this.filters.length;e++)d=this.filters[e].transform(a,b,c,!1,[d]);return d},setValue:function(a,b,c){for(var d=this.filters?this.filters.length:0;d-->0;)b=this.filters[d].transform(a,void 0,c,!0,[b]);return this.expression.setValue?this.expression.setValue(a,b):void 0}};var t="@"+Math.random().toString(36).slice(2);p.prototype={styleObject:function(a){var b=[];for(var c in a)b.push(m(c)+": "+a[c]);return b.join("; ")},tokenList:function(a){var b=[];for(var c in a)a[c]&&b.push(c);return b.join(" ")},prepareInstancePositionChanged:function(a){var b=a.polymerExpressionIndexIdent_;if(b)return function(a,c){a.model[b]=c}},prepareBinding:function(a,c,d){var e=Path.get(a);{if(o(a)||!e.valid)return b(a,c,d,this);if(1==e.length)return function(a,b,c){if(c)return e.getValueFrom(a);var d=n(a,e[0]);return new PathObserver(d,e)}}},prepareInstanceModel:function(a){var b=a.polymerExpressionScopeIdent_;if(b){var c=a.templateInstance?a.templateInstance.model:a.model,d=a.polymerExpressionIndexIdent_;return function(a){return u(c,a,b,d)}}}};var u="__proto__"in{}?function(a,b,c,d){var e={};return e[c]=b,e[d]=void 0,e[t]=a,e.__proto__=a,e}:function(a,b,c,d){var e=Object.create(a);return Object.defineProperty(e,c,{value:b,configurable:!0,writable:!0}),Object.defineProperty(e,d,{value:void 0,configurable:!0,writable:!0}),Object.defineProperty(e,t,{value:a,configurable:!0,writable:!0}),e};a.PolymerExpressions=p,p.getExpression=c}(this),Polymer={version:"0.5.5"},"function"==typeof window.Polymer&&(Polymer={}),function(a){function b(a,b){return b=b||[],b.map||(b=[b]),a.apply(this,b.map(d))}function c(a,c,d){var e;switch(arguments.length){case 0:return;case 1:e=null;break;case 2:e=c.apply(this);break;default:e=b(d,c)}f[a]=e}function d(a){return f[a]}function e(a,c){HTMLImports.whenImportsReady(function(){b(c,a)})}var f={};a.marshal=d,a.modularize=c,a.using=e}(window),window.WebComponents||(window.WebComponents||(WebComponents={flush:function(){},flags:{log:{}}},Platform=WebComponents,CustomElements={useNative:!0,ready:!0,takeRecords:function(){},"instanceof":function(a,b){return a instanceof b}},HTMLImports={useNative:!0},addEventListener("HTMLImportsLoaded",function(){document.dispatchEvent(new CustomEvent("WebComponentsReady",{bubbles:!0}))}),ShadowDOMPolyfill=null,wrap=unwrap=function(a){return a}),window.HTMLImports=window.HTMLImports||{flags:{}},function(a){function b(a,b){b=b||o,d(function(){f(a,b)},b)}function c(a){return"complete"===a.readyState||a.readyState===r}function d(a,b){if(c(b))a&&a();else{var e=function(){("complete"===b.readyState||b.readyState===r)&&(b.removeEventListener(s,e),d(a,b))};b.addEventListener(s,e)}}function e(a){a.target.__loaded=!0}function f(a,b){function c(){h==i&&a&&a()}function d(a){e(a),h++,c()}var f=b.querySelectorAll("link[rel=import]"),h=0,i=f.length;if(i)for(var j,k=0;i>k&&(j=f[k]);k++)g(j)?d.call(j,{target:j}):(j.addEventListener("load",d),j.addEventListener("error",d));else c()}function g(a){return l?a.__loaded||a["import"]&&"loading"!==a["import"].readyState:a.__importParsed}function h(a){for(var b,c=0,d=a.length;d>c&&(b=a[c]);c++)i(b)&&j(b)}function i(a){return"link"===a.localName&&"import"===a.rel}function j(a){var b=a["import"];b?e({target:a}):(a.addEventListener("load",e),a.addEventListener("error",e))}var k="import",l=Boolean(k in document.createElement("link")),m=Boolean(window.ShadowDOMPolyfill),n=function(a){return m?ShadowDOMPolyfill.wrapIfNeeded(a):a},o=n(document),p={get:function(){var a=HTMLImports.currentScript||document.currentScript||("complete"!==document.readyState?document.scripts[document.scripts.length-1]:null);return n(a)},configurable:!0};Object.defineProperty(document,"_currentScript",p),Object.defineProperty(o,"_currentScript",p);var q=/Trident/.test(navigator.userAgent),r=q?"complete":"interactive",s="readystatechange";l&&(new MutationObserver(function(a){for(var b,c=0,d=a.length;d>c&&(b=a[c]);c++)b.addedNodes&&h(b.addedNodes)}).observe(document.head,{childList:!0}),function(){if("loading"===document.readyState)for(var a,b=document.querySelectorAll("link[rel=import]"),c=0,d=b.length;d>c&&(a=b[c]);c++)j(a)}()),b(function(){HTMLImports.ready=!0,HTMLImports.readyTime=(new Date).getTime(),o.dispatchEvent(new CustomEvent("HTMLImportsLoaded",{bubbles:!0}))}),a.IMPORT_LINK_TYPE=k,a.useNative=l,a.rootDocument=o,a.whenReady=b,a.isIE=q}(HTMLImports),function(){var a=document.createElement("style");a.textContent="body {transition: opacity ease-in 0.2s; } \nbody[unresolved] {opacity: 0; display: block; overflow: hidden; } \n";var b=document.querySelector("head");b.insertBefore(a,b.firstChild)}(Platform)),function(a){"use strict";function b(){function a(a){b=a}if("function"!=typeof Object.observe||"function"!=typeof Array.observe)return!1;var b=[],c={},d=[];return Object.observe(c,a),Array.observe(d,a),c.id=1,c.id=2,delete c.id,d.push(1,2),d.length=0,Object.deliverChangeRecords(a),5!==b.length?!1:"add"!=b[0].type||"update"!=b[1].type||"delete"!=b[2].type||"splice"!=b[3].type||"splice"!=b[4].type?!1:(Object.unobserve(c,a),Array.unobserve(d,a),!0)}function c(){if("undefined"!=typeof chrome&&chrome.app&&chrome.app.runtime)return!1;if("undefined"!=typeof navigator&&navigator.getDeviceStorage)return!1;try{var a=new Function("","return true;");return a()}catch(b){return!1}}function d(a){return+a===a>>>0&&""!==a}function e(a){return+a}function f(a){return a===Object(a)}function g(a,b){return a===b?0!==a||1/a===1/b:R(a)&&R(b)?!0:a!==a&&b!==b}function h(a){if(void 0===a)return"eof";var b=a.charCodeAt(0);switch(b){case 91:case 93:case 46:case 34:case 39:case 48:return a;case 95:case 36:return"ident";case 32:case 9:case 10:case 13:case 160:case 65279:case 8232:case 8233:return"ws"}return b>=97&&122>=b||b>=65&&90>=b?"ident":b>=49&&57>=b?"number":"else"}function i(){}function j(a){function b(){if(!(m>=a.length)){var b=a[m+1];return"inSingleQuote"==n&&"'"==b||"inDoubleQuote"==n&&'"'==b?(m++,d=b,o.append(),!0):void 0}}for(var c,d,e,f,g,j,k,l=[],m=-1,n="beforePath",o={push:function(){void 0!==e&&(l.push(e),e=void 0)},append:function(){void 0===e?e=d:e+=d}};n;)if(m++,c=a[m],"\\"!=c||!b(n)){if(f=h(c),k=W[n],g=k[f]||k["else"]||"error","error"==g)return;if(n=g[0],j=o[g[1]]||i,d=void 0===g[2]?c:g[2],j(),"afterPath"===n)return l}}function k(a){return V.test(a)}function l(a,b){if(b!==X)throw Error("Use Path.get to retrieve path objects");for(var c=0;c<a.length;c++)this.push(String(a[c]));Q&&this.length&&(this.getValueFrom=this.compiledGetValueFromFn())}function m(a){if(a instanceof l)return a;if((null==a||0==a.length)&&(a=""),"string"!=typeof a){if(d(a.length))return new l(a,X);a=String(a)}var b=Y[a];if(b)return b;var c=j(a);if(!c)return Z;var b=new l(c,X);return Y[a]=b,b}function n(a){return d(a)?"["+a+"]":'["'+a.replace(/"/g,'\\"')+'"]'}function o(b){for(var c=0;_>c&&b.check_();)c++;return O&&(a.dirtyCheckCycleCount=c),c>0}function p(a){for(var b in a)return!1;return!0}function q(a){return p(a.added)&&p(a.removed)&&p(a.changed)}function r(a,b){var c={},d={},e={};for(var f in b){var g=a[f];(void 0===g||g!==b[f])&&(f in a?g!==b[f]&&(e[f]=g):d[f]=void 0)}for(var f in a)f in b||(c[f]=a[f]);return Array.isArray(a)&&a.length!==b.length&&(e.length=a.length),{added:c,removed:d,changed:e}}function s(){if(!ab.length)return!1;for(var a=0;a<ab.length;a++)ab[a]();return ab.length=0,!0}function t(){function a(a){b&&b.state_===fb&&!d&&b.check_(a)}var b,c,d=!1,e=!0;return{open:function(c){if(b)throw Error("ObservedObject in use");e||Object.deliverChangeRecords(a),b=c,e=!1},observe:function(b,d){c=b,d?Array.observe(c,a):Object.observe(c,a)},deliver:function(b){d=b,Object.deliverChangeRecords(a),d=!1},close:function(){b=void 0,Object.unobserve(c,a),cb.push(this)}}}function u(a,b,c){var d=cb.pop()||t();return d.open(a),d.observe(b,c),d}function v(){function a(b,f){b&&(b===d&&(e[f]=!0),h.indexOf(b)<0&&(h.push(b),Object.observe(b,c)),a(Object.getPrototypeOf(b),f))}function b(a){for(var b=0;b<a.length;b++){var c=a[b];if(c.object!==d||e[c.name]||"setPrototype"===c.type)return!1}return!0}function c(c){if(!b(c)){for(var d,e=0;e<g.length;e++)d=g[e],d.state_==fb&&d.iterateObjects_(a);for(var e=0;e<g.length;e++)d=g[e],d.state_==fb&&d.check_()}}var d,e,f=0,g=[],h=[],i={objects:h,get rootObject(){return d},set rootObject(a){d=a,e={}},open:function(b){g.push(b),f++,b.iterateObjects_(a)},close:function(){if(f--,!(f>0)){for(var a=0;a<h.length;a++)Object.unobserve(h[a],c),x.unobservedCount++;g.length=0,h.length=0,d=void 0,e=void 0,db.push(this),$===this&&($=null)}}};return i}function w(a,b){return $&&$.rootObject===b||($=db.pop()||v(),$.rootObject=b),$.open(a,b),$}function x(){this.state_=eb,this.callback_=void 0,this.target_=void 0,this.directObserver_=void 0,this.value_=void 0,this.id_=ib++}function y(a){x._allObserversCount++,kb&&jb.push(a)}function z(){x._allObserversCount--}function A(a){x.call(this),this.value_=a,this.oldObject_=void 0}function B(a){if(!Array.isArray(a))throw Error("Provided object is not an Array");A.call(this,a)}function C(a,b){x.call(this),this.object_=a,this.path_=m(b),this.directObserver_=void 0}function D(a){x.call(this),this.reportChangesOnOpen_=a,this.value_=[],this.directObserver_=void 0,this.observed_=[]}function E(a){return a}function F(a,b,c,d){this.callback_=void 0,this.target_=void 0,this.value_=void 0,this.observable_=a,this.getValueFn_=b||E,this.setValueFn_=c||E,this.dontPassThroughSet_=d}function G(a,b,c){for(var d={},e={},f=0;f<b.length;f++){var g=b[f];nb[g.type]?(g.name in c||(c[g.name]=g.oldValue),"update"!=g.type&&("add"!=g.type?g.name in d?(delete d[g.name],delete c[g.name]):e[g.name]=!0:g.name in e?delete e[g.name]:d[g.name]=!0)):(console.error("Unknown changeRecord type: "+g.type),console.error(g))}for(var h in d)d[h]=a[h];for(var h in e)e[h]=void 0;var i={};for(var h in c)if(!(h in d||h in e)){var j=a[h];c[h]!==j&&(i[h]=j)}return{added:d,removed:e,changed:i}}function H(a,b,c){return{index:a,removed:b,addedCount:c}}function I(){}function J(a,b,c,d,e,f){return sb.calcSplices(a,b,c,d,e,f)}function K(a,b,c,d){return c>b||a>d?-1:b==c||d==a?0:c>a?d>b?b-c:d-c:b>d?d-a:b-a}function L(a,b,c,d){for(var e=H(b,c,d),f=!1,g=0,h=0;h<a.length;h++){var i=a[h];if(i.index+=g,!f){var j=K(e.index,e.index+e.removed.length,i.index,i.index+i.addedCount);if(j>=0){a.splice(h,1),h--,g-=i.addedCount-i.removed.length,e.addedCount+=i.addedCount-j;var k=e.removed.length+i.removed.length-j;if(e.addedCount||k){var c=i.removed;if(e.index<i.index){var l=e.removed.slice(0,i.index-e.index);Array.prototype.push.apply(l,c),c=l}if(e.index+e.removed.length>i.index+i.addedCount){var m=e.removed.slice(i.index+i.addedCount-e.index);Array.prototype.push.apply(c,m)}e.removed=c,i.index<e.index&&(e.index=i.index)}else f=!0}else if(e.index<i.index){f=!0,a.splice(h,0,e),h++;var n=e.addedCount-e.removed.length;i.index+=n,g+=n}}}f||a.push(e)}function M(a,b){for(var c=[],f=0;f<b.length;f++){var g=b[f];switch(g.type){case"splice":L(c,g.index,g.removed.slice(),g.addedCount);break;case"add":case"update":case"delete":if(!d(g.name))continue;var h=e(g.name);if(0>h)continue;L(c,h,[g.oldValue],1);break;default:console.error("Unexpected record type: "+JSON.stringify(g))}}return c}function N(a,b){var c=[];return M(a,b).forEach(function(b){return 1==b.addedCount&&1==b.removed.length?void(b.removed[0]!==a[b.index]&&c.push(b)):void(c=c.concat(J(a,b.index,b.index+b.addedCount,b.removed,0,b.removed.length)))}),c}var O=a.testingExposeCycleCount,P=b(),Q=c(),R=a.Number.isNaN||function(b){return"number"==typeof b&&a.isNaN(b)},S="__proto__"in{}?function(a){return a}:function(a){var b=a.__proto__;if(!b)return a;var c=Object.create(b);return Object.getOwnPropertyNames(a).forEach(function(b){Object.defineProperty(c,b,Object.getOwnPropertyDescriptor(a,b))}),c},T="[$_a-zA-Z]",U="[$_a-zA-Z0-9]",V=new RegExp("^"+T+"+"+U+"*$"),W={beforePath:{ws:["beforePath"],ident:["inIdent","append"],"[":["beforeElement"],eof:["afterPath"]},inPath:{ws:["inPath"],".":["beforeIdent"],"[":["beforeElement"],eof:["afterPath"]},beforeIdent:{ws:["beforeIdent"],ident:["inIdent","append"]},inIdent:{ident:["inIdent","append"],0:["inIdent","append"],number:["inIdent","append"],ws:["inPath","push"],".":["beforeIdent","push"],"[":["beforeElement","push"],eof:["afterPath","push"]},beforeElement:{ws:["beforeElement"],0:["afterZero","append"],number:["inIndex","append"],"'":["inSingleQuote","append",""],'"':["inDoubleQuote","append",""]},afterZero:{ws:["afterElement","push"],"]":["inPath","push"]},inIndex:{0:["inIndex","append"],number:["inIndex","append"],ws:["afterElement"],"]":["inPath","push"]},inSingleQuote:{"'":["afterElement"],eof:["error"],"else":["inSingleQuote","append"]},inDoubleQuote:{'"':["afterElement"],eof:["error"],"else":["inDoubleQuote","append"]},afterElement:{ws:["afterElement"],"]":["inPath","push"]}},X={},Y={};l.get=m,l.prototype=S({__proto__:[],valid:!0,toString:function(){for(var a="",b=0;b<this.length;b++){var c=this[b];a+=k(c)?b?"."+c:c:n(c)}return a},getValueFrom:function(a){for(var b=0;b<this.length;b++){if(null==a)return;a=a[this[b]]}return a},iterateObjects:function(a,b){for(var c=0;c<this.length;c++){if(c&&(a=a[this[c-1]]),!f(a))return;b(a,this[c])}},compiledGetValueFromFn:function(){var a="",b="obj";a+="if (obj != null";for(var c,d=0;d<this.length-1;d++)c=this[d],b+=k(c)?"."+c:n(c),a+=" &&\n     "+b+" != null";a+=")\n";var c=this[d];return b+=k(c)?"."+c:n(c),a+="  return "+b+";\nelse\n  return undefined;",new Function("obj",a)},setValueFrom:function(a,b){if(!this.length)return!1;for(var c=0;c<this.length-1;c++){if(!f(a))return!1;a=a[this[c]]}return f(a)?(a[this[c]]=b,!0):!1}});var Z=new l("",X);Z.valid=!1,Z.getValueFrom=Z.setValueFrom=function(){};var $,_=1e3,ab=[],bb=P?function(){return function(a){return Promise.resolve().then(a)}}():function(){return function(a){ab.push(a)}}(),cb=[],db=[],eb=0,fb=1,gb=2,hb=3,ib=1;x.prototype={open:function(a,b){if(this.state_!=eb)throw Error("Observer has already been opened.");return y(this),this.callback_=a,this.target_=b,this.connect_(),this.state_=fb,this.value_},close:function(){this.state_==fb&&(z(this),this.disconnect_(),this.value_=void 0,this.callback_=void 0,this.target_=void 0,this.state_=gb)},deliver:function(){this.state_==fb&&o(this)},report_:function(a){try{this.callback_.apply(this.target_,a)}catch(b){x._errorThrownDuringCallback=!0,console.error("Exception caught during observer callback: "+(b.stack||b))}},discardChanges:function(){return this.check_(void 0,!0),this.value_}};var jb,kb=!P;x._allObserversCount=0,kb&&(jb=[]);var lb=!1;a.Platform=a.Platform||{},a.Platform.performMicrotaskCheckpoint=function(){if(!lb&&kb){lb=!0;var b,c,d=0;do{d++,c=jb,jb=[],b=!1;for(var e=0;e<c.length;e++){var f=c[e];f.state_==fb&&(f.check_()&&(b=!0),jb.push(f))}s()&&(b=!0)}while(_>d&&b);O&&(a.dirtyCheckCycleCount=d),lb=!1}},kb&&(a.Platform.clearObservers=function(){jb=[]}),A.prototype=S({__proto__:x.prototype,arrayObserve:!1,connect_:function(){P?this.directObserver_=u(this,this.value_,this.arrayObserve):this.oldObject_=this.copyObject(this.value_)},copyObject:function(a){var b=Array.isArray(a)?[]:{};for(var c in a)b[c]=a[c];return Array.isArray(a)&&(b.length=a.length),b},check_:function(a){var b,c;if(P){if(!a)return!1;c={},b=G(this.value_,a,c)}else c=this.oldObject_,b=r(this.value_,this.oldObject_);return q(b)?!1:(P||(this.oldObject_=this.copyObject(this.value_)),this.report_([b.added||{},b.removed||{},b.changed||{},function(a){return c[a]}]),!0)},disconnect_:function(){P?(this.directObserver_.close(),this.directObserver_=void 0):this.oldObject_=void 0},deliver:function(){this.state_==fb&&(P?this.directObserver_.deliver(!1):o(this))},discardChanges:function(){return this.directObserver_?this.directObserver_.deliver(!0):this.oldObject_=this.copyObject(this.value_),this.value_}}),B.prototype=S({__proto__:A.prototype,arrayObserve:!0,copyObject:function(a){return a.slice()},check_:function(a){var b;if(P){if(!a)return!1;b=N(this.value_,a)}else b=J(this.value_,0,this.value_.length,this.oldObject_,0,this.oldObject_.length);return b&&b.length?(P||(this.oldObject_=this.copyObject(this.value_)),this.report_([b]),!0):!1}}),B.applySplices=function(a,b,c){c.forEach(function(c){for(var d=[c.index,c.removed.length],e=c.index;e<c.index+c.addedCount;)d.push(b[e]),e++;Array.prototype.splice.apply(a,d)})},C.prototype=S({__proto__:x.prototype,get path(){return this.path_},connect_:function(){P&&(this.directObserver_=w(this,this.object_)),this.check_(void 0,!0)},disconnect_:function(){this.value_=void 0,this.directObserver_&&(this.directObserver_.close(this),this.directObserver_=void 0)},iterateObjects_:function(a){this.path_.iterateObjects(this.object_,a)},check_:function(a,b){var c=this.value_;return this.value_=this.path_.getValueFrom(this.object_),b||g(this.value_,c)?!1:(this.report_([this.value_,c,this]),!0)},setValue:function(a){this.path_&&this.path_.setValueFrom(this.object_,a)}});var mb={};D.prototype=S({__proto__:x.prototype,connect_:function(){if(P){for(var a,b=!1,c=0;c<this.observed_.length;c+=2)if(a=this.observed_[c],a!==mb){b=!0;break}b&&(this.directObserver_=w(this,a))}this.check_(void 0,!this.reportChangesOnOpen_)},disconnect_:function(){for(var a=0;a<this.observed_.length;a+=2)this.observed_[a]===mb&&this.observed_[a+1].close();this.observed_.length=0,this.value_.length=0,this.directObserver_&&(this.directObserver_.close(this),this.directObserver_=void 0)},addPath:function(a,b){if(this.state_!=eb&&this.state_!=hb)throw Error("Cannot add paths once started.");var b=m(b);if(this.observed_.push(a,b),this.reportChangesOnOpen_){var c=this.observed_.length/2-1;this.value_[c]=b.getValueFrom(a)}},addObserver:function(a){if(this.state_!=eb&&this.state_!=hb)throw Error("Cannot add observers once started.");if(this.observed_.push(mb,a),this.reportChangesOnOpen_){var b=this.observed_.length/2-1;this.value_[b]=a.open(this.deliver,this)}},startReset:function(){if(this.state_!=fb)throw Error("Can only reset while open");this.state_=hb,this.disconnect_()},finishReset:function(){if(this.state_!=hb)throw Error("Can only finishReset after startReset");return this.state_=fb,this.connect_(),this.value_},iterateObjects_:function(a){for(var b,c=0;c<this.observed_.length;c+=2)b=this.observed_[c],b!==mb&&this.observed_[c+1].iterateObjects(b,a)},check_:function(a,b){for(var c,d=0;d<this.observed_.length;d+=2){var e,f=this.observed_[d],h=this.observed_[d+1];if(f===mb){var i=h;e=this.state_===eb?i.open(this.deliver,this):i.discardChanges()}else e=h.getValueFrom(f);b?this.value_[d/2]=e:g(e,this.value_[d/2])||(c=c||[],c[d/2]=this.value_[d/2],this.value_[d/2]=e)}return c?(this.report_([this.value_,c,this.observed_]),!0):!1}}),F.prototype={open:function(a,b){return this.callback_=a,this.target_=b,this.value_=this.getValueFn_(this.observable_.open(this.observedCallback_,this)),this.value_},observedCallback_:function(a){if(a=this.getValueFn_(a),!g(a,this.value_)){var b=this.value_;this.value_=a,this.callback_.call(this.target_,this.value_,b)}},discardChanges:function(){return this.value_=this.getValueFn_(this.observable_.discardChanges()),this.value_},deliver:function(){return this.observable_.deliver()},setValue:function(a){return a=this.setValueFn_(a),!this.dontPassThroughSet_&&this.observable_.setValue?this.observable_.setValue(a):void 0},close:function(){this.observable_&&this.observable_.close(),this.callback_=void 0,this.target_=void 0,this.observable_=void 0,this.value_=void 0,this.getValueFn_=void 0,this.setValueFn_=void 0}};var nb={add:!0,update:!0,"delete":!0},ob=0,pb=1,qb=2,rb=3;I.prototype={calcEditDistances:function(a,b,c,d,e,f){for(var g=f-e+1,h=c-b+1,i=new Array(g),j=0;g>j;j++)i[j]=new Array(h),i[j][0]=j;for(var k=0;h>k;k++)i[0][k]=k;for(var j=1;g>j;j++)for(var k=1;h>k;k++)if(this.equals(a[b+k-1],d[e+j-1]))i[j][k]=i[j-1][k-1];else{var l=i[j-1][k]+1,m=i[j][k-1]+1;i[j][k]=m>l?l:m}return i},spliceOperationsFromEditDistances:function(a){for(var b=a.length-1,c=a[0].length-1,d=a[b][c],e=[];b>0||c>0;)if(0!=b)if(0!=c){var f,g=a[b-1][c-1],h=a[b-1][c],i=a[b][c-1];f=i>h?g>h?h:g:g>i?i:g,f==g?(g==d?e.push(ob):(e.push(pb),d=g),b--,c--):f==h?(e.push(rb),b--,d=h):(e.push(qb),c--,d=i)}else e.push(rb),b--;else e.push(qb),c--;return e.reverse(),e},calcSplices:function(a,b,c,d,e,f){var g=0,h=0,i=Math.min(c-b,f-e);if(0==b&&0==e&&(g=this.sharedPrefix(a,d,i)),c==a.length&&f==d.length&&(h=this.sharedSuffix(a,d,i-g)),b+=g,e+=g,c-=h,f-=h,c-b==0&&f-e==0)return[];if(b==c){for(var j=H(b,[],0);f>e;)j.removed.push(d[e++]);return[j]}if(e==f)return[H(b,[],c-b)];for(var k=this.spliceOperationsFromEditDistances(this.calcEditDistances(a,b,c,d,e,f)),j=void 0,l=[],m=b,n=e,o=0;o<k.length;o++)switch(k[o]){case ob:j&&(l.push(j),j=void 0),m++,n++;break;case pb:j||(j=H(m,[],0)),j.addedCount++,m++,j.removed.push(d[n]),n++;break;case qb:j||(j=H(m,[],0)),j.addedCount++,m++;break;case rb:j||(j=H(m,[],0)),j.removed.push(d[n]),n++}return j&&l.push(j),l},sharedPrefix:function(a,b,c){for(var d=0;c>d;d++)if(!this.equals(a[d],b[d]))return d;return c},sharedSuffix:function(a,b,c){for(var d=a.length,e=b.length,f=0;c>f&&this.equals(a[--d],b[--e]);)f++;return f},calculateSplices:function(a,b){return this.calcSplices(a,0,a.length,b,0,b.length)},equals:function(a,b){return a===b}};var sb=new I,tb=a;"undefined"==typeof exports||exports.nodeType||("undefined"!=typeof module&&module.exports&&(exports=module.exports),tb=exports),tb.Observer=x,tb.Observer.runEOM_=bb,tb.Observer.observerSentinel_=mb,tb.Observer.hasObjectObserve=P,tb.ArrayObserver=B,tb.ArrayObserver.calculateSplices=function(a,b){return sb.calculateSplices(a,b)},tb.ArraySplice=I,tb.ObjectObserver=A,tb.PathObserver=C,tb.CompoundObserver=D,tb.Path=l,tb.ObserverTransform=F}("undefined"!=typeof global&&global&&"undefined"!=typeof module&&module?global:this||window),function(){"use strict";function a(a){for(;a.parentNode;)a=a.parentNode;return"function"==typeof a.getElementById?a:null}function b(a,b,c){var d=a.bindings_;return d||(d=a.bindings_={}),d[b]&&c[b].close(),d[b]=c}function c(a,b,c){return c}function d(a){return null==a?"":a}function e(a,b){a.data=d(b)}function f(a){return function(b){return e(a,b)}}function g(a,b,c,e){return c?void(e?a.setAttribute(b,""):a.removeAttribute(b)):void a.setAttribute(b,d(e))}function h(a,b,c){return function(d){g(a,b,c,d)}}function i(a){switch(a.type){case"checkbox":return u;case"radio":case"select-multiple":case"select-one":return"change";case"range":if(/Trident|MSIE/.test(navigator.userAgent))return"change";default:return"input"}}function j(a,b,c,e){a[b]=(e||d)(c)}function k(a,b,c){return function(d){return j(a,b,d,c)}}function l(){}function m(a,b,c,d){function e(){var e="value"==b&&"number"==a.type;c.setValue(e?a.valueAsNumber:a[b]),c.discardChanges(),(d||l)(a),Platform.performMicrotaskCheckpoint()}var f=i(a);return a.addEventListener(f,e),{close:function(){a.removeEventListener(f,e),c.close()},observable_:c}}function n(a){return Boolean(a)}function o(b){if(b.form)return s(b.form.elements,function(a){return a!=b&&"INPUT"==a.tagName&&"radio"==a.type&&a.name==b.name});var c=a(b);if(!c)return[];var d=c.querySelectorAll('input[type="radio"][name="'+b.name+'"]');return s(d,function(a){return a!=b&&!a.form})}function p(a){"INPUT"===a.tagName&&"radio"===a.type&&o(a).forEach(function(a){var b=a.bindings_.checked;b&&b.observable_.setValue(!1)})}function q(a,b){var c,e,f,g=a.parentNode;g instanceof HTMLSelectElement&&g.bindings_&&g.bindings_.value&&(c=g,e=c.bindings_.value,f=c.value),a.value=d(b),c&&c.value!=f&&(e.observable_.setValue(c.value),e.observable_.discardChanges(),Platform.performMicrotaskCheckpoint())}function r(a){return function(b){q(a,b)}}var s=Array.prototype.filter.call.bind(Array.prototype.filter);Node.prototype.bind=function(a,b){console.error("Unhandled binding to Node: ",this,a,b)},Node.prototype.bindFinished=function(){};var t=c;Object.defineProperty(Platform,"enableBindingsReflection",{get:function(){return t===b},set:function(a){return t=a?b:c,a},configurable:!0}),Text.prototype.bind=function(a,b,c){if("textContent"!==a)return Node.prototype.bind.call(this,a,b,c);if(c)return e(this,b);var d=b;return e(this,d.open(f(this))),t(this,a,d)},Element.prototype.bind=function(a,b,c){var d="?"==a[a.length-1];if(d&&(this.removeAttribute(a),a=a.slice(0,-1)),c)return g(this,a,d,b);var e=b;return g(this,a,d,e.open(h(this,a,d))),t(this,a,e)};var u;!function(){var a=document.createElement("div"),b=a.appendChild(document.createElement("input"));b.setAttribute("type","checkbox");var c,d=0;b.addEventListener("click",function(){d++,c=c||"click"}),b.addEventListener("change",function(){d++,c=c||"change"});var e=document.createEvent("MouseEvent");e.initMouseEvent("click",!0,!0,window,0,0,0,0,0,!1,!1,!1,!1,0,null),b.dispatchEvent(e),u=1==d?"change":c}(),HTMLInputElement.prototype.bind=function(a,c,e){if("value"!==a&&"checked"!==a)return HTMLElement.prototype.bind.call(this,a,c,e);this.removeAttribute(a);var f="checked"==a?n:d,g="checked"==a?p:l;if(e)return j(this,a,c,f);var h=c,i=m(this,a,h,g);return j(this,a,h.open(k(this,a,f)),f),b(this,a,i)},HTMLTextAreaElement.prototype.bind=function(a,b,c){if("value"!==a)return HTMLElement.prototype.bind.call(this,a,b,c);if(this.removeAttribute("value"),c)return j(this,"value",b);var e=b,f=m(this,"value",e);return j(this,"value",e.open(k(this,"value",d))),t(this,a,f)},HTMLOptionElement.prototype.bind=function(a,b,c){if("value"!==a)return HTMLElement.prototype.bind.call(this,a,b,c);if(this.removeAttribute("value"),c)return q(this,b);var d=b,e=m(this,"value",d);
+return q(this,d.open(r(this))),t(this,a,e)},HTMLSelectElement.prototype.bind=function(a,c,d){if("selectedindex"===a&&(a="selectedIndex"),"selectedIndex"!==a&&"value"!==a)return HTMLElement.prototype.bind.call(this,a,c,d);if(this.removeAttribute(a),d)return j(this,a,c);var e=c,f=m(this,a,e);return j(this,a,e.open(k(this,a))),b(this,a,f)}}(this),function(a){"use strict";function b(a){if(!a)throw new Error("Assertion failed")}function c(a){for(var b;b=a.parentNode;)a=b;return a}function d(a,b){if(b){for(var d,e="#"+b;!d&&(a=c(a),a.protoContent_?d=a.protoContent_.querySelector(e):a.getElementById&&(d=a.getElementById(b)),!d&&a.templateCreator_);)a=a.templateCreator_;return d}}function e(a){return"template"==a.tagName&&"http://www.w3.org/2000/svg"==a.namespaceURI}function f(a){return"TEMPLATE"==a.tagName&&"http://www.w3.org/1999/xhtml"==a.namespaceURI}function g(a){return Boolean(L[a.tagName]&&a.hasAttribute("template"))}function h(a){return void 0===a.isTemplate_&&(a.isTemplate_="TEMPLATE"==a.tagName||g(a)),a.isTemplate_}function i(a,b){var c=a.querySelectorAll(N);h(a)&&b(a),G(c,b)}function j(a){function b(a){HTMLTemplateElement.decorate(a)||j(a.content)}i(a,b)}function k(a,b){Object.getOwnPropertyNames(b).forEach(function(c){Object.defineProperty(a,c,Object.getOwnPropertyDescriptor(b,c))})}function l(a){var b=a.ownerDocument;if(!b.defaultView)return b;var c=b.templateContentsOwner_;if(!c){for(c=b.implementation.createHTMLDocument("");c.lastChild;)c.removeChild(c.lastChild);b.templateContentsOwner_=c}return c}function m(a){if(!a.stagingDocument_){var b=a.ownerDocument;if(!b.stagingDocument_){b.stagingDocument_=b.implementation.createHTMLDocument(""),b.stagingDocument_.isStagingDocument=!0;var c=b.stagingDocument_.createElement("base");c.href=document.baseURI,b.stagingDocument_.head.appendChild(c),b.stagingDocument_.stagingDocument_=b.stagingDocument_}a.stagingDocument_=b.stagingDocument_}return a.stagingDocument_}function n(a){var b=a.ownerDocument.createElement("template");a.parentNode.insertBefore(b,a);for(var c=a.attributes,d=c.length;d-->0;){var e=c[d];K[e.name]&&("template"!==e.name&&b.setAttribute(e.name,e.value),a.removeAttribute(e.name))}return b}function o(a){var b=a.ownerDocument.createElement("template");a.parentNode.insertBefore(b,a);for(var c=a.attributes,d=c.length;d-->0;){var e=c[d];b.setAttribute(e.name,e.value),a.removeAttribute(e.name)}return a.parentNode.removeChild(a),b}function p(a,b,c){var d=a.content;if(c)return void d.appendChild(b);for(var e;e=b.firstChild;)d.appendChild(e)}function q(a){P?a.__proto__=HTMLTemplateElement.prototype:k(a,HTMLTemplateElement.prototype)}function r(a){a.setModelFn_||(a.setModelFn_=function(){a.setModelFnScheduled_=!1;var b=z(a,a.delegate_&&a.delegate_.prepareBinding);w(a,b,a.model_)}),a.setModelFnScheduled_||(a.setModelFnScheduled_=!0,Observer.runEOM_(a.setModelFn_))}function s(a,b,c,d){if(a&&a.length){for(var e,f=a.length,g=0,h=0,i=0,j=!0;f>h;){var g=a.indexOf("{{",h),k=a.indexOf("[[",h),l=!1,m="}}";if(k>=0&&(0>g||g>k)&&(g=k,l=!0,m="]]"),i=0>g?-1:a.indexOf(m,g+2),0>i){if(!e)return;e.push(a.slice(h));break}e=e||[],e.push(a.slice(h,g));var n=a.slice(g+2,i).trim();e.push(l),j=j&&l;var o=d&&d(n,b,c);e.push(null==o?Path.get(n):null),e.push(o),h=i+2}return h===f&&e.push(""),e.hasOnePath=5===e.length,e.isSimplePath=e.hasOnePath&&""==e[0]&&""==e[4],e.onlyOneTime=j,e.combinator=function(a){for(var b=e[0],c=1;c<e.length;c+=4){var d=e.hasOnePath?a:a[(c-1)/4];void 0!==d&&(b+=d),b+=e[c+3]}return b},e}}function t(a,b,c,d){if(b.hasOnePath){var e=b[3],f=e?e(d,c,!0):b[2].getValueFrom(d);return b.isSimplePath?f:b.combinator(f)}for(var g=[],h=1;h<b.length;h+=4){var e=b[h+2];g[(h-1)/4]=e?e(d,c):b[h+1].getValueFrom(d)}return b.combinator(g)}function u(a,b,c,d){var e=b[3],f=e?e(d,c,!1):new PathObserver(d,b[2]);return b.isSimplePath?f:new ObserverTransform(f,b.combinator)}function v(a,b,c,d){if(b.onlyOneTime)return t(a,b,c,d);if(b.hasOnePath)return u(a,b,c,d);for(var e=new CompoundObserver,f=1;f<b.length;f+=4){var g=b[f],h=b[f+2];if(h){var i=h(d,c,g);g?e.addPath(i):e.addObserver(i)}else{var j=b[f+1];g?e.addPath(j.getValueFrom(d)):e.addPath(d,j)}}return new ObserverTransform(e,b.combinator)}function w(a,b,c,d){for(var e=0;e<b.length;e+=2){var f=b[e],g=b[e+1],h=v(f,g,a,c),i=a.bind(f,h,g.onlyOneTime);i&&d&&d.push(i)}if(a.bindFinished(),b.isTemplate){a.model_=c;var j=a.processBindingDirectives_(b);d&&j&&d.push(j)}}function x(a,b,c){var d=a.getAttribute(b);return s(""==d?"{{}}":d,b,a,c)}function y(a,c){b(a);for(var d=[],e=0;e<a.attributes.length;e++){for(var f=a.attributes[e],g=f.name,i=f.value;"_"===g[0];)g=g.substring(1);if(!h(a)||g!==J&&g!==H&&g!==I){var j=s(i,g,a,c);j&&d.push(g,j)}}return h(a)&&(d.isTemplate=!0,d["if"]=x(a,J,c),d.bind=x(a,H,c),d.repeat=x(a,I,c),!d["if"]||d.bind||d.repeat||(d.bind=s("{{}}",H,a,c))),d}function z(a,b){if(a.nodeType===Node.ELEMENT_NODE)return y(a,b);if(a.nodeType===Node.TEXT_NODE){var c=s(a.data,"textContent",a,b);if(c)return["textContent",c]}return[]}function A(a,b,c,d,e,f,g){for(var h=b.appendChild(c.importNode(a,!1)),i=0,j=a.firstChild;j;j=j.nextSibling)A(j,h,c,d.children[i++],e,f,g);return d.isTemplate&&(HTMLTemplateElement.decorate(h,a),f&&h.setDelegate_(f)),w(h,d,e,g),h}function B(a,b){var c=z(a,b);c.children={};for(var d=0,e=a.firstChild;e;e=e.nextSibling)c.children[d++]=B(e,b);return c}function C(a){var b=a.id_;return b||(b=a.id_=S++),b}function D(a,b){var c=C(a);if(b){var d=b.bindingMaps[c];return d||(d=b.bindingMaps[c]=B(a,b.prepareBinding)||[]),d}var d=a.bindingMap_;return d||(d=a.bindingMap_=B(a,void 0)||[]),d}function E(a){this.closed=!1,this.templateElement_=a,this.instances=[],this.deps=void 0,this.iteratedValue=[],this.presentValue=void 0,this.arrayObserver=void 0}var F,G=Array.prototype.forEach.call.bind(Array.prototype.forEach);a.Map&&"function"==typeof a.Map.prototype.forEach?F=a.Map:(F=function(){this.keys=[],this.values=[]},F.prototype={set:function(a,b){var c=this.keys.indexOf(a);0>c?(this.keys.push(a),this.values.push(b)):this.values[c]=b},get:function(a){var b=this.keys.indexOf(a);if(!(0>b))return this.values[b]},"delete":function(a){var b=this.keys.indexOf(a);return 0>b?!1:(this.keys.splice(b,1),this.values.splice(b,1),!0)},forEach:function(a,b){for(var c=0;c<this.keys.length;c++)a.call(b||this,this.values[c],this.keys[c],this)}});"function"!=typeof document.contains&&(Document.prototype.contains=function(a){return a===this||a.parentNode===this?!0:this.documentElement.contains(a)});var H="bind",I="repeat",J="if",K={template:!0,repeat:!0,bind:!0,ref:!0,"if":!0},L={THEAD:!0,TBODY:!0,TFOOT:!0,TH:!0,TR:!0,TD:!0,COLGROUP:!0,COL:!0,CAPTION:!0,OPTION:!0,OPTGROUP:!0},M="undefined"!=typeof HTMLTemplateElement;M&&!function(){var a=document.createElement("template"),b=a.content.ownerDocument,c=b.appendChild(b.createElement("html")),d=c.appendChild(b.createElement("head")),e=b.createElement("base");e.href=document.baseURI,d.appendChild(e)}();var N="template, "+Object.keys(L).map(function(a){return a.toLowerCase()+"[template]"}).join(", ");document.addEventListener("DOMContentLoaded",function(){j(document),Platform.performMicrotaskCheckpoint()},!1),M||(a.HTMLTemplateElement=function(){throw TypeError("Illegal constructor")});var O,P="__proto__"in{};"function"==typeof MutationObserver&&(O=new MutationObserver(function(a){for(var b=0;b<a.length;b++)a[b].target.refChanged_()})),HTMLTemplateElement.decorate=function(a,c){if(a.templateIsDecorated_)return!1;var d=a;d.templateIsDecorated_=!0;var h=f(d)&&M,i=h,k=!h,m=!1;if(h||(g(d)?(b(!c),d=n(a),d.templateIsDecorated_=!0,h=M,m=!0):e(d)&&(d=o(a),d.templateIsDecorated_=!0,h=M)),!h){q(d);var r=l(d);d.content_=r.createDocumentFragment()}return c?d.instanceRef_=c:k?p(d,a,m):i&&j(d.content),!0},HTMLTemplateElement.bootstrap=j;var Q=a.HTMLUnknownElement||HTMLElement,R={get:function(){return this.content_},enumerable:!0,configurable:!0};M||(HTMLTemplateElement.prototype=Object.create(Q.prototype),Object.defineProperty(HTMLTemplateElement.prototype,"content",R)),k(HTMLTemplateElement.prototype,{bind:function(a,b,c){if("ref"!=a)return Element.prototype.bind.call(this,a,b,c);var d=this,e=c?b:b.open(function(a){d.setAttribute("ref",a),d.refChanged_()});return this.setAttribute("ref",e),this.refChanged_(),c?void 0:(this.bindings_?this.bindings_.ref=b:this.bindings_={ref:b},b)},processBindingDirectives_:function(a){return this.iterator_&&this.iterator_.closeDeps(),a["if"]||a.bind||a.repeat?(this.iterator_||(this.iterator_=new E(this)),this.iterator_.updateDependencies(a,this.model_),O&&O.observe(this,{attributes:!0,attributeFilter:["ref"]}),this.iterator_):void(this.iterator_&&(this.iterator_.close(),this.iterator_=void 0))},createInstance:function(a,b,c){b?c=this.newDelegate_(b):c||(c=this.delegate_),this.refContent_||(this.refContent_=this.ref_.content);var d=this.refContent_;if(null===d.firstChild)return T;var e=D(d,c),f=m(this),g=f.createDocumentFragment();g.templateCreator_=this,g.protoContent_=d,g.bindings_=[],g.terminator_=null;for(var h=g.templateInstance_={firstNode:null,lastNode:null,model:a},i=0,j=!1,k=d.firstChild;k;k=k.nextSibling){null===k.nextSibling&&(j=!0);var l=A(k,g,f,e.children[i++],a,c,g.bindings_);l.templateInstance_=h,j&&(g.terminator_=l)}return h.firstNode=g.firstChild,h.lastNode=g.lastChild,g.templateCreator_=void 0,g.protoContent_=void 0,g},get model(){return this.model_},set model(a){this.model_=a,r(this)},get bindingDelegate(){return this.delegate_&&this.delegate_.raw},refChanged_:function(){this.iterator_&&this.refContent_!==this.ref_.content&&(this.refContent_=void 0,this.iterator_.valueChanged(),this.iterator_.updateIteratedValue(this.iterator_.getUpdatedValue()))},clear:function(){this.model_=void 0,this.delegate_=void 0,this.bindings_&&this.bindings_.ref&&this.bindings_.ref.close(),this.refContent_=void 0,this.iterator_&&(this.iterator_.valueChanged(),this.iterator_.close(),this.iterator_=void 0)},setDelegate_:function(a){this.delegate_=a,this.bindingMap_=void 0,this.iterator_&&(this.iterator_.instancePositionChangedFn_=void 0,this.iterator_.instanceModelFn_=void 0)},newDelegate_:function(a){function b(b){var c=a&&a[b];if("function"==typeof c)return function(){return c.apply(a,arguments)}}if(a)return{bindingMaps:{},raw:a,prepareBinding:b("prepareBinding"),prepareInstanceModel:b("prepareInstanceModel"),prepareInstancePositionChanged:b("prepareInstancePositionChanged")}},set bindingDelegate(a){if(this.delegate_)throw Error("Template must be cleared before a new bindingDelegate can be assigned");this.setDelegate_(this.newDelegate_(a))},get ref_(){var a=d(this,this.getAttribute("ref"));if(a||(a=this.instanceRef_),!a)return this;var b=a.ref_;return b?b:a}});var S=1;Object.defineProperty(Node.prototype,"templateInstance",{get:function(){var a=this.templateInstance_;return a?a:this.parentNode?this.parentNode.templateInstance:void 0}});var T=document.createDocumentFragment();T.bindings_=[],T.terminator_=null,E.prototype={closeDeps:function(){var a=this.deps;a&&(a.ifOneTime===!1&&a.ifValue.close(),a.oneTime===!1&&a.value.close())},updateDependencies:function(a,b){this.closeDeps();var c=this.deps={},d=this.templateElement_,e=!0;if(a["if"]){if(c.hasIf=!0,c.ifOneTime=a["if"].onlyOneTime,c.ifValue=v(J,a["if"],d,b),e=c.ifValue,c.ifOneTime&&!e)return void this.valueChanged();c.ifOneTime||(e=e.open(this.updateIfValue,this))}a.repeat?(c.repeat=!0,c.oneTime=a.repeat.onlyOneTime,c.value=v(I,a.repeat,d,b)):(c.repeat=!1,c.oneTime=a.bind.onlyOneTime,c.value=v(H,a.bind,d,b));var f=c.value;return c.oneTime||(f=f.open(this.updateIteratedValue,this)),e?void this.updateValue(f):void this.valueChanged()},getUpdatedValue:function(){var a=this.deps.value;return this.deps.oneTime||(a=a.discardChanges()),a},updateIfValue:function(a){return a?void this.updateValue(this.getUpdatedValue()):void this.valueChanged()},updateIteratedValue:function(a){if(this.deps.hasIf){var b=this.deps.ifValue;if(this.deps.ifOneTime||(b=b.discardChanges()),!b)return void this.valueChanged()}this.updateValue(a)},updateValue:function(a){this.deps.repeat||(a=[a]);var b=this.deps.repeat&&!this.deps.oneTime&&Array.isArray(a);this.valueChanged(a,b)},valueChanged:function(a,b){Array.isArray(a)||(a=[]),a!==this.iteratedValue&&(this.unobserve(),this.presentValue=a,b&&(this.arrayObserver=new ArrayObserver(this.presentValue),this.arrayObserver.open(this.handleSplices,this)),this.handleSplices(ArrayObserver.calculateSplices(this.presentValue,this.iteratedValue)))},getLastInstanceNode:function(a){if(-1==a)return this.templateElement_;var b=this.instances[a],c=b.terminator_;if(!c)return this.getLastInstanceNode(a-1);if(c.nodeType!==Node.ELEMENT_NODE||this.templateElement_===c)return c;var d=c.iterator_;return d?d.getLastTemplateNode():c},getLastTemplateNode:function(){return this.getLastInstanceNode(this.instances.length-1)},insertInstanceAt:function(a,b){var c=this.getLastInstanceNode(a-1),d=this.templateElement_.parentNode;this.instances.splice(a,0,b),d.insertBefore(b,c.nextSibling)},extractInstanceAt:function(a){for(var b=this.getLastInstanceNode(a-1),c=this.getLastInstanceNode(a),d=this.templateElement_.parentNode,e=this.instances.splice(a,1)[0];c!==b;){var f=b.nextSibling;f==c&&(c=b),e.appendChild(d.removeChild(f))}return e},getDelegateFn:function(a){return a=a&&a(this.templateElement_),"function"==typeof a?a:null},handleSplices:function(a){if(!this.closed&&a.length){var b=this.templateElement_;if(!b.parentNode)return void this.close();ArrayObserver.applySplices(this.iteratedValue,this.presentValue,a);var c=b.delegate_;void 0===this.instanceModelFn_&&(this.instanceModelFn_=this.getDelegateFn(c&&c.prepareInstanceModel)),void 0===this.instancePositionChangedFn_&&(this.instancePositionChangedFn_=this.getDelegateFn(c&&c.prepareInstancePositionChanged));for(var d=new F,e=0,f=0;f<a.length;f++){for(var g=a[f],h=g.removed,i=0;i<h.length;i++){var j=h[i],k=this.extractInstanceAt(g.index+e);k!==T&&d.set(j,k)}e-=g.addedCount}for(var f=0;f<a.length;f++)for(var g=a[f],l=g.index;l<g.index+g.addedCount;l++){var j=this.iteratedValue[l],k=d.get(j);k?d["delete"](j):(this.instanceModelFn_&&(j=this.instanceModelFn_(j)),k=void 0===j?T:b.createInstance(j,void 0,c)),this.insertInstanceAt(l,k)}d.forEach(function(a){this.closeInstanceBindings(a)},this),this.instancePositionChangedFn_&&this.reportInstancesMoved(a)}},reportInstanceMoved:function(a){var b=this.instances[a];b!==T&&this.instancePositionChangedFn_(b.templateInstance_,a)},reportInstancesMoved:function(a){for(var b=0,c=0,d=0;d<a.length;d++){var e=a[d];if(0!=c)for(;b<e.index;)this.reportInstanceMoved(b),b++;else b=e.index;for(;b<e.index+e.addedCount;)this.reportInstanceMoved(b),b++;c+=e.addedCount-e.removed.length}if(0!=c)for(var f=this.instances.length;f>b;)this.reportInstanceMoved(b),b++},closeInstanceBindings:function(a){for(var b=a.bindings_,c=0;c<b.length;c++)b[c].close()},unobserve:function(){this.arrayObserver&&(this.arrayObserver.close(),this.arrayObserver=void 0)},close:function(){if(!this.closed){this.unobserve();for(var a=0;a<this.instances.length;a++)this.closeInstanceBindings(this.instances[a]);this.instances.length=0,this.closeDeps(),this.templateElement_.iterator_=void 0,this.closed=!0}}},HTMLTemplateElement.forAllTemplatesFrom_=i}(this),function(a){"use strict";function b(a){return void 0!==m[a]}function c(){h.call(this),this._isInvalid=!0}function d(a){return""==a&&c.call(this),a.toLowerCase()}function e(a){var b=a.charCodeAt(0);return b>32&&127>b&&-1==[34,35,60,62,63,96].indexOf(b)?a:encodeURIComponent(a)}function f(a){var b=a.charCodeAt(0);return b>32&&127>b&&-1==[34,35,60,62,96].indexOf(b)?a:encodeURIComponent(a)}function g(a,g,h){function i(a){t.push(a)}var j=g||"scheme start",k=0,l="",r=!1,s=!1,t=[];a:for(;(a[k-1]!=o||0==k)&&!this._isInvalid;){var u=a[k];switch(j){case"scheme start":if(!u||!p.test(u)){if(g){i("Invalid scheme.");break a}l="",j="no scheme";continue}l+=u.toLowerCase(),j="scheme";break;case"scheme":if(u&&q.test(u))l+=u.toLowerCase();else{if(":"!=u){if(g){if(o==u)break a;i("Code point not allowed in scheme: "+u);break a}l="",k=0,j="no scheme";continue}if(this._scheme=l,l="",g)break a;b(this._scheme)&&(this._isRelative=!0),j="file"==this._scheme?"relative":this._isRelative&&h&&h._scheme==this._scheme?"relative or authority":this._isRelative?"authority first slash":"scheme data"}break;case"scheme data":"?"==u?(query="?",j="query"):"#"==u?(this._fragment="#",j="fragment"):o!=u&&"	"!=u&&"\n"!=u&&"\r"!=u&&(this._schemeData+=e(u));break;case"no scheme":if(h&&b(h._scheme)){j="relative";continue}i("Missing scheme."),c.call(this);break;case"relative or authority":if("/"!=u||"/"!=a[k+1]){i("Expected /, got: "+u),j="relative";continue}j="authority ignore slashes";break;case"relative":if(this._isRelative=!0,"file"!=this._scheme&&(this._scheme=h._scheme),o==u){this._host=h._host,this._port=h._port,this._path=h._path.slice(),this._query=h._query;break a}if("/"==u||"\\"==u)"\\"==u&&i("\\ is an invalid code point."),j="relative slash";else if("?"==u)this._host=h._host,this._port=h._port,this._path=h._path.slice(),this._query="?",j="query";else{if("#"!=u){var v=a[k+1],w=a[k+2];("file"!=this._scheme||!p.test(u)||":"!=v&&"|"!=v||o!=w&&"/"!=w&&"\\"!=w&&"?"!=w&&"#"!=w)&&(this._host=h._host,this._port=h._port,this._path=h._path.slice(),this._path.pop()),j="relative path";continue}this._host=h._host,this._port=h._port,this._path=h._path.slice(),this._query=h._query,this._fragment="#",j="fragment"}break;case"relative slash":if("/"!=u&&"\\"!=u){"file"!=this._scheme&&(this._host=h._host,this._port=h._port),j="relative path";continue}"\\"==u&&i("\\ is an invalid code point."),j="file"==this._scheme?"file host":"authority ignore slashes";break;case"authority first slash":if("/"!=u){i("Expected '/', got: "+u),j="authority ignore slashes";continue}j="authority second slash";break;case"authority second slash":if(j="authority ignore slashes","/"!=u){i("Expected '/', got: "+u);continue}break;case"authority ignore slashes":if("/"!=u&&"\\"!=u){j="authority";continue}i("Expected authority, got: "+u);break;case"authority":if("@"==u){r&&(i("@ already seen."),l+="%40"),r=!0;for(var x=0;x<l.length;x++){var y=l[x];if("	"!=y&&"\n"!=y&&"\r"!=y)if(":"!=y||null!==this._password){var z=e(y);null!==this._password?this._password+=z:this._username+=z}else this._password="";else i("Invalid whitespace in authority.")}l=""}else{if(o==u||"/"==u||"\\"==u||"?"==u||"#"==u){k-=l.length,l="",j="host";continue}l+=u}break;case"file host":if(o==u||"/"==u||"\\"==u||"?"==u||"#"==u){2!=l.length||!p.test(l[0])||":"!=l[1]&&"|"!=l[1]?0==l.length?j="relative path start":(this._host=d.call(this,l),l="",j="relative path start"):j="relative path";continue}"	"==u||"\n"==u||"\r"==u?i("Invalid whitespace in file host."):l+=u;break;case"host":case"hostname":if(":"!=u||s){if(o==u||"/"==u||"\\"==u||"?"==u||"#"==u){if(this._host=d.call(this,l),l="",j="relative path start",g)break a;continue}"	"!=u&&"\n"!=u&&"\r"!=u?("["==u?s=!0:"]"==u&&(s=!1),l+=u):i("Invalid code point in host/hostname: "+u)}else if(this._host=d.call(this,l),l="",j="port","hostname"==g)break a;break;case"port":if(/[0-9]/.test(u))l+=u;else{if(o==u||"/"==u||"\\"==u||"?"==u||"#"==u||g){if(""!=l){var A=parseInt(l,10);A!=m[this._scheme]&&(this._port=A+""),l=""}if(g)break a;j="relative path start";continue}"	"==u||"\n"==u||"\r"==u?i("Invalid code point in port: "+u):c.call(this)}break;case"relative path start":if("\\"==u&&i("'\\' not allowed in path."),j="relative path","/"!=u&&"\\"!=u)continue;break;case"relative path":if(o!=u&&"/"!=u&&"\\"!=u&&(g||"?"!=u&&"#"!=u))"	"!=u&&"\n"!=u&&"\r"!=u&&(l+=e(u));else{"\\"==u&&i("\\ not allowed in relative path.");var B;(B=n[l.toLowerCase()])&&(l=B),".."==l?(this._path.pop(),"/"!=u&&"\\"!=u&&this._path.push("")):"."==l&&"/"!=u&&"\\"!=u?this._path.push(""):"."!=l&&("file"==this._scheme&&0==this._path.length&&2==l.length&&p.test(l[0])&&"|"==l[1]&&(l=l[0]+":"),this._path.push(l)),l="","?"==u?(this._query="?",j="query"):"#"==u&&(this._fragment="#",j="fragment")}break;case"query":g||"#"!=u?o!=u&&"	"!=u&&"\n"!=u&&"\r"!=u&&(this._query+=f(u)):(this._fragment="#",j="fragment");break;case"fragment":o!=u&&"	"!=u&&"\n"!=u&&"\r"!=u&&(this._fragment+=u)}k++}}function h(){this._scheme="",this._schemeData="",this._username="",this._password=null,this._host="",this._port="",this._path=[],this._query="",this._fragment="",this._isInvalid=!1,this._isRelative=!1}function i(a,b){void 0===b||b instanceof i||(b=new i(String(b))),this._url=a,h.call(this);var c=a.replace(/^[ \t\r\n\f]+|[ \t\r\n\f]+$/g,"");g.call(this,c,null,b)}var j=!1;if(!a.forceJURL)try{var k=new URL("b","http://a");k.pathname="c%20d",j="http://a/c%20d"===k.href}catch(l){}if(!j){var m=Object.create(null);m.ftp=21,m.file=0,m.gopher=70,m.http=80,m.https=443,m.ws=80,m.wss=443;var n=Object.create(null);n["%2e"]=".",n[".%2e"]="..",n["%2e."]="..",n["%2e%2e"]="..";var o=void 0,p=/[a-zA-Z]/,q=/[a-zA-Z0-9\+\-\.]/;i.prototype={get href(){if(this._isInvalid)return this._url;var a="";return(""!=this._username||null!=this._password)&&(a=this._username+(null!=this._password?":"+this._password:"")+"@"),this.protocol+(this._isRelative?"//"+a+this.host:"")+this.pathname+this._query+this._fragment},set href(a){h.call(this),g.call(this,a)},get protocol(){return this._scheme+":"},set protocol(a){this._isInvalid||g.call(this,a+":","scheme start")},get host(){return this._isInvalid?"":this._port?this._host+":"+this._port:this._host},set host(a){!this._isInvalid&&this._isRelative&&g.call(this,a,"host")},get hostname(){return this._host},set hostname(a){!this._isInvalid&&this._isRelative&&g.call(this,a,"hostname")},get port(){return this._port},set port(a){!this._isInvalid&&this._isRelative&&g.call(this,a,"port")},get pathname(){return this._isInvalid?"":this._isRelative?"/"+this._path.join("/"):this._schemeData},set pathname(a){!this._isInvalid&&this._isRelative&&(this._path=[],g.call(this,a,"relative path start"))},get search(){return this._isInvalid||!this._query||"?"==this._query?"":this._query},set search(a){!this._isInvalid&&this._isRelative&&(this._query="?","?"==a[0]&&(a=a.slice(1)),g.call(this,a,"query"))},get hash(){return this._isInvalid||!this._fragment||"#"==this._fragment?"":this._fragment},set hash(a){this._isInvalid||(this._fragment="#","#"==a[0]&&(a=a.slice(1)),g.call(this,a,"fragment"))},get origin(){var a;if(this._isInvalid||!this._scheme)return"";switch(this._scheme){case"data":case"file":case"javascript":case"mailto":return"null"}return a=this.host,a?this._scheme+"://"+a:""}};var r=a.URL;r&&(i.createObjectURL=function(){return r.createObjectURL.apply(r,arguments)},i.revokeObjectURL=function(a){r.revokeObjectURL(a)}),a.URL=i}}(this),function(a){function b(a){f.textContent=d++,e.push(a)}function c(){for(;e.length;)e.shift()()}var d=0,e=[],f=document.createTextNode("");new(window.MutationObserver||JsMutationObserver)(c).observe(f,{characterData:!0}),a.endOfMicrotask=b,Platform.endOfMicrotask=b}(Polymer),function(a){function b(){g||(g=!0,c(function(){g=!1,d.data&&console.group("flush"),Platform.performMicrotaskCheckpoint(),d.data&&console.groupEnd()}))}var c=a.endOfMicrotask,d=window.WebComponents?WebComponents.flags.log:{},e=document.createElement("style");e.textContent="template {display: none !important;} /* injected by platform.js */";var f=document.querySelector("head");f.insertBefore(e,f.firstChild);var g;if(Observer.hasObjectObserve)b=function(){};else{var h=125;window.addEventListener("WebComponentsReady",function(){b();var c=function(){"hidden"===document.visibilityState?a.flushPoll&&clearInterval(a.flushPoll):a.flushPoll=setInterval(b,h)};"string"==typeof document.visibilityState&&document.addEventListener("visibilitychange",c),c()})}if(window.CustomElements&&!CustomElements.useNative){var i=Document.prototype.importNode;Document.prototype.importNode=function(a,b){var c=i.call(this,a,b);return CustomElements.upgradeAll(c),c}}a.flush=b,Platform.flush=b}(window.Polymer),function(a){function b(a){var b=new URL(a.ownerDocument.baseURI);return b.search="",b.hash="",b}function c(a,b,c,e){return a.replace(e,function(a,e,f,g){var h=f.replace(/["']/g,"");return h=d(b,h,c),e+"'"+h+"'"+g})}function d(a,b,c){if(b&&"/"===b[0])return b;if(b&&"#"===b[0])return b;var d=new URL(b,a);return c?d.href:e(d.href)}function e(a){var c=b(document.documentElement),d=new URL(a,c);return d.host===c.host&&d.port===c.port&&d.protocol===c.protocol?f(c,d):a}function f(a,b){for(var c=a.pathname,d=b.pathname,e=c.split("/"),f=d.split("/");e.length&&e[0]===f[0];)e.shift(),f.shift();for(var g=0,h=e.length-1;h>g;g++)f.unshift("..");var i=b.href.slice(-1)===m?m:b.hash;return f.join("/")+b.search+i}var g={resolveDom:function(a,c){c=c||b(a),this.resolveAttributes(a,c),this.resolveStyles(a,c);var d=a.querySelectorAll("template");if(d)for(var e,f=0,g=d.length;g>f&&(e=d[f]);f++)e.content&&this.resolveDom(e.content,c)},resolveTemplate:function(a){this.resolveDom(a.content,b(a))},resolveStyles:function(a,b){var c=a.querySelectorAll("style");if(c)for(var d,e=0,f=c.length;f>e&&(d=c[e]);e++)this.resolveStyle(d,b)},resolveStyle:function(a,c){c=c||b(a),a.textContent=this.resolveCssText(a.textContent,c)},resolveCssText:function(a,b,d){return a=c(a,b,d,h),c(a,b,d,i)},resolveAttributes:function(a,b){a.hasAttributes&&a.hasAttributes()&&this.resolveElementAttributes(a,b);var c=a&&a.querySelectorAll(k);if(c)for(var d,e=0,f=c.length;f>e&&(d=c[e]);e++)this.resolveElementAttributes(d,b)},resolveElementAttributes:function(a,e){e=e||b(a),j.forEach(function(b){var f,g=a.attributes[b],i=g&&g.value;i&&i.search(l)<0&&(f="style"===b?c(i,e,!1,h):d(e,i),g.value=f)})}},h=/(url\()([^)]*)(\))/g,i=/(@import[\s]+(?!url\())([^;]*)(;)/g,j=["href","src","action","style","url"],k="["+j.join("],[")+"]",l="{{.*}}",m="#";a.urlResolver=g}(Polymer),function(a){function b(a){this.cache=Object.create(null),this.map=Object.create(null),this.requests=0,this.regex=a}var c=Polymer.endOfMicrotask;b.prototype={extractUrls:function(a,b){for(var c,d,e=[];c=this.regex.exec(a);)d=new URL(c[1],b),e.push({matched:c[0],url:d.href});return e},process:function(a,b,c){var d=this.extractUrls(a,b),e=c.bind(null,this.map);this.fetch(d,e)},fetch:function(a,b){var c=a.length;if(!c)return b();for(var d,e,f,g=function(){0===--c&&b()},h=0;c>h;h++)d=a[h],f=d.url,e=this.cache[f],e||(e=this.xhr(f),e.match=d,this.cache[f]=e),e.wait(g)},handleXhr:function(a){var b=a.match,c=b.url,d=a.response||a.responseText||"";this.map[c]=d,this.fetch(this.extractUrls(d,c),a.resolve)},xhr:function(a){this.requests++;var b=new XMLHttpRequest;return b.open("GET",a,!0),b.send(),b.onerror=b.onload=this.handleXhr.bind(this,b),b.pending=[],b.resolve=function(){for(var a=b.pending,c=0;c<a.length;c++)a[c]();b.pending=null},b.wait=function(a){b.pending?b.pending.push(a):c(a)},b}},a.Loader=b}(Polymer),function(a){function b(){this.loader=new d(this.regex)}var c=a.urlResolver,d=a.Loader;b.prototype={regex:/@import\s+(?:url)?["'\(]*([^'"\)]*)['"\)]*;/g,resolve:function(a,b,c){var d=function(d){c(this.flatten(a,b,d))}.bind(this);this.loader.process(a,b,d)},resolveNode:function(a,b,c){var d=a.textContent,e=function(b){a.textContent=b,c(a)};this.resolve(d,b,e)},flatten:function(a,b,d){for(var e,f,g,h=this.loader.extractUrls(a,b),i=0;i<h.length;i++)e=h[i],f=e.url,g=c.resolveCssText(d[f],f,!0),g=this.flatten(g,b,d),a=a.replace(e.matched,g);return a},loadStyles:function(a,b,c){function d(){f++,f===g&&c&&c()}for(var e,f=0,g=a.length,h=0;g>h&&(e=a[h]);h++)this.resolveNode(e,b,d)}};var e=new b;a.styleResolver=e}(Polymer),function(a){function b(a,b){return a&&b&&Object.getOwnPropertyNames(b).forEach(function(c){var d=Object.getOwnPropertyDescriptor(b,c);d&&(Object.defineProperty(a,c,d),"function"==typeof d.value&&(d.value.nom=c))}),a}function c(a){for(var b=a||{},c=1;c<arguments.length;c++){var e=arguments[c];try{for(var f in e)d(f,e,b)}catch(g){}}return b}function d(a,b,c){var d=e(b,a);Object.defineProperty(c,a,d)}function e(a,b){if(a){var c=Object.getOwnPropertyDescriptor(a,b);return c||e(Object.getPrototypeOf(a),b)}}a.extend=b,a.mixin=c,Platform.mixin=c}(Polymer),function(a){function b(a,b,d){return a?a.stop():a=new c(this),a.go(b,d),a}var c=function(a){this.context=a,this.boundComplete=this.complete.bind(this)};c.prototype={go:function(a,b){this.callback=a;var c;b?(c=setTimeout(this.boundComplete,b),this.handle=function(){clearTimeout(c)}):(c=requestAnimationFrame(this.boundComplete),this.handle=function(){cancelAnimationFrame(c)})},stop:function(){this.handle&&(this.handle(),this.handle=null)},complete:function(){this.handle&&(this.stop(),this.callback.call(this.context))}},a.job=b}(Polymer),function(a){function b(a,b,c){var d="string"==typeof a?document.createElement(a):a.cloneNode(!0);if(d.innerHTML=b,c)for(var e in c)d.setAttribute(e,c[e]);return d}var c={};HTMLElement.register=function(a,b){c[a]=b},HTMLElement.getPrototypeForTag=function(a){var b=a?c[a]:HTMLElement.prototype;return b||Object.getPrototypeOf(document.createElement(a))};var d=Event.prototype.stopPropagation;Event.prototype.stopPropagation=function(){this.cancelBubble=!0,d.apply(this,arguments)};var e=DOMTokenList.prototype.add,f=DOMTokenList.prototype.remove;DOMTokenList.prototype.add=function(){for(var a=0;a<arguments.length;a++)e.call(this,arguments[a])},DOMTokenList.prototype.remove=function(){for(var a=0;a<arguments.length;a++)f.call(this,arguments[a])},DOMTokenList.prototype.toggle=function(a,b){1==arguments.length&&(b=!this.contains(a)),b?this.add(a):this.remove(a)},DOMTokenList.prototype["switch"]=function(a,b){a&&this.remove(a),b&&this.add(b)};var g=function(){return Array.prototype.slice.call(this)},h=window.NamedNodeMap||window.MozNamedAttrMap||{};NodeList.prototype.array=g,h.prototype.array=g,HTMLCollection.prototype.array=g,a.createDOM=b}(Polymer),function(a){function b(a){var e=b.caller,g=e.nom,h=e._super;h||(g||(g=e.nom=c.call(this,e)),g||console.warn("called super() on a method not installed declaratively (has no .nom property)"),h=d(e,g,f(this)));var i=h[g];return i?(i._super||d(i,g,h),i.apply(this,a||[])):void 0}function c(a){for(var b=this.__proto__;b&&b!==HTMLElement.prototype;){for(var c,d=Object.getOwnPropertyNames(b),e=0,f=d.length;f>e&&(c=d[e]);e++){var g=Object.getOwnPropertyDescriptor(b,c);if("function"==typeof g.value&&g.value===a)return c}b=b.__proto__}}function d(a,b,c){var d=e(c,b,a);return d[b]&&(d[b].nom=b),a._super=d}function e(a,b,c){for(;a;){if(a[b]!==c&&a[b])return a;a=f(a)}return Object}function f(a){return a.__proto__}a["super"]=b}(Polymer),function(a){function b(a){return a}function c(a,b){var c=typeof b;return b instanceof Date&&(c="date"),d[c](a,b)}var d={string:b,undefined:b,date:function(a){return new Date(Date.parse(a)||Date.now())},"boolean":function(a){return""===a?!0:"false"===a?!1:!!a},number:function(a){var b=parseFloat(a);return 0===b&&(b=parseInt(a)),isNaN(b)?a:b},object:function(a,b){if(null===b)return a;try{return JSON.parse(a.replace(/'/g,'"'))}catch(c){return a}},"function":function(a,b){return b}};a.deserializeValue=c}(Polymer),function(a){var b=a.extend,c={};c.declaration={},c.instance={},c.publish=function(a,c){for(var d in a)b(c,a[d])},a.api=c}(Polymer),function(a){var b={async:function(a,b,c){Polymer.flush(),b=b&&b.length?b:[b];var d=function(){(this[a]||a).apply(this,b)}.bind(this),e=c?setTimeout(d,c):requestAnimationFrame(d);return c?e:~e},cancelAsync:function(a){0>a?cancelAnimationFrame(~a):clearTimeout(a)},fire:function(a,b,c,d,e){var f=c||this,b=null===b||void 0===b?{}:b,g=new CustomEvent(a,{bubbles:void 0!==d?d:!0,cancelable:void 0!==e?e:!0,detail:b});return f.dispatchEvent(g),g},asyncFire:function(){this.async("fire",arguments)},classFollows:function(a,b,c){b&&b.classList.remove(c),a&&a.classList.add(c)},injectBoundHTML:function(a,b){var c=document.createElement("template");c.innerHTML=a;var d=this.instanceTemplate(c);return b&&(b.textContent="",b.appendChild(d)),d}},c=function(){},d={};b.asyncMethod=b.async,a.api.instance.utils=b,a.nop=c,a.nob=d}(Polymer),function(a){var b=window.WebComponents?WebComponents.flags.log:{},c="on-",d={EVENT_PREFIX:c,addHostListeners:function(){var a=this.eventDelegates;
+b.events&&Object.keys(a).length>0&&console.log("[%s] addHostListeners:",this.localName,a);for(var c in a){var d=a[c];PolymerGestures.addEventListener(this,c,this.element.getEventHandler(this,this,d))}},dispatchMethod:function(a,c,d){if(a){b.events&&console.group("[%s] dispatch [%s]",a.localName,c);var e="function"==typeof c?c:a[c];e&&e[d?"apply":"call"](a,d),b.events&&console.groupEnd(),Polymer.flush()}}};a.api.instance.events=d,a.addEventListener=function(a,b,c,d){PolymerGestures.addEventListener(wrap(a),b,c,d)},a.removeEventListener=function(a,b,c,d){PolymerGestures.removeEventListener(wrap(a),b,c,d)}}(Polymer),function(a){var b={copyInstanceAttributes:function(){var a=this._instanceAttributes;for(var b in a)this.hasAttribute(b)||this.setAttribute(b,a[b])},takeAttributes:function(){if(this._publishLC)for(var a,b=0,c=this.attributes,d=c.length;(a=c[b])&&d>b;b++)this.attributeToProperty(a.name,a.value)},attributeToProperty:function(b,c){var b=this.propertyForAttribute(b);if(b){if(c&&c.search(a.bindPattern)>=0)return;var d=this[b],c=this.deserializeValue(c,d);c!==d&&(this[b]=c)}},propertyForAttribute:function(a){var b=this._publishLC&&this._publishLC[a];return b},deserializeValue:function(b,c){return a.deserializeValue(b,c)},serializeValue:function(a,b){return"boolean"===b?a?"":void 0:"object"!==b&&"function"!==b&&void 0!==a?a:void 0},reflectPropertyToAttribute:function(a){var b=typeof this[a],c=this.serializeValue(this[a],b);void 0!==c?this.setAttribute(a,c):"boolean"===b&&this.removeAttribute(a)}};a.api.instance.attributes=b}(Polymer),function(a){function b(a,b){return a===b?0!==a||1/a===1/b:f(a)&&f(b)?!0:a!==a&&b!==b}function c(a,b){return void 0===b&&null===a?b:null===b||void 0===b?a:b}var d=window.WebComponents?WebComponents.flags.log:{},e={object:void 0,type:"update",name:void 0,oldValue:void 0},f=Number.isNaN||function(a){return"number"==typeof a&&isNaN(a)},g={createPropertyObserver:function(){var a=this._observeNames;if(a&&a.length){var b=this._propertyObserver=new CompoundObserver(!0);this.registerObserver(b);for(var c,d=0,e=a.length;e>d&&(c=a[d]);d++)b.addPath(this,c),this.observeArrayValue(c,this[c],null)}},openPropertyObserver:function(){this._propertyObserver&&this._propertyObserver.open(this.notifyPropertyChanges,this)},notifyPropertyChanges:function(a,b,c){var d,e,f={};for(var g in b)if(d=c[2*g+1],e=this.observe[d]){var h=b[g],i=a[g];this.observeArrayValue(d,i,h),f[e]||(void 0!==h&&null!==h||void 0!==i&&null!==i)&&(f[e]=!0,this.invokeMethod(e,[h,i,arguments]))}},invokeMethod:function(a,b){var c=this[a]||a;"function"==typeof c&&c.apply(this,b)},deliverChanges:function(){this._propertyObserver&&this._propertyObserver.deliver()},observeArrayValue:function(a,b,c){var e=this.observe[a];if(e&&(Array.isArray(c)&&(d.observe&&console.log("[%s] observeArrayValue: unregister observer [%s]",this.localName,a),this.closeNamedObserver(a+"__array")),Array.isArray(b))){d.observe&&console.log("[%s] observeArrayValue: register observer [%s]",this.localName,a,b);var f=new ArrayObserver(b);f.open(function(a){this.invokeMethod(e,[a])},this),this.registerNamedObserver(a+"__array",f)}},emitPropertyChangeRecord:function(a,c,d){if(!b(c,d)&&(this._propertyChanged(a,c,d),Observer.hasObjectObserve)){var f=this._objectNotifier;f||(f=this._objectNotifier=Object.getNotifier(this)),e.object=this,e.name=a,e.oldValue=d,f.notify(e)}},_propertyChanged:function(a){this.reflect[a]&&this.reflectPropertyToAttribute(a)},bindProperty:function(a,b,d){if(d)return void(this[a]=b);var e=this.element.prototype.computed;if(e&&e[a]){var f=a+"ComputedBoundObservable_";return void(this[f]=b)}return this.bindToAccessor(a,b,c)},bindToAccessor:function(a,c,d){function e(b,c){j[f]=b;var d=j[h];d&&"function"==typeof d.setValue&&d.setValue(b),j.emitPropertyChangeRecord(a,b,c)}var f=a+"_",g=a+"Observable_",h=a+"ComputedBoundObservable_";this[g]=c;var i=this[f],j=this,k=c.open(e);if(d&&!b(i,k)){var l=d(i,k);b(k,l)||(k=l,c.setValue&&c.setValue(k))}e(k,i);var m={close:function(){c.close(),j[g]=void 0,j[h]=void 0}};return this.registerObserver(m),m},createComputedProperties:function(){if(this._computedNames)for(var a=0;a<this._computedNames.length;a++){var b=this._computedNames[a],c=this.computed[b];try{var d=PolymerExpressions.getExpression(c),e=d.getBinding(this,this.element.syntax);this.bindToAccessor(b,e)}catch(f){console.error("Failed to create computed property",f)}}},registerObserver:function(a){return this._observers?void this._observers.push(a):void(this._observers=[a])},closeObservers:function(){if(this._observers){for(var a=this._observers,b=0;b<a.length;b++){var c=a[b];c&&"function"==typeof c.close&&c.close()}this._observers=[]}},registerNamedObserver:function(a,b){var c=this._namedObservers||(this._namedObservers={});c[a]=b},closeNamedObserver:function(a){var b=this._namedObservers;return b&&b[a]?(b[a].close(),b[a]=null,!0):void 0},closeNamedObservers:function(){if(this._namedObservers){for(var a in this._namedObservers)this.closeNamedObserver(a);this._namedObservers={}}}};a.api.instance.properties=g}(Polymer),function(a){var b=window.WebComponents?WebComponents.flags.log:{},c={instanceTemplate:function(a){HTMLTemplateElement.decorate(a);for(var b=this.syntax||!a.bindingDelegate&&this.element.syntax,c=a.createInstance(this,b),d=c.bindings_,e=0;e<d.length;e++)this.registerObserver(d[e]);return c},bind:function(a,b,c){var d=this.propertyForAttribute(a);if(d){var e=this.bindProperty(d,b,c);return Platform.enableBindingsReflection&&e&&(e.path=b.path_,this._recordBinding(d,e)),this.reflect[d]&&this.reflectPropertyToAttribute(d),e}return this.mixinSuper(arguments)},_recordBinding:function(a,b){this.bindings_=this.bindings_||{},this.bindings_[a]=b},bindFinished:function(){this.makeElementReady()},asyncUnbindAll:function(){this._unbound||(b.unbind&&console.log("[%s] asyncUnbindAll",this.localName),this._unbindAllJob=this.job(this._unbindAllJob,this.unbindAll,0))},unbindAll:function(){this._unbound||(this.closeObservers(),this.closeNamedObservers(),this._unbound=!0)},cancelUnbindAll:function(){return this._unbound?void(b.unbind&&console.warn("[%s] already unbound, cannot cancel unbindAll",this.localName)):(b.unbind&&console.log("[%s] cancelUnbindAll",this.localName),void(this._unbindAllJob&&(this._unbindAllJob=this._unbindAllJob.stop())))}},d=/\{\{([^{}]*)}}/;a.bindPattern=d,a.api.instance.mdv=c}(Polymer),function(a){function b(a){return a.hasOwnProperty("PolymerBase")}function c(){}var d={PolymerBase:!0,job:function(a,b,c){if("string"!=typeof a)return Polymer.job.call(this,a,b,c);var d="___"+a;this[d]=Polymer.job.call(this,this[d],b,c)},"super":Polymer["super"],created:function(){},ready:function(){},createdCallback:function(){this.templateInstance&&this.templateInstance.model&&console.warn("Attributes on "+this.localName+" were data bound prior to Polymer upgrading the element. This may result in incorrect binding types."),this.created(),this.prepareElement(),this.ownerDocument.isStagingDocument||this.makeElementReady()},prepareElement:function(){return this._elementPrepared?void console.warn("Element already prepared",this.localName):(this._elementPrepared=!0,this.shadowRoots={},this.createPropertyObserver(),this.openPropertyObserver(),this.copyInstanceAttributes(),this.takeAttributes(),void this.addHostListeners())},makeElementReady:function(){this._readied||(this._readied=!0,this.createComputedProperties(),this.parseDeclarations(this.__proto__),this.removeAttribute("unresolved"),this.ready())},attributeChangedCallback:function(a){"class"!==a&&"style"!==a&&this.attributeToProperty(a,this.getAttribute(a)),this.attributeChanged&&this.attributeChanged.apply(this,arguments)},attachedCallback:function(){this.cancelUnbindAll(),this.attached&&this.attached(),this.hasBeenAttached||(this.hasBeenAttached=!0,this.domReady&&this.async("domReady"))},detachedCallback:function(){this.preventDispose||this.asyncUnbindAll(),this.detached&&this.detached(),this.leftView&&this.leftView()},parseDeclarations:function(a){a&&a.element&&(this.parseDeclarations(a.__proto__),a.parseDeclaration.call(this,a.element))},parseDeclaration:function(a){var b=this.fetchTemplate(a);if(b){var c=this.shadowFromTemplate(b);this.shadowRoots[a.name]=c}},fetchTemplate:function(a){return a.querySelector("template")},shadowFromTemplate:function(a){if(a){var b=this.createShadowRoot(),c=this.instanceTemplate(a);return b.appendChild(c),this.shadowRootReady(b,a),b}},lightFromTemplate:function(a,b){if(a){this.eventController=this;var c=this.instanceTemplate(a);return b?this.insertBefore(c,b):this.appendChild(c),this.shadowRootReady(this),c}},shadowRootReady:function(a){this.marshalNodeReferences(a)},marshalNodeReferences:function(a){var b=this.$=this.$||{};if(a)for(var c,d=a.querySelectorAll("[id]"),e=0,f=d.length;f>e&&(c=d[e]);e++)b[c.id]=c},onMutation:function(a,b){var c=new MutationObserver(function(a){b.call(this,c,a),c.disconnect()}.bind(this));c.observe(a,{childList:!0,subtree:!0})}};c.prototype=d,d.constructor=c,a.Base=c,a.isBase=b,a.api.instance.base=d}(Polymer),function(a){function b(a){return a.__proto__}function c(a,b){var c="",d=!1;b&&(c=b.localName,d=b.hasAttribute("is"));var e=WebComponents.ShadowCSS.makeScopeSelector(c,d);return WebComponents.ShadowCSS.shimCssText(a,e)}var d=(window.WebComponents?WebComponents.flags.log:{},window.ShadowDOMPolyfill),e="element",f="controller",g={STYLE_SCOPE_ATTRIBUTE:e,installControllerStyles:function(){var a=this.findStyleScope();if(a&&!this.scopeHasNamedStyle(a,this.localName)){for(var c=b(this),d="";c&&c.element;)d+=c.element.cssTextForScope(f),c=b(c);d&&this.installScopeCssText(d,a)}},installScopeStyle:function(a,b,c){var c=c||this.findStyleScope(),b=b||"";if(c&&!this.scopeHasNamedStyle(c,this.localName+b)){var d="";if(a instanceof Array)for(var e,f=0,g=a.length;g>f&&(e=a[f]);f++)d+=e.textContent+"\n\n";else d=a.textContent;this.installScopeCssText(d,c,b)}},installScopeCssText:function(a,b,e){if(b=b||this.findStyleScope(),e=e||"",b){d&&(a=c(a,b.host));var g=this.element.cssTextToScopeStyle(a,f);Polymer.applyStyleToScope(g,b),this.styleCacheForScope(b)[this.localName+e]=!0}},findStyleScope:function(a){for(var b=a||this;b.parentNode;)b=b.parentNode;return b},scopeHasNamedStyle:function(a,b){var c=this.styleCacheForScope(a);return c[b]},styleCacheForScope:function(a){if(d){var b=a.host?a.host.localName:a.localName;return h[b]||(h[b]={})}return a._scopeStyles=a._scopeStyles||{}}},h={};a.api.instance.styles=g}(Polymer),function(a){function b(a,b){if("string"!=typeof a){var c=b||document._currentScript;if(b=a,a=c&&c.parentNode&&c.parentNode.getAttribute?c.parentNode.getAttribute("name"):"",!a)throw"Element name could not be inferred."}if(f(a))throw"Already registered (Polymer) prototype for element "+a;e(a,b),d(a)}function c(a,b){i[a]=b}function d(a){i[a]&&(i[a].registerWhenReady(),delete i[a])}function e(a,b){return j[a]=b||{}}function f(a){return j[a]}function g(a,b){if("string"!=typeof b)return!1;var c=HTMLElement.getPrototypeForTag(b),d=c&&c.constructor;return d?CustomElements["instanceof"]?CustomElements["instanceof"](a,d):a instanceof d:!1}var h=a.extend,i=(a.api,{}),j={};a.getRegisteredPrototype=f,a.waitingForPrototype=c,a.instanceOfType=g,window.Polymer=b,h(Polymer,a),WebComponents.consumeDeclarations&&WebComponents.consumeDeclarations(function(a){if(a)for(var c,d=0,e=a.length;e>d&&(c=a[d]);d++)b.apply(null,c)})}(Polymer),function(a){var b={resolveElementPaths:function(a){Polymer.urlResolver.resolveDom(a)},addResolvePathApi:function(){var a=this.getAttribute("assetpath")||"",b=new URL(a,this.ownerDocument.baseURI);this.prototype.resolvePath=function(a,c){var d=new URL(a,c||b);return d.href}}};a.api.declaration.path=b}(Polymer),function(a){function b(a,b){var c=new URL(a.getAttribute("href"),b).href;return"@import '"+c+"';"}function c(a,b){if(a){b===document&&(b=document.head),i&&(b=document.head);var c=d(a.textContent),e=a.getAttribute(h);e&&c.setAttribute(h,e);var f=b.firstElementChild;if(b===document.head){var g="style["+h+"]",j=document.head.querySelectorAll(g);j.length&&(f=j[j.length-1].nextElementSibling)}b.insertBefore(c,f)}}function d(a,b){b=b||document,b=b.createElement?b:b.ownerDocument;var c=b.createElement("style");return c.textContent=a,c}function e(a){return a&&a.__resource||""}function f(a,b){return q?q.call(a,b):void 0}var g=(window.WebComponents?WebComponents.flags.log:{},a.api.instance.styles),h=g.STYLE_SCOPE_ATTRIBUTE,i=window.ShadowDOMPolyfill,j="style",k="@import",l="link[rel=stylesheet]",m="global",n="polymer-scope",o={loadStyles:function(a){var b=this.fetchTemplate(),c=b&&this.templateContent();if(c){this.convertSheetsToStyles(c);var d=this.findLoadableStyles(c);if(d.length){var e=b.ownerDocument.baseURI;return Polymer.styleResolver.loadStyles(d,e,a)}}a&&a()},convertSheetsToStyles:function(a){for(var c,e,f=a.querySelectorAll(l),g=0,h=f.length;h>g&&(c=f[g]);g++)e=d(b(c,this.ownerDocument.baseURI),this.ownerDocument),this.copySheetAttributes(e,c),c.parentNode.replaceChild(e,c)},copySheetAttributes:function(a,b){for(var c,d=0,e=b.attributes,f=e.length;(c=e[d])&&f>d;d++)"rel"!==c.name&&"href"!==c.name&&a.setAttribute(c.name,c.value)},findLoadableStyles:function(a){var b=[];if(a)for(var c,d=a.querySelectorAll(j),e=0,f=d.length;f>e&&(c=d[e]);e++)c.textContent.match(k)&&b.push(c);return b},installSheets:function(){this.cacheSheets(),this.cacheStyles(),this.installLocalSheets(),this.installGlobalStyles()},cacheSheets:function(){this.sheets=this.findNodes(l),this.sheets.forEach(function(a){a.parentNode&&a.parentNode.removeChild(a)})},cacheStyles:function(){this.styles=this.findNodes(j+"["+n+"]"),this.styles.forEach(function(a){a.parentNode&&a.parentNode.removeChild(a)})},installLocalSheets:function(){var a=this.sheets.filter(function(a){return!a.hasAttribute(n)}),b=this.templateContent();if(b){var c="";if(a.forEach(function(a){c+=e(a)+"\n"}),c){var f=d(c,this.ownerDocument);b.insertBefore(f,b.firstChild)}}},findNodes:function(a,b){var c=this.querySelectorAll(a).array(),d=this.templateContent();if(d){var e=d.querySelectorAll(a).array();c=c.concat(e)}return b?c.filter(b):c},installGlobalStyles:function(){var a=this.styleForScope(m);c(a,document.head)},cssTextForScope:function(a){var b="",c="["+n+"="+a+"]",d=function(a){return f(a,c)},g=this.sheets.filter(d);g.forEach(function(a){b+=e(a)+"\n\n"});var h=this.styles.filter(d);return h.forEach(function(a){b+=a.textContent+"\n\n"}),b},styleForScope:function(a){var b=this.cssTextForScope(a);return this.cssTextToScopeStyle(b,a)},cssTextToScopeStyle:function(a,b){if(a){var c=d(a);return c.setAttribute(h,this.getAttribute("name")+"-"+b),c}}},p=HTMLElement.prototype,q=p.matches||p.matchesSelector||p.webkitMatchesSelector||p.mozMatchesSelector;a.api.declaration.styles=o,a.applyStyleToScope=c}(Polymer),function(a){var b=(window.WebComponents?WebComponents.flags.log:{},a.api.instance.events),c=b.EVENT_PREFIX,d={};["webkitAnimationStart","webkitAnimationEnd","webkitTransitionEnd","DOMFocusOut","DOMFocusIn","DOMMouseScroll"].forEach(function(a){d[a.toLowerCase()]=a});var e={parseHostEvents:function(){var a=this.prototype.eventDelegates;this.addAttributeDelegates(a)},addAttributeDelegates:function(a){for(var b,c=0;b=this.attributes[c];c++)this.hasEventPrefix(b.name)&&(a[this.removeEventPrefix(b.name)]=b.value.replace("{{","").replace("}}","").trim())},hasEventPrefix:function(a){return a&&"o"===a[0]&&"n"===a[1]&&"-"===a[2]},removeEventPrefix:function(a){return a.slice(f)},findController:function(a){for(;a.parentNode;){if(a.eventController)return a.eventController;a=a.parentNode}return a.host},getEventHandler:function(a,b,c){var d=this;return function(e){a&&a.PolymerBase||(a=d.findController(b));var f=[e,e.detail,e.currentTarget];a.dispatchMethod(a,c,f)}},prepareEventBinding:function(a,b){if(this.hasEventPrefix(b)){var c=this.removeEventPrefix(b);c=d[c]||c;var e=this;return function(b,d,f){function g(){return"{{ "+a+" }}"}var h=e.getEventHandler(void 0,d,a);return PolymerGestures.addEventListener(d,c,h),f?void 0:{open:g,discardChanges:g,close:function(){PolymerGestures.removeEventListener(d,c,h)}}}}}},f=c.length;a.api.declaration.events=e}(Polymer),function(a){var b=["attribute"],c={inferObservers:function(a){var b,c=a.observe;for(var d in a)"Changed"===d.slice(-7)&&(b=d.slice(0,-7),this.canObserveProperty(b)&&(c||(c=a.observe={}),c[b]=c[b]||d))},canObserveProperty:function(a){return b.indexOf(a)<0},explodeObservers:function(a){var b=a.observe;if(b){var c={};for(var d in b)for(var e,f=d.split(" "),g=0;e=f[g];g++)c[e]=b[d];a.observe=c}},optimizePropertyMaps:function(a){if(a.observe){var b=a._observeNames=[];for(var c in a.observe)for(var d,e=c.split(" "),f=0;d=e[f];f++)b.push(d)}if(a.publish){var b=a._publishNames=[];for(var c in a.publish)b.push(c)}if(a.computed){var b=a._computedNames=[];for(var c in a.computed)b.push(c)}},publishProperties:function(a,b){var c=a.publish;c&&(this.requireProperties(c,a,b),this.filterInvalidAccessorNames(c),a._publishLC=this.lowerCaseMap(c));var d=a.computed;d&&this.filterInvalidAccessorNames(d)},filterInvalidAccessorNames:function(a){for(var b in a)this.propertyNameBlacklist[b]&&(console.warn('Cannot define property "'+b+'" for element "'+this.name+'" because it has the same name as an HTMLElement property, and not all browsers support overriding that. Consider giving it a different name.'),delete a[b])},requireProperties:function(a,b){b.reflect=b.reflect||{};for(var c in a){var d=a[c];d&&void 0!==d.reflect&&(b.reflect[c]=Boolean(d.reflect),d=d.value),void 0!==d&&(b[c]=d)}},lowerCaseMap:function(a){var b={};for(var c in a)b[c.toLowerCase()]=c;return b},createPropertyAccessor:function(a,b){var c=this.prototype,d=a+"_",e=a+"Observable_";c[d]=c[a],Object.defineProperty(c,a,{get:function(){var a=this[e];return a&&a.deliver(),this[d]},set:function(c){if(b)return this[d];var f=this[e];if(f)return void f.setValue(c);var g=this[d];return this[d]=c,this.emitPropertyChangeRecord(a,c,g),c},configurable:!0})},createPropertyAccessors:function(a){var b=a._computedNames;if(b&&b.length)for(var c,d=0,e=b.length;e>d&&(c=b[d]);d++)this.createPropertyAccessor(c,!0);var b=a._publishNames;if(b&&b.length)for(var c,d=0,e=b.length;e>d&&(c=b[d]);d++)a.computed&&a.computed[c]||this.createPropertyAccessor(c)},propertyNameBlacklist:{children:1,"class":1,id:1,hidden:1,style:1,title:1}};a.api.declaration.properties=c}(Polymer),function(a){var b="attributes",c=/\s|,/,d={inheritAttributesObjects:function(a){this.inheritObject(a,"publishLC"),this.inheritObject(a,"_instanceAttributes")},publishAttributes:function(a){var d=this.getAttribute(b);if(d)for(var e,f=a.publish||(a.publish={}),g=d.split(c),h=0,i=g.length;i>h;h++)e=g[h].trim(),e&&void 0===f[e]&&(f[e]=void 0)},accumulateInstanceAttributes:function(){for(var a,b=this.prototype._instanceAttributes,c=this.attributes,d=0,e=c.length;e>d&&(a=c[d]);d++)this.isInstanceAttribute(a.name)&&(b[a.name]=a.value)},isInstanceAttribute:function(a){return!this.blackList[a]&&"on-"!==a.slice(0,3)},blackList:{name:1,"extends":1,constructor:1,noscript:1,assetpath:1,"cache-csstext":1}};d.blackList[b]=1,a.api.declaration.attributes=d}(Polymer),function(a){var b=a.api.declaration.events,c=new PolymerExpressions,d=c.prepareBinding;c.prepareBinding=function(a,e,f){return b.prepareEventBinding(a,e,f)||d.call(c,a,e,f)};var e={syntax:c,fetchTemplate:function(){return this.querySelector("template")},templateContent:function(){var a=this.fetchTemplate();return a&&a.content},installBindingDelegate:function(a){a&&(a.bindingDelegate=this.syntax)}};a.api.declaration.mdv=e}(Polymer),function(a){function b(a){if(!Object.__proto__){var b=Object.getPrototypeOf(a);a.__proto__=b,d(b)&&(b.__proto__=Object.getPrototypeOf(b))}}var c=a.api,d=a.isBase,e=a.extend,f=window.ShadowDOMPolyfill,g={register:function(a,b){this.buildPrototype(a,b),this.registerPrototype(a,b),this.publishConstructor()},buildPrototype:function(b,c){var d=a.getRegisteredPrototype(b),e=this.generateBasePrototype(c);this.desugarBeforeChaining(d,e),this.prototype=this.chainPrototypes(d,e),this.desugarAfterChaining(b,c)},desugarBeforeChaining:function(a,b){a.element=this,this.publishAttributes(a,b),this.publishProperties(a,b),this.inferObservers(a),this.explodeObservers(a)},chainPrototypes:function(a,c){this.inheritMetaData(a,c);var d=this.chainObject(a,c);return b(d),d},inheritMetaData:function(a,b){this.inheritObject("observe",a,b),this.inheritObject("publish",a,b),this.inheritObject("reflect",a,b),this.inheritObject("_publishLC",a,b),this.inheritObject("_instanceAttributes",a,b),this.inheritObject("eventDelegates",a,b)},desugarAfterChaining:function(a,b){this.optimizePropertyMaps(this.prototype),this.createPropertyAccessors(this.prototype),this.installBindingDelegate(this.fetchTemplate()),this.installSheets(),this.resolveElementPaths(this),this.accumulateInstanceAttributes(),this.parseHostEvents(),this.addResolvePathApi(),f&&WebComponents.ShadowCSS.shimStyling(this.templateContent(),a,b),this.prototype.registerCallback&&this.prototype.registerCallback(this)},publishConstructor:function(){var a=this.getAttribute("constructor");a&&(window[a]=this.ctor)},generateBasePrototype:function(a){var b=this.findBasePrototype(a);if(!b){var b=HTMLElement.getPrototypeForTag(a);b=this.ensureBaseApi(b),h[a]=b}return b},findBasePrototype:function(a){return h[a]},ensureBaseApi:function(a){if(a.PolymerBase)return a;var b=Object.create(a);return c.publish(c.instance,b),this.mixinMethod(b,a,c.instance.mdv,"bind"),b},mixinMethod:function(a,b,c,d){var e=function(a){return b[d].apply(this,a)};a[d]=function(){return this.mixinSuper=e,c[d].apply(this,arguments)}},inheritObject:function(a,b,c){var d=b[a]||{};b[a]=this.chainObject(d,c[a])},registerPrototype:function(a,b){var c={prototype:this.prototype},d=this.findTypeExtension(b);d&&(c["extends"]=d),HTMLElement.register(a,this.prototype),this.ctor=document.registerElement(a,c)},findTypeExtension:function(a){if(a&&a.indexOf("-")<0)return a;var b=this.findBasePrototype(a);return b.element?this.findTypeExtension(b.element["extends"]):void 0}},h={};g.chainObject=Object.__proto__?function(a,b){return a&&b&&a!==b&&(a.__proto__=b),a}:function(a,b){if(a&&b&&a!==b){var c=Object.create(b);a=e(c,a)}return a},c.declaration.prototype=g}(Polymer),function(a){function b(a){return document.contains(a)?j:i}function c(){return i.length?i[0]:j[0]}function d(a){f.waitToReady=!0,Polymer.endOfMicrotask(function(){HTMLImports.whenReady(function(){f.addReadyCallback(a),f.waitToReady=!1,f.check()})})}function e(a){if(void 0===a)return void f.ready();var b=setTimeout(function(){f.ready()},a);Polymer.whenReady(function(){clearTimeout(b)})}var f={wait:function(a){a.__queue||(a.__queue={},g.push(a))},enqueue:function(a,c,d){var e=a.__queue&&!a.__queue.check;return e&&(b(a).push(a),a.__queue.check=c,a.__queue.go=d),0!==this.indexOf(a)},indexOf:function(a){var c=b(a).indexOf(a);return c>=0&&document.contains(a)&&(c+=HTMLImports.useNative||HTMLImports.ready?i.length:1e9),c},go:function(a){var b=this.remove(a);b&&(a.__queue.flushable=!0,this.addToFlushQueue(b),this.check())},remove:function(a){var c=this.indexOf(a);if(0===c)return b(a).shift()},check:function(){var a=this.nextElement();return a&&a.__queue.check.call(a),this.canReady()?(this.ready(),!0):void 0},nextElement:function(){return c()},canReady:function(){return!this.waitToReady&&this.isEmpty()},isEmpty:function(){for(var a,b=0,c=g.length;c>b&&(a=g[b]);b++)if(a.__queue&&!a.__queue.flushable)return;return!0},addToFlushQueue:function(a){h.push(a)},flush:function(){if(!this.flushing){this.flushing=!0;for(var a;h.length;)a=h.shift(),a.__queue.go.call(a),a.__queue=null;this.flushing=!1}},ready:function(){var a=CustomElements.ready;CustomElements.ready=!1,this.flush(),CustomElements.useNative||CustomElements.upgradeDocumentTree(document),CustomElements.ready=a,Polymer.flush(),requestAnimationFrame(this.flushReadyCallbacks)},addReadyCallback:function(a){a&&k.push(a)},flushReadyCallbacks:function(){if(k)for(var a;k.length;)(a=k.shift())()},waitingFor:function(){for(var a,b=[],c=0,d=g.length;d>c&&(a=g[c]);c++)a.__queue&&!a.__queue.flushable&&b.push(a);return b},waitToReady:!0},g=[],h=[],i=[],j=[],k=[];a.elements=g,a.waitingFor=f.waitingFor.bind(f),a.forceReady=e,a.queue=f,a.whenReady=a.whenPolymerReady=d}(Polymer),function(a){function b(a){return Boolean(HTMLElement.getPrototypeForTag(a))}function c(a){return a&&a.indexOf("-")>=0}var d=a.extend,e=a.api,f=a.queue,g=a.whenReady,h=a.getRegisteredPrototype,i=a.waitingForPrototype,j=d(Object.create(HTMLElement.prototype),{createdCallback:function(){this.getAttribute("name")&&this.init()},init:function(){this.name=this.getAttribute("name"),this["extends"]=this.getAttribute("extends"),f.wait(this),this.loadResources(),this.registerWhenReady()},registerWhenReady:function(){this.registered||this.waitingForPrototype(this.name)||this.waitingForQueue()||this.waitingForResources()||f.go(this)},_register:function(){c(this["extends"])&&!b(this["extends"])&&console.warn("%s is attempting to extend %s, an unregistered element or one that was not registered with Polymer.",this.name,this["extends"]),this.register(this.name,this["extends"]),this.registered=!0},waitingForPrototype:function(a){return h(a)?void 0:(i(a,this),this.handleNoScript(a),!0)},handleNoScript:function(a){this.hasAttribute("noscript")&&!this.noscript&&(this.noscript=!0,Polymer(a))},waitingForResources:function(){return this._needsResources},waitingForQueue:function(){return f.enqueue(this,this.registerWhenReady,this._register)},loadResources:function(){this._needsResources=!0,this.loadStyles(function(){this._needsResources=!1,this.registerWhenReady()}.bind(this))}});e.publish(e.declaration,j),g(function(){document.body.removeAttribute("unresolved"),document.dispatchEvent(new CustomEvent("polymer-ready",{bubbles:!0}))}),document.registerElement("polymer-element",{prototype:j})}(Polymer),function(a){function b(a,b){a?(document.head.appendChild(a),d(b)):b&&b()}function c(a,c){if(a&&a.length){for(var d,e,f=document.createDocumentFragment(),g=0,h=a.length;h>g&&(d=a[g]);g++)e=document.createElement("link"),e.rel="import",e.href=d,f.appendChild(e);b(f,c)}else c&&c()}var d=a.whenReady;a["import"]=c,a.importElements=b}(Polymer),function(){var a=document.createElement("polymer-element");a.setAttribute("name","auto-binding"),a.setAttribute("extends","template"),a.init(),Polymer("auto-binding",{createdCallback:function(){this.syntax=this.bindingDelegate=this.makeSyntax(),Polymer.whenPolymerReady(function(){this.model=this,this.setAttribute("bind",""),this.async(function(){this.marshalNodeReferences(this.parentNode),this.fire("template-bound")})}.bind(this))},makeSyntax:function(){var a=Object.create(Polymer.api.declaration.events),b=this;a.findController=function(){return b.model};var c=new PolymerExpressions,d=c.prepareBinding;return c.prepareBinding=function(b,e,f){return a.prepareEventBinding(b,e,f)||d.call(c,b,e,f)},c}})}();'use strict';var global=this;this.tr=(function(){if(global.tr){console.warn('Base was multiply initialized. First init wins.');return global.tr;}
+function exportPath(name){var parts=name.split('.');var cur=global;for(var part;parts.length&&(part=parts.shift());){if(part in cur){cur=cur[part];}else{cur=cur[part]={};}}
+return cur;};function isExported(name){var parts=name.split('.');var cur=global;for(var part;parts.length&&(part=parts.shift());){if(part in cur){cur=cur[part];}else{return false;}}
+return true;}
+function isDefined(name){var parts=name.split('.');var curObject=global;for(var i=0;i<parts.length;i++){var partName=parts[i];var nextObject=curObject[partName];if(nextObject===undefined)
+return false;curObject=nextObject;}
+return true;}
+var panicElement=undefined;var rawPanicMessages=[];function showPanicElementIfNeeded(){if(panicElement)
+return;var panicOverlay=document.createElement('div');panicOverlay.style.backgroundColor='white';panicOverlay.style.border='3px solid red';panicOverlay.style.boxSizing='border-box';panicOverlay.style.color='black';panicOverlay.style.display='-webkit-flex';panicOverlay.style.height='100%';panicOverlay.style.left=0;panicOverlay.style.padding='8px';panicOverlay.style.position='fixed';panicOverlay.style.top=0;panicOverlay.style.webkitFlexDirection='column';panicOverlay.style.width='100%';panicElement=document.createElement('div');panicElement.style.webkitFlex='1 1 auto';panicElement.style.overflow='auto';panicOverlay.appendChild(panicElement);if(!document.body){setTimeout(function(){document.body.appendChild(panicOverlay);},150);}else{document.body.appendChild(panicOverlay);}}
+function showPanic(panicTitle,panicDetails){if(tr.isHeadless){if(panicDetails instanceof Error)
+throw panicDetails;throw new Error('Panic: '+panicTitle+':\n'+panicDetails);}
+if(panicDetails instanceof Error)
+panicDetails=panicDetails.stack;showPanicElementIfNeeded();var panicMessageEl=document.createElement('div');panicMessageEl.innerHTML='<h2 id="message"></h2>'+'<pre id="details"></pre>';panicMessageEl.querySelector('#message').textContent=panicTitle;panicMessageEl.querySelector('#details').textContent=panicDetails;panicElement.appendChild(panicMessageEl);rawPanicMessages.push({title:panicTitle,details:panicDetails});}
+function hasPanic(){return rawPanicMessages.length!==0;}
+function getPanicText(){return rawPanicMessages.map(function(msg){return msg.title;}).join(', ');}
+function exportTo(namespace,fn){var obj=exportPath(namespace);var exports=fn();for(var propertyName in exports){var propertyDescriptor=Object.getOwnPropertyDescriptor(exports,propertyName);if(propertyDescriptor)
+Object.defineProperty(obj,propertyName,propertyDescriptor);}};function initialize(){if(global.isVinn){tr.isVinn=true;}else if(global.process&&global.process.versions.node){tr.isNode=true;}else{tr.isVinn=false;tr.isNode=false;tr.doc=document;tr.isMac=/Mac/.test(navigator.platform);tr.isWindows=/Win/.test(navigator.platform);tr.isChromeOS=/CrOS/.test(navigator.userAgent);tr.isLinux=/Linux/.test(navigator.userAgent);}
+tr.isHeadless=tr.isVinn||tr.isNode;}
+return{initialize:initialize,exportTo:exportTo,isExported:isExported,isDefined:isDefined,showPanic:showPanic,hasPanic:hasPanic,getPanicText:getPanicText};})();tr.initialize();'use strict';tr.exportTo('tr.b',function(){function asArray(arrayish){var values=[];for(var i=0;i<arrayish.length;i++)
+values.push(arrayish[i]);return values;}
+function compareArrays(x,y,elementCmp){var minLength=Math.min(x.length,y.length);for(var i=0;i<minLength;i++){var tmp=elementCmp(x[i],y[i]);if(tmp)
+return tmp;}
+if(x.length==y.length)
+return 0;if(x[i]===undefined)
+return-1;return 1;}
+function comparePossiblyUndefinedValues(x,y,cmp,opt_this){if(x!==undefined&&y!==undefined)
+return cmp.call(opt_this,x,y);if(x!==undefined)
+return-1;if(y!==undefined)
+return 1;return 0;}
+function compareNumericWithNaNs(x,y){if(!isNaN(x)&&!isNaN(y))
+return x-y;if(isNaN(x))
+return 1;if(isNaN(y))
+return-1;return 0;}
+function concatenateArrays(){var values=[];for(var i=0;i<arguments.length;i++){if(!(arguments[i]instanceof Array))
+throw new Error('Arguments '+i+'is not an array');values.push.apply(values,arguments[i]);}
+return values;}
+function concatenateObjects(){var result={};for(var i=0;i<arguments.length;i++){var object=arguments[i];for(var j in object){result[j]=object[j];}}
+return result;}
+function dictionaryKeys(dict){var keys=[];for(var key in dict)
+keys.push(key);return keys;}
+function dictionaryValues(dict){var values=[];for(var key in dict)
+values.push(dict[key]);return values;}
+function dictionaryLength(dict){var n=0;for(var key in dict)
+n++;return n;}
+function dictionaryContainsValue(dict,value){for(var key in dict)
+if(dict[key]===value)
+return true;return false;}
+function group(ary,fn){return ary.reduce(function(accumulator,curr){var key=fn(curr);if(key in accumulator)
+accumulator[key].push(curr);else
+accumulator[key]=[curr];return accumulator;},{});}
+function iterItems(dict,fn,opt_this){opt_this=opt_this||this;var keys=Object.keys(dict);for(var i=0;i<keys.length;i++){var key=keys[i];fn.call(opt_this,key,dict[key]);}}
+function mapItems(dict,fn,opt_this){opt_this=opt_this||this;var result={};var keys=Object.keys(dict);for(var i=0;i<keys.length;i++){var key=keys[i];result[key]=fn.call(opt_this,key,dict[key]);}
+return result;}
+function filterItems(dict,predicate,opt_this){opt_this=opt_this||this;var result={};var keys=Object.keys(dict);for(var i=0;i<keys.length;i++){var key=keys[i];var value=dict[key];if(predicate.call(opt_this,key,value))
+result[key]=value;}
+return result;}
+function iterObjectFieldsRecursively(object,func){if(!(object instanceof Object))
+return;if(object instanceof Array){for(var i=0;i<object.length;i++){func(object,i,object[i]);iterObjectFieldsRecursively(object[i],func);}
+return;}
+for(var key in object){var value=object[key];func(object,key,value);iterObjectFieldsRecursively(value,func);}}
+function invertArrayOfDicts(array,opt_dictGetter,opt_this){opt_this=opt_this||this;var result={};for(var i=0;i<array.length;i++){var item=array[i];if(item===undefined)
+continue;var dict=opt_dictGetter?opt_dictGetter.call(opt_this,item):item;if(dict===undefined)
+continue;for(var key in dict){var valueList=result[key];if(valueList===undefined)
+result[key]=valueList=new Array(array.length);valueList[i]=dict[key];}}
+return result;}
+function arrayToDict(array,valueToKeyFn,opt_this){opt_this=opt_this||this;var result={};var length=array.length;for(var i=0;i<length;i++){var value=array[i];var key=valueToKeyFn.call(opt_this,value);result[key]=value;}
+return result;}
+function identity(d){return d;}
+function findFirstIndexInArray(ary,opt_func,opt_this){var func=opt_func||identity;for(var i=0;i<ary.length;i++){if(func.call(opt_this,ary[i],i))
+return i;}
+return-1;}
+function findFirstInArray(ary,opt_func,opt_this){var i=findFirstIndexInArray(ary,opt_func,opt_func);if(i===-1)
+return undefined;return ary[i];}
+function findFirstKeyInDictMatching(dict,opt_func,opt_this){var func=opt_func||identity;for(var key in dict){if(func.call(opt_this,key,dict[key]))
+return key;}
+return undefined;}
+return{asArray:asArray,concatenateArrays:concatenateArrays,concatenateObjects:concatenateObjects,compareArrays:compareArrays,comparePossiblyUndefinedValues:comparePossiblyUndefinedValues,compareNumericWithNaNs:compareNumericWithNaNs,dictionaryLength:dictionaryLength,dictionaryKeys:dictionaryKeys,dictionaryValues:dictionaryValues,dictionaryContainsValue:dictionaryContainsValue,group:group,iterItems:iterItems,mapItems:mapItems,filterItems:filterItems,iterObjectFieldsRecursively:iterObjectFieldsRecursively,invertArrayOfDicts:invertArrayOfDicts,arrayToDict:arrayToDict,identity:identity,findFirstIndexInArray:findFirstIndexInArray,findFirstInArray:findFirstInArray,findFirstKeyInDictMatching:findFirstKeyInDictMatching};});'use strict';tr.exportTo('tr.b',function(){function EventTarget(){}
+EventTarget.decorate=function(target){for(var k in EventTarget.prototype){if(k=='decorate')
+continue;var v=EventTarget.prototype[k];if(typeof v!=='function')
+continue;target[k]=v;}};EventTarget.prototype={addEventListener:function(type,handler){if(!this.listeners_)
+this.listeners_=Object.create(null);if(!(type in this.listeners_)){this.listeners_[type]=[handler];}else{var handlers=this.listeners_[type];if(handlers.indexOf(handler)<0)
+handlers.push(handler);}},removeEventListener:function(type,handler){if(!this.listeners_)
+return;if(type in this.listeners_){var handlers=this.listeners_[type];var index=handlers.indexOf(handler);if(index>=0){if(handlers.length==1)
+delete this.listeners_[type];else
+handlers.splice(index,1);}}},dispatchEvent:function(event){if(!this.listeners_)
+return true;var self=this;event.__defineGetter__('target',function(){return self;});var realPreventDefault=event.preventDefault;event.preventDefault=function(){realPreventDefault.call(this);this.rawReturnValue=false;};var type=event.type;var prevented=0;if(type in this.listeners_){var handlers=this.listeners_[type].concat();for(var i=0,handler;handler=handlers[i];i++){if(handler.handleEvent)
+prevented|=handler.handleEvent.call(handler,event)===false;else
+prevented|=handler.call(this,event)===false;}}
+return!prevented&&event.rawReturnValue;},hasEventListener:function(type){return this.listeners_[type]!==undefined;}};var EventTargetHelper={decorate:function(target){for(var k in EventTargetHelper){if(k=='decorate')
+continue;var v=EventTargetHelper[k];if(typeof v!=='function')
+continue;target[k]=v;}
+target.listenerCounts_={};},addEventListener:function(type,listener,useCapture){this.__proto__.addEventListener.call(this,type,listener,useCapture);if(this.listenerCounts_[type]===undefined)
+this.listenerCounts_[type]=0;this.listenerCounts_[type]++;},removeEventListener:function(type,listener,useCapture){this.__proto__.removeEventListener.call(this,type,listener,useCapture);this.listenerCounts_[type]--;},hasEventListener:function(type){return this.listenerCounts_[type]>0;}};return{EventTarget:EventTarget,EventTargetHelper:EventTargetHelper};});'use strict';tr.exportTo('tr.b',function(){function RegisteredTypeInfo(constructor,metadata){this.constructor=constructor;this.metadata=metadata;};var BASIC_REGISTRY_MODE='BASIC_REGISTRY_MODE';var TYPE_BASED_REGISTRY_MODE='TYPE_BASED_REGISTRY_MODE';var ALL_MODES={BASIC_REGISTRY_MODE:true,TYPE_BASED_REGISTRY_MODE:true};function ExtensionRegistryOptions(mode){if(mode===undefined)
+throw new Error('Mode is required');if(!ALL_MODES[mode])
+throw new Error('Not a mode.');this.mode_=mode;this.defaultMetadata_={};this.defaultConstructor_=undefined;this.mandatoryBaseClass_=undefined;this.defaultTypeInfo_=undefined;this.frozen_=false;}
+ExtensionRegistryOptions.prototype={freeze:function(){if(this.frozen_)
+throw new Error('Frozen');this.frozen_=true;},get mode(){return this.mode_;},get defaultMetadata(){return this.defaultMetadata_;},set defaultMetadata(defaultMetadata){if(this.frozen_)
+throw new Error('Frozen');this.defaultMetadata_=defaultMetadata;this.defaultTypeInfo_=undefined;},get defaultConstructor(){return this.defaultConstructor_;},set defaultConstructor(defaultConstructor){if(this.frozen_)
+throw new Error('Frozen');this.defaultConstructor_=defaultConstructor;this.defaultTypeInfo_=undefined;},get defaultTypeInfo(){if(this.defaultTypeInfo_===undefined&&this.defaultConstructor_){this.defaultTypeInfo_=new RegisteredTypeInfo(this.defaultConstructor,this.defaultMetadata);}
+return this.defaultTypeInfo_;},validateConstructor:function(constructor){if(!this.mandatoryBaseClass)
+return;var curProto=constructor.prototype.__proto__;var ok=false;while(curProto){if(curProto===this.mandatoryBaseClass.prototype){ok=true;break;}
+curProto=curProto.__proto__;}
+if(!ok)
+throw new Error(constructor+'must be subclass of '+registry);}};return{BASIC_REGISTRY_MODE:BASIC_REGISTRY_MODE,TYPE_BASED_REGISTRY_MODE:TYPE_BASED_REGISTRY_MODE,ExtensionRegistryOptions:ExtensionRegistryOptions,RegisteredTypeInfo:RegisteredTypeInfo};});'use strict';tr.exportTo('tr.b',function(){var Event;if(tr.isHeadless){function HeadlessEvent(type,opt_bubbles,opt_preventable){this.type=type;this.bubbles=(opt_bubbles!==undefined?!!opt_bubbles:false);this.cancelable=(opt_preventable!==undefined?!!opt_preventable:false);this.defaultPrevented=false;this.cancelBubble=false;};HeadlessEvent.prototype={preventDefault:function(){this.defaultPrevented=true;},stopPropagation:function(){this.cancelBubble=true;}};Event=HeadlessEvent;}else{function TrEvent(type,opt_bubbles,opt_preventable){var e=tr.doc.createEvent('Event');e.initEvent(type,!!opt_bubbles,!!opt_preventable);e.__proto__=global.Event.prototype;return e;};TrEvent.prototype={__proto__:global.Event.prototype};Event=TrEvent;}
+function dispatchSimpleEvent(target,type,opt_bubbles,opt_cancelable){var e=new tr.b.Event(type,opt_bubbles,opt_cancelable);return target.dispatchEvent(e);}
+return{Event:Event,dispatchSimpleEvent:dispatchSimpleEvent};});'use strict';tr.exportTo('tr.b',function(){var RegisteredTypeInfo=tr.b.RegisteredTypeInfo;var ExtensionRegistryOptions=tr.b.ExtensionRegistryOptions;function decorateBasicExtensionRegistry(registry,extensionRegistryOptions){var savedStateStack=[];registry.registeredTypeInfos_=[];registry.register=function(constructor,opt_metadata){if(registry.findIndexOfRegisteredConstructor(constructor)!==undefined)
+throw new Error('Handler already registered for '+constructor);extensionRegistryOptions.validateConstructor(constructor);var metadata={};for(var k in extensionRegistryOptions.defaultMetadata)
+metadata[k]=extensionRegistryOptions.defaultMetadata[k];if(opt_metadata){for(var k in opt_metadata)
+metadata[k]=opt_metadata[k];}
+var typeInfo=new RegisteredTypeInfo(constructor,metadata);var e=new tr.b.Event('will-register');e.typeInfo=typeInfo;registry.dispatchEvent(e);registry.registeredTypeInfos_.push(typeInfo);e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.pushCleanStateBeforeTest=function(){savedStateStack.push(registry.registeredTypeInfos_);registry.registeredTypeInfos_=[];var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.popCleanStateAfterTest=function(){registry.registeredTypeInfos_=savedStateStack[0];savedStateStack.splice(0,1);var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.findIndexOfRegisteredConstructor=function(constructor){for(var i=0;i<registry.registeredTypeInfos_.length;i++)
+if(registry.registeredTypeInfos_[i].constructor==constructor)
+return i;return undefined;};registry.unregister=function(constructor){var foundIndex=registry.findIndexOfRegisteredConstructor(constructor);if(foundIndex===undefined)
+throw new Error(constructor+' not registered');registry.registeredTypeInfos_.splice(foundIndex,1);var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.getAllRegisteredTypeInfos=function(){return registry.registeredTypeInfos_;};registry.findTypeInfo=function(constructor){var foundIndex=this.findIndexOfRegisteredConstructor(constructor);if(foundIndex!==undefined)
+return this.registeredTypeInfos_[foundIndex];return undefined;};registry.findTypeInfoMatching=function(predicate,opt_this){opt_this=opt_this?opt_this:undefined;for(var i=0;i<registry.registeredTypeInfos_.length;++i){var typeInfo=registry.registeredTypeInfos_[i];if(predicate.call(opt_this,typeInfo))
+return typeInfo;}
+return extensionRegistryOptions.defaultTypeInfo;};}
+return{_decorateBasicExtensionRegistry:decorateBasicExtensionRegistry};});'use strict';tr.exportTo('tr.b',function(){var categoryPartsFor={};function getCategoryParts(category){var parts=categoryPartsFor[category];if(parts!==undefined)
+return parts;parts=category.split(',');categoryPartsFor[category]=parts;return parts;}
+return{getCategoryParts:getCategoryParts};});'use strict';tr.exportTo('tr.b',function(){var getCategoryParts=tr.b.getCategoryParts;var RegisteredTypeInfo=tr.b.RegisteredTypeInfo;var ExtensionRegistryOptions=tr.b.ExtensionRegistryOptions;function decorateTypeBasedExtensionRegistry(registry,extensionRegistryOptions){var savedStateStack=[];registry.registeredTypeInfos_=[];registry.categoryPartToTypeInfoMap_={};registry.typeNameToTypeInfoMap_={};registry.register=function(constructor,metadata){extensionRegistryOptions.validateConstructor(constructor);var typeInfo=new RegisteredTypeInfo(constructor,metadata||extensionRegistryOptions.defaultMetadata);typeInfo.typeNames=[];typeInfo.categoryParts=[];if(metadata&&metadata.typeName)
+typeInfo.typeNames.push(metadata.typeName);if(metadata&&metadata.typeNames){typeInfo.typeNames.push.apply(typeInfo.typeNames,metadata.typeNames);}
+if(metadata&&metadata.categoryParts){typeInfo.categoryParts.push.apply(typeInfo.categoryParts,metadata.categoryParts);}
+if(typeInfo.typeNames.length===0&&typeInfo.categoryParts.length===0)
+throw new Error('typeName or typeNames must be provided');typeInfo.typeNames.forEach(function(typeName){if(registry.typeNameToTypeInfoMap_[typeName])
+throw new Error('typeName '+typeName+' already registered');});typeInfo.categoryParts.forEach(function(categoryPart){if(registry.categoryPartToTypeInfoMap_[categoryPart]){throw new Error('categoryPart '+categoryPart+' already registered');}});var e=new tr.b.Event('will-register');e.typeInfo=typeInfo;registry.dispatchEvent(e);typeInfo.typeNames.forEach(function(typeName){registry.typeNameToTypeInfoMap_[typeName]=typeInfo;});typeInfo.categoryParts.forEach(function(categoryPart){registry.categoryPartToTypeInfoMap_[categoryPart]=typeInfo;});registry.registeredTypeInfos_.push(typeInfo);var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.pushCleanStateBeforeTest=function(){savedStateStack.push({registeredTypeInfos:registry.registeredTypeInfos_,typeNameToTypeInfoMap:registry.typeNameToTypeInfoMap_,categoryPartToTypeInfoMap:registry.categoryPartToTypeInfoMap_});registry.registeredTypeInfos_=[];registry.typeNameToTypeInfoMap_={};registry.categoryPartToTypeInfoMap_={};var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.popCleanStateAfterTest=function(){var state=savedStateStack[0];savedStateStack.splice(0,1);registry.registeredTypeInfos_=state.registeredTypeInfos;registry.typeNameToTypeInfoMap_=state.typeNameToTypeInfoMap;registry.categoryPartToTypeInfoMap_=state.categoryPartToTypeInfoMap;var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.unregister=function(constructor){var typeInfoIndex=-1;for(var i=0;i<registry.registeredTypeInfos_.length;i++){if(registry.registeredTypeInfos_[i].constructor==constructor){typeInfoIndex=i;break;}}
+if(typeInfoIndex===-1)
+throw new Error(constructor+' not registered');var typeInfo=registry.registeredTypeInfos_[typeInfoIndex];registry.registeredTypeInfos_.splice(typeInfoIndex,1);typeInfo.typeNames.forEach(function(typeName){delete registry.typeNameToTypeInfoMap_[typeName];});typeInfo.categoryParts.forEach(function(categoryPart){delete registry.categoryPartToTypeInfoMap_[categoryPart];});var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.getTypeInfo=function(category,typeName){if(category){var categoryParts=getCategoryParts(category);for(var i=0;i<categoryParts.length;i++){var categoryPart=categoryParts[i];if(registry.categoryPartToTypeInfoMap_[categoryPart])
+return registry.categoryPartToTypeInfoMap_[categoryPart];}}
+if(registry.typeNameToTypeInfoMap_[typeName])
+return registry.typeNameToTypeInfoMap_[typeName];return extensionRegistryOptions.defaultTypeInfo;};registry.getConstructor=function(category,typeName){var typeInfo=registry.getTypeInfo(category,typeName);if(typeInfo)
+return typeInfo.constructor;return undefined;};}
+return{_decorateTypeBasedExtensionRegistry:decorateTypeBasedExtensionRegistry};});'use strict';tr.exportTo('tr.b',function(){function decorateExtensionRegistry(registry,registryOptions){if(registry.register)
+throw new Error('Already has registry');registryOptions.freeze();if(registryOptions.mode==tr.b.BASIC_REGISTRY_MODE){tr.b._decorateBasicExtensionRegistry(registry,registryOptions);}else if(registryOptions.mode==tr.b.TYPE_BASED_REGISTRY_MODE){tr.b._decorateTypeBasedExtensionRegistry(registry,registryOptions);}else{throw new Error('Unrecognized mode');}
+if(registry.addEventListener===undefined)
+tr.b.EventTarget.decorate(registry);}
+return{decorateExtensionRegistry:decorateExtensionRegistry};});'use strict';tr.exportTo('tr.importer',function(){function Importer(){}
+Importer.prototype={__proto__:Object.prototype,isTraceDataContainer:function(){return false;},extractSubtraces:function(){return[];},importEvents:function(){},importSampleData:function(){},finalizeImport:function(){},joinRefs:function(){}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Importer;tr.b.decorateExtensionRegistry(Importer,options);Importer.findImporterFor=function(eventData){var typeInfo=Importer.findTypeInfoMatching(function(ti){return ti.constructor.canImport(eventData);});if(typeInfo)
+return typeInfo.constructor;return undefined;};return{Importer:Importer};});'use strict';tr.exportTo('tr.e.importer.gcloud_trace',function(){function GcloudTraceImporter(model,eventData){this.importPriority=2;this.eventData_=eventData;}
+GcloudTraceImporter.canImport=function(eventData){if(typeof(eventData)!=='string'&&!(eventData instanceof String))
+return false;var normalizedEventData=eventData.slice(0,20).replace(/\s/g,'');if(normalizedEventData.length<14)
+return false;return normalizedEventData.slice(0,14)=='{"projectId":"';};GcloudTraceImporter.prototype={__proto__:tr.importer.Importer.prototype,extractSubtraces:function(){var traceEvents=this.createEventsForTrace();return traceEvents?[traceEvents]:[];},createEventsForTrace:function(){var events=[];var trace=JSON.parse(this.eventData_);var spanLength=trace.spans.length;for(var i=0;i<spanLength;i++){events.push(this.createEventForSpan(trace.traceId,trace.spans[i]));}
+return{'traceEvents':events};},createEventForSpan:function(traceId,span){var newArgs={};if(span.labels){newArgs=JSON.parse(JSON.stringify(span.labels));}
+newArgs['Span ID']=span.spanId;newArgs['Start Time']=span.startTime;newArgs['End Time']=span.endTime;if(span.parentSpanId){newArgs['Parent Span ID']=span.parentSpanId;}
+return{name:span.name,args:newArgs,pid:traceId,ts:Date.parse(span.startTime)*1000,dur:(Date.parse(span.endTime)-Date.parse(span.startTime))*1000,cat:'tracespan',tid:traceId,ph:'X'};}};tr.importer.Importer.register(GcloudTraceImporter);return{GcloudTraceImporter:GcloudTraceImporter};});'use strict';tr.exportTo('tr.b',function(){function max(a,b){if(a===undefined)
+return b;if(b===undefined)
+return a;return Math.max(a,b);}
+function IntervalTree(beginPositionCb,endPositionCb){this.beginPositionCb_=beginPositionCb;this.endPositionCb_=endPositionCb;this.root_=undefined;this.size_=0;}
+IntervalTree.prototype={insert:function(datum){var startPosition=this.beginPositionCb_(datum);var endPosition=this.endPositionCb_(datum);var node=new IntervalTreeNode(datum,startPosition,endPosition);this.size_++;this.root_=this.insertNode_(this.root_,node);this.root_.colour=Colour.BLACK;return datum;},insertNode_:function(root,node){if(root===undefined)
+return node;if(root.leftNode&&root.leftNode.isRed&&root.rightNode&&root.rightNode.isRed)
+this.flipNodeColour_(root);if(node.key<root.key)
+root.leftNode=this.insertNode_(root.leftNode,node);else if(node.key===root.key)
+root.merge(node);else
+root.rightNode=this.insertNode_(root.rightNode,node);if(root.rightNode&&root.rightNode.isRed&&(root.leftNode===undefined||!root.leftNode.isRed))
+root=this.rotateLeft_(root);if(root.leftNode&&root.leftNode.isRed&&root.leftNode.leftNode&&root.leftNode.leftNode.isRed)
+root=this.rotateRight_(root);return root;},rotateRight_:function(node){var sibling=node.leftNode;node.leftNode=sibling.rightNode;sibling.rightNode=node;sibling.colour=node.colour;node.colour=Colour.RED;return sibling;},rotateLeft_:function(node){var sibling=node.rightNode;node.rightNode=sibling.leftNode;sibling.leftNode=node;sibling.colour=node.colour;node.colour=Colour.RED;return sibling;},flipNodeColour_:function(node){node.colour=this.flipColour_(node.colour);node.leftNode.colour=this.flipColour_(node.leftNode.colour);node.rightNode.colour=this.flipColour_(node.rightNode.colour);},flipColour_:function(colour){return colour===Colour.RED?Colour.BLACK:Colour.RED;},updateHighValues:function(){this.updateHighValues_(this.root_);},updateHighValues_:function(node){if(node===undefined)
+return undefined;node.maxHighLeft=this.updateHighValues_(node.leftNode);node.maxHighRight=this.updateHighValues_(node.rightNode);return max(max(node.maxHighLeft,node.highValue),node.maxHighRight);},validateFindArguments_:function(queryLow,queryHigh){if(queryLow===undefined||queryHigh===undefined)
+throw new Error('queryLow and queryHigh must be defined');if((typeof queryLow!=='number')||(typeof queryHigh!=='number'))
+throw new Error('queryLow and queryHigh must be numbers');},findIntersection:function(queryLow,queryHigh){this.validateFindArguments_(queryLow,queryHigh);if(this.root_===undefined)
+return[];var ret=[];this.root_.appendIntersectionsInto_(ret,queryLow,queryHigh);return ret;},get size(){return this.size_;},get root(){return this.root_;},dump_:function(){if(this.root_===undefined)
+return[];return this.root_.dump();}};var Colour={RED:'red',BLACK:'black'};function IntervalTreeNode(datum,lowValue,highValue){this.lowValue_=lowValue;this.data_=[{datum:datum,high:highValue,low:lowValue}];this.colour_=Colour.RED;this.parentNode_=undefined;this.leftNode_=undefined;this.rightNode_=undefined;this.maxHighLeft_=undefined;this.maxHighRight_=undefined;}
+IntervalTreeNode.prototype={appendIntersectionsInto_:function(ret,queryLow,queryHigh){if(this.lowValue_>=queryHigh){if(!this.leftNode_)
+return;return this.leftNode_.appendIntersectionsInto_(ret,queryLow,queryHigh);}
+if(this.maxHighLeft_>queryLow){this.leftNode_.appendIntersectionsInto_(ret,queryLow,queryHigh);}
+if(this.highValue>queryLow){for(var i=(this.data.length-1);i>=0;--i){if(this.data[i].high<queryLow)
+break;ret.push(this.data[i].datum);}}
+if(this.rightNode_){this.rightNode_.appendIntersectionsInto_(ret,queryLow,queryHigh);}},get colour(){return this.colour_;},set colour(colour){this.colour_=colour;},get key(){return this.lowValue_;},get lowValue(){return this.lowValue_;},get highValue(){return this.data_[this.data_.length-1].high;},set leftNode(left){this.leftNode_=left;},get leftNode(){return this.leftNode_;},get hasLeftNode(){return this.leftNode_!==undefined;},set rightNode(right){this.rightNode_=right;},get rightNode(){return this.rightNode_;},get hasRightNode(){return this.rightNode_!==undefined;},set parentNode(parent){this.parentNode_=parent;},get parentNode(){return this.parentNode_;},get isRootNode(){return this.parentNode_===undefined;},set maxHighLeft(high){this.maxHighLeft_=high;},get maxHighLeft(){return this.maxHighLeft_;},set maxHighRight(high){this.maxHighRight_=high;},get maxHighRight(){return this.maxHighRight_;},get data(){return this.data_;},get isRed(){return this.colour_===Colour.RED;},merge:function(node){for(var i=0;i<node.data.length;i++)
+this.data_.push(node.data[i]);this.data_.sort(function(a,b){return a.high-b.high;});},dump:function(){var ret={};if(this.leftNode_)
+ret['left']=this.leftNode_.dump();ret['data']=this.data_.map(function(d){return[d.low,d.high];});if(this.rightNode_)
+ret['right']=this.rightNode_.dump();return ret;}};return{IntervalTree:IntervalTree};});'use strict';tr.exportTo('tr.b',function(){function Range(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;};Range.prototype={__proto__:Object.prototype,reset:function(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;},get isEmpty(){return this.isEmpty_;},addRange:function(range){if(range.isEmpty)
+return;this.addValue(range.min);this.addValue(range.max);},addValue:function(value){if(this.isEmpty_){this.max_=value;this.min_=value;this.isEmpty_=false;return;}
+this.max_=Math.max(this.max_,value);this.min_=Math.min(this.min_,value);},set min(min){this.isEmpty_=false;this.min_=min;},get min(){if(this.isEmpty_)
+return undefined;return this.min_;},get max(){if(this.isEmpty_)
+return undefined;return this.max_;},set max(max){this.isEmpty_=false;this.max_=max;},get range(){if(this.isEmpty_)
+return undefined;return this.max_-this.min_;},get center(){return(this.min_+this.max_)*0.5;},get duration(){if(this.isEmpty_)
+return 0;return this.max_-this.min_;},equals:function(that){if(this.isEmpty&&that.isEmpty)
+return true;if(this.isEmpty!=that.isEmpty)
+return false;return this.min===that.min&&this.max===that.max;},containsRange:function(range){if(this.isEmpty||range.isEmpty)
+return false;return this.findIntersection(range).duration==range.duration;},containsExplicitRange:function(min,max){return this.containsRange(Range.fromExplicitRange(min,max));},intersectsRange:function(range){if(this.isEmpty||range.isEmpty)
+return false;return!this.findIntersection(range).isEmpty;},intersectsExplicitRange:function(min,max){return this.intersectsRange(Range.fromExplicitRange(min,max));},findIntersection:function(range){if(this.isEmpty||range.isEmpty)
+return new Range();var min=Math.max(this.min,range.min);var max=Math.min(this.max,range.max);if(max<min)
+return new Range();return Range.fromExplicitRange(min,max);},toJSON:function(){if(this.isEmpty_)
+return{isEmpty:true};return{isEmpty:false,max:this.max,min:this.min};},filterArray:function(array,opt_keyFunc,opt_this){if(this.isEmpty_)
+return[];function binSearch(test){var i0=0;var i1=array.length;while(i0<i1-1){var i=Math.trunc((i0+i1)/2);if(test(i))
+i1=i;else
+i0=i;}
+return i1;}
+var keyFunc=opt_keyFunc||tr.b.identity;function getValue(index){return keyFunc.call(opt_this,array[index]);}
+var first=binSearch(function(i){return this.min_===undefined||this.min_<=getValue(i);}.bind(this));var last=binSearch(function(i){return this.max_!==undefined&&this.max_<getValue(i);}.bind(this));return array.slice(first,last);}};Range.fromDict=function(d){if(d.isEmpty===true){return new Range();}else if(d.isEmpty===false){var range=new Range();range.min=d.min;range.max=d.max;return range;}else{throw new Error('Not a range');}};Range.fromExplicitRange=function(min,max){var range=new Range();range.min=min;range.max=max;return range;};Range.compareByMinTimes=function(a,b){if(!a.isEmpty&&!b.isEmpty)
+return a.min_-b.min_;if(a.isEmpty&&!b.isEmpty)
+return-1;if(!a.isEmpty&&b.isEmpty)
+return 1;return 0;};return{Range:Range};});'use strict';tr.exportTo('tr.b',function(){function addSingletonGetter(ctor){ctor.getInstance=function(){return ctor.instance_||(ctor.instance_=new ctor());};}
+function deepCopy(value){if(!(value instanceof Object)){if(value===undefined||value===null)
+return value;if(typeof value=='string')
+return value.substring();if(typeof value=='boolean')
+return value;if(typeof value=='number')
+return value;throw new Error('Unrecognized: '+typeof value);}
+var object=value;if(object instanceof Array){var res=new Array(object.length);for(var i=0;i<object.length;i++)
+res[i]=deepCopy(object[i]);return res;}
+if(object.__proto__!=Object.prototype)
+throw new Error('Can only clone simple types');var res={};for(var key in object){res[key]=deepCopy(object[key]);}
+return res;}
+function normalizeException(e){if(e===undefined||e===null){return{typeName:'UndefinedError',message:'Unknown: null or undefined exception',stack:'Unknown'};}
+if(typeof(e)=='string'){return{typeName:'StringError',message:e,stack:[e]};}
+var typeName;if(e.name){typeName=e.name;}else if(e.constructor){if(e.constructor.name){typeName=e.constructor.name;}else{typeName='AnonymousError';}}else{typeName='ErrorWithNoConstructor';}
+var msg=e.message?e.message:'Unknown';return{typeName:typeName,message:msg,stack:e.stack?e.stack:[msg]};}
+function stackTraceAsString(){return new Error().stack+'';}
+function stackTrace(){var stack=stackTraceAsString();stack=stack.split('\n');return stack.slice(2);}
+function getUsingPath(path,from_dict){var parts=path.split('.');var cur=from_dict;for(var part;parts.length&&(part=parts.shift());){if(!parts.length){return cur[part];}else if(part in cur){cur=cur[part];}else{return undefined;}}
+return undefined;}
+return{addSingletonGetter:addSingletonGetter,deepCopy:deepCopy,normalizeException:normalizeException,stackTrace:stackTrace,stackTraceAsString:stackTraceAsString,getUsingPath:getUsingPath};});'use strict';tr.exportTo('tr.b',function(){var recordRAFStacks=false;var pendingPreAFs=[];var pendingRAFs=[];var pendingIdleCallbacks=[];var currentRAFDispatchList=undefined;var rafScheduled=false;function scheduleRAF(){if(rafScheduled)
+return;rafScheduled=true;if(tr.isHeadless){Promise.resolve().then(function(){processRequests(0);},function(e){console.log(e.stack);throw e;});}else{if(window.requestAnimationFrame){window.requestAnimationFrame(processRequests);}else{var delta=Date.now()-window.performance.now();window.webkitRequestAnimationFrame(function(domTimeStamp){processRequests(domTimeStamp-delta);});}}}
+function onAnimationFrameError(e,opt_stack){console.log(e.stack);if(tr.isHeadless)
+throw e;if(opt_stack)
+console.log(opt_stack);if(e.message)
+console.error(e.message,e.stack);else
+console.error(e);}
+function runTask(task,frameBeginTime){try{task.callback.call(task.context,frameBeginTime);}catch(e){tr.b.onAnimationFrameError(e,task.stack);}}
+function processRequests(frameBeginTime){var rafCompletionDeadline=frameBeginTime+10;rafScheduled=false;var currentPreAFs=pendingPreAFs;currentRAFDispatchList=pendingRAFs;pendingPreAFs=[];pendingRAFs=[];var hasRAFTasks=currentPreAFs.length||currentRAFDispatchList.length;for(var i=0;i<currentPreAFs.length;i++)
+runTask(currentPreAFs[i],frameBeginTime);while(currentRAFDispatchList.length>0)
+runTask(currentRAFDispatchList.shift(),frameBeginTime);currentRAFDispatchList=undefined;if(!hasRAFTasks){while(pendingIdleCallbacks.length>0){runTask(pendingIdleCallbacks.shift());if(tr.isHeadless||window.performance.now()>=rafCompletionDeadline)
+break;}}
+if(pendingIdleCallbacks.length>0)
+scheduleRAF();}
+function getStack_(){if(!recordRAFStacks)
+return'';var stackLines=tr.b.stackTrace();stackLines.shift();return stackLines.join('\n');}
+function requestPreAnimationFrame(callback,opt_this){pendingPreAFs.push({callback:callback,context:opt_this||window,stack:getStack_()});scheduleRAF();}
+function requestAnimationFrameInThisFrameIfPossible(callback,opt_this){if(!currentRAFDispatchList){requestAnimationFrame(callback,opt_this);return;}
+currentRAFDispatchList.push({callback:callback,context:opt_this||window,stack:getStack_()});return;}
+function requestAnimationFrame(callback,opt_this){pendingRAFs.push({callback:callback,context:opt_this||window,stack:getStack_()});scheduleRAF();}
+function requestIdleCallback(callback,opt_this){pendingIdleCallbacks.push({callback:callback,context:opt_this||window,stack:getStack_()});scheduleRAF();}
+function forcePendingRAFTasksToRun(frameBeginTime){if(!rafScheduled)
+return;processRequests(frameBeginTime);}
+return{onAnimationFrameError:onAnimationFrameError,requestPreAnimationFrame:requestPreAnimationFrame,requestAnimationFrame:requestAnimationFrame,requestAnimationFrameInThisFrameIfPossible:requestAnimationFrameInThisFrameIfPossible,requestIdleCallback:requestIdleCallback,forcePendingRAFTasksToRun:forcePendingRAFTasksToRun};});'use strict';tr.exportTo('tr.b',function(){function Task(runCb,thisArg){if(runCb!==undefined&&thisArg===undefined)
+throw new Error('Almost certainly, you meant to pass a thisArg.');this.runCb_=runCb;this.thisArg_=thisArg;this.afterTask_=undefined;this.subTasks_=[];}
+Task.prototype={subTask:function(cb,thisArg){if(cb instanceof Task)
+this.subTasks_.push(cb);else
+this.subTasks_.push(new Task(cb,thisArg));return this.subTasks_[this.subTasks_.length-1];},run:function(){if(this.runCb_!==undefined)
+this.runCb_.call(this.thisArg_,this);var subTasks=this.subTasks_;this.subTasks_=undefined;if(!subTasks.length)
+return this.afterTask_;for(var i=1;i<subTasks.length;i++)
+subTasks[i-1].afterTask_=subTasks[i];subTasks[subTasks.length-1].afterTask_=this.afterTask_;return subTasks[0];},after:function(cb,thisArg){if(this.afterTask_)
+throw new Error('Has an after task already');if(cb instanceof Task)
+this.afterTask_=cb;else
+this.afterTask_=new Task(cb,thisArg);return this.afterTask_;},enqueue:function(cb,thisArg){var lastTask=this;while(lastTask.afterTask_)
+lastTask=lastTask.afterTask_;return lastTask.after(cb,thisArg);}};Task.RunSynchronously=function(task){var curTask=task;while(curTask)
+curTask=curTask.run();}
+Task.RunWhenIdle=function(task){return new Promise(function(resolve,reject){var curTask=task;function runAnother(){try{curTask=curTask.run();}catch(e){reject(e);console.error(e.stack);return;}
+if(curTask){tr.b.requestIdleCallback(runAnother);return;}
+resolve();}
+tr.b.requestIdleCallback(runAnother);});}
+return{Task:Task};});'use strict';tr.exportTo('tr.b',function(){function _iterateElementDeeplyImpl(element,cb,thisArg,includeElement){if(includeElement){if(cb.call(thisArg,element))
+return true;}
+if(element.shadowRoot){if(_iterateElementDeeplyImpl(element.shadowRoot,cb,thisArg,false))
+return true;}
+for(var i=0;i<element.children.length;i++){if(_iterateElementDeeplyImpl(element.children[i],cb,thisArg,true))
+return true;}}
+function iterateElementDeeply(element,cb,thisArg){_iterateElementDeeplyImpl(element,cb,thisArg,false);}
+function findDeepElementMatchingPredicate(element,predicate){var foundElement=undefined;function matches(element){var match=predicate(element);if(!match)
+return false;foundElement=element;return true;}
+iterateElementDeeply(element,matches);return foundElement;}
+function findDeepElementsMatchingPredicate(element,predicate){var foundElements=[];function matches(element){var match=predicate(element);if(match){foundElements.push(element);}
+return false;}
+iterateElementDeeply(element,matches);return foundElements;}
+function findDeepElementMatching(element,selector){return findDeepElementMatchingPredicate(element,function(element){return element.matches(selector);});}
+function findDeepElementsMatching(element,selector){return findDeepElementsMatchingPredicate(element,function(element){return element.matches(selector);});}
+function findDeepElementWithTextContent(element,re){return findDeepElementMatchingPredicate(element,function(element){if(element.children.length!==0)
+return false;return re.test(element.textContent);});}
+return{iterateElementDeeply:iterateElementDeeply,findDeepElementMatching:findDeepElementMatching,findDeepElementsMatching:findDeepElementsMatching,findDeepElementMatchingPredicate:findDeepElementMatchingPredicate,findDeepElementsMatchingPredicate:findDeepElementsMatchingPredicate,findDeepElementWithTextContent:findDeepElementWithTextContent};});'use strict';tr.exportTo('tr.b.u',function(){var msDisplayMode={scale:1e-3,suffix:'ms',roundedLess:function(a,b){return Math.round(a*1000)<Math.round(b*1000);},format:function(ts){return new Number(ts).toLocaleString(undefined,{minimumFractionDigits:3})+' ms';}};var nsDisplayMode={scale:1e-9,suffix:'ns',roundedLess:function(a,b){return Math.round(a*1000000)<Math.round(b*1000000);},format:function(ts){return new Number(ts*1000000).toLocaleString(undefined,{maximumFractionDigits:0})+' ns';}};var TimeDisplayModes={ns:nsDisplayMode,ms:msDisplayMode};return{TimeDisplayModes:TimeDisplayModes};});'use strict';tr.exportTo('tr.b.u',function(){var TimeDisplayModes=tr.b.u.TimeDisplayModes;function max(a,b){if(a===undefined)
+return b;if(b===undefined)
+return a;return a.scale>b.scale?a:b;}
+var Units={reset:function(){this.currentTimeDisplayMode=TimeDisplayModes.ms;},timestampFromUs:function(us){return us/1000;},maybeTimestampFromUs:function(us){return us===undefined?undefined:us/1000;},get currentTimeDisplayMode(){return this.currentTimeDisplayMode_;},set currentTimeDisplayMode(value){if(this.currentTimeDisplayMode_==value)
+return;this.currentTimeDisplayMode_=value;this.dispatchEvent(new tr.b.Event('display-mode-changed'));},didPreferredTimeDisplayUnitChange:function(){var largest=undefined;var els=tr.b.findDeepElementsMatching(document.body,'tr-ui-u-preferred-display-unit');els.forEach(function(el){largest=max(largest,el.preferredTimeDisplayMode);});this.currentDisplayUnit=largest===undefined?TimeDisplayModes.ms:largest;},unitsByJSONName:{},fromJSON:function(object){var u=this.unitsByJSONName[object];if(u){return u;}
+throw new Error('Unrecognized unit');}};tr.b.EventTarget.decorate(Units);Units.reset();Units.timeDurationInMs={asJSON:function(){return'ms';},format:function(value){return Units.currentTimeDisplayMode_.format(value);}};Units.unitsByJSONName['ms']=Units.timeDurationInMs;Units.timeStampInMs={asJSON:function(){return'tsMs';},format:function(value){return Units.currentTimeDisplayMode_.format(value);}};Units.unitsByJSONName['tsMs']=Units.timeStampInMs;Units.normalizedPercentage={asJSON:function(){return'n%';},format:function(value){var tmp=new Number(Math.round(value*100000)/1000);return tmp.toLocaleString(undefined,{minimumFractionDigits:3})+'%';}};Units.unitsByJSONName['n%']=Units.normalizedPercentage;var SIZE_UNIT_PREFIXES=['','Ki','Mi','Gi','Ti'];Units.sizeInBytes={asJSON:function(){return'sizeInBytes';},format:function(value){var signPrefix='';if(value<0){signPrefix='-';value=-value;}
+var i=0;while(value>=1024&&i<SIZE_UNIT_PREFIXES.length-1){value/=1024;i++;}
+return signPrefix+value.toFixed(1)+' '+SIZE_UNIT_PREFIXES[i]+'B';}};Units.unitsByJSONName['sizeInBytes']=Units.sizeInBytes;Units.energyInJoules={asJSON:function(){return'J';},format:function(value){return value.toLocaleString(undefined,{minimumFractionDigits:3})+' J';}};Units.unitsByJSONName['J']=Units.energyInJoules;Units.powerInWatts={asJSON:function(){return'W';},format:function(value){return(value*1000.0).toLocaleString(undefined,{minimumFractionDigits:3})+' mW';}};Units.unitsByJSONName['W']=Units.powerInWatts;Units.unitlessNumber={asJSON:function(){return'unitless';},format:function(value){return value.toLocaleString(undefined,{minimumFractionDigits:3,maximumFractionDigits:3});}};Units.unitsByJSONName['unitless']=Units.unitlessNumber;return{Units:Units};});'use strict';tr.exportTo('tr.c',function(){function Auditor(model){this.model_=model;}
+Auditor.prototype={__proto__:Object.prototype,get model(){return this.model_;},runAnnotate:function(){},runAudit:function(){}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Auditor;tr.b.decorateExtensionRegistry(Auditor,options);return{Auditor:Auditor};});'use strict';tr.exportTo('tr.c',function(){function makeCaseInsensitiveRegex(pattern){pattern=pattern.replace(/[.*+?^${}()|[\]\\]/g,'\\$&');return new RegExp(pattern,'i');}
+function Filter(){}
+Filter.prototype={__proto__:Object.prototype,matchCounter:function(counter){return true;},matchCpu:function(cpu){return true;},matchProcess:function(process){return true;},matchSlice:function(slice){return true;},matchThread:function(thread){return true;}};function TitleOrCategoryFilter(text){Filter.call(this);this.regex_=makeCaseInsensitiveRegex(text);if(!text.length)
+throw new Error('Filter text is empty.');}
+TitleOrCategoryFilter.prototype={__proto__:Filter.prototype,matchSlice:function(slice){if(slice.title===undefined&&slice.category===undefined)
+return false;return this.regex_.test(slice.title)||(!!slice.category&&this.regex_.test(slice.category));}};function ExactTitleFilter(text){Filter.call(this);this.text_=text;if(!text.length)
+throw new Error('Filter text is empty.');}
+ExactTitleFilter.prototype={__proto__:Filter.prototype,matchSlice:function(slice){return slice.title===this.text_;}};function FullTextFilter(text){Filter.call(this);this.regex_=makeCaseInsensitiveRegex(text);this.titleOrCategoryFilter_=new TitleOrCategoryFilter(text);}
+FullTextFilter.prototype={__proto__:Filter.prototype,matchObject_:function(obj){for(var key in obj){if(!obj.hasOwnProperty(key))
+continue;if(this.regex_.test(key))
+return true;if(this.regex_.test(obj[key]))
+return true;}
+return false;},matchSlice:function(slice){if(this.titleOrCategoryFilter_.matchSlice(slice))
+return true;return this.matchObject_(slice.args);}};return{Filter:Filter,TitleOrCategoryFilter:TitleOrCategoryFilter,ExactTitleFilter:ExactTitleFilter,FullTextFilter:FullTextFilter};});'use strict';tr.exportTo('tr.b.u',function(){function Scalar(value,unit){this.value=value;this.unit=unit;};Scalar.prototype={toString:function(){return this.unit.format(this.value);}};return{Scalar:Scalar};});'use strict';tr.exportTo('tr.b.u',function(){function TimeStamp(timestamp){tr.b.u.Scalar.call(this,timestamp,tr.b.u.Units.timeStampInMs);};TimeStamp.prototype={__proto__:tr.b.u.Scalar.prototype,get timestamp(){return this.value;}};TimeStamp.format=function(timestamp){return tr.b.u.Units.timeStampInMs.format(timestamp);};return{TimeStamp:TimeStamp};});'use strict';tr.exportTo('tr.b',function(){function clamp01(value){return Math.max(0,Math.min(1,value));}
+function Color(opt_r,opt_g,opt_b,opt_a){this.r=Math.floor(opt_r)||0;this.g=Math.floor(opt_g)||0;this.b=Math.floor(opt_b)||0;this.a=opt_a;}
+Color.fromString=function(str){var tmp;var values;if(str.substr(0,4)=='rgb('){tmp=str.substr(4,str.length-5);values=tmp.split(',').map(function(v){return v.replace(/^\s+/,'','g');});if(values.length!=3)
+throw new Error('Malformatted rgb-expression');return new Color(parseInt(values[0]),parseInt(values[1]),parseInt(values[2]));}else if(str.substr(0,5)=='rgba('){tmp=str.substr(5,str.length-6);values=tmp.split(',').map(function(v){return v.replace(/^\s+/,'','g');});if(values.length!=4)
+throw new Error('Malformatted rgb-expression');return new Color(parseInt(values[0]),parseInt(values[1]),parseInt(values[2]),parseFloat(values[3]));}else if(str[0]=='#'&&str.length==7){return new Color(parseInt(str.substr(1,2),16),parseInt(str.substr(3,2),16),parseInt(str.substr(5,2),16));}else{throw new Error('Unrecognized string format.');}};Color.lerp=function(a,b,percent){if(a.a!==undefined&&b.a!==undefined)
+return Color.lerpRGBA(a,b,percent);return Color.lerpRGB(a,b,percent);};Color.lerpRGB=function(a,b,percent){return new Color(((b.r-a.r)*percent)+a.r,((b.g-a.g)*percent)+a.g,((b.b-a.b)*percent)+a.b);};Color.lerpRGBA=function(a,b,percent){return new Color(((b.r-a.r)*percent)+a.r,((b.g-a.g)*percent)+a.g,((b.b-a.b)*percent)+a.b,((b.a-a.a)*percent)+a.a);};Color.fromDict=function(dict){return new Color(dict.r,dict.g,dict.b,dict.a);};Color.fromHSLExplicit=function(h,s,l,a){var r,g,b;function hue2rgb(p,q,t){if(t<0)t+=1;if(t>1)t-=1;if(t<1/6)return p+(q-p)*6*t;if(t<1/2)return q;if(t<2/3)return p+(q-p)*(2/3-t)*6;return p;}
+if(s===0){r=g=b=l;}else{var q=l<0.5?l*(1+s):l+s-l*s;var p=2*l-q;r=hue2rgb(p,q,h+1/3);g=hue2rgb(p,q,h);b=hue2rgb(p,q,h-1/3);}
+return new Color(Math.floor(r*255),Math.floor(g*255),Math.floor(b*255),a);}
+Color.fromHSL=function(hsl){return Color.fromHSLExplicit(hsl.h,hsl.s,hsl.l,hsl.a);}
+Color.prototype={clone:function(){var c=new Color();c.r=this.r;c.g=this.g;c.b=this.b;c.a=this.a;return c;},blendOver:function(bgColor){var oneMinusThisAlpha=1-this.a;var outA=this.a+bgColor.a*oneMinusThisAlpha;var bgBlend=(bgColor.a*oneMinusThisAlpha)/bgColor.a;return new Color(this.r*this.a+bgColor.r*bgBlend,this.g*this.a+bgColor.g*bgBlend,this.b*this.a+bgColor.b*bgBlend,outA);},brighten:function(opt_k){var k;k=opt_k||0.45;return new Color(Math.min(255,this.r+Math.floor(this.r*k)),Math.min(255,this.g+Math.floor(this.g*k)),Math.min(255,this.b+Math.floor(this.b*k)),this.a);},lighten:function(k,opt_max_l){var max_l=opt_max_l!==undefined?opt_max_l:1.0;var hsl=this.toHSL();hsl.l=clamp01(hsl.l+k);return Color.fromHSL(hsl);},darken:function(opt_k){var k;if(opt_k!==undefined)
+k=opt_k;else
+k=0.45;return new Color(Math.min(255,this.r-Math.floor(this.r*k)),Math.min(255,this.g-Math.floor(this.g*k)),Math.min(255,this.b-Math.floor(this.b*k)),this.a);},desaturate:function(opt_desaturateFactor){var desaturateFactor;if(opt_desaturateFactor!==undefined)
+desaturateFactor=opt_desaturateFactor;else
+desaturateFactor=1;var hsl=this.toHSL();hsl.s=clamp01(hsl.s*(1-desaturateFactor));return Color.fromHSL(hsl);},withAlpha:function(a){return new Color(this.r,this.g,this.b,a);},toString:function(){if(this.a!==undefined){return'rgba('+
+this.r+','+this.g+','+
+this.b+','+this.a+')';}
+return'rgb('+this.r+','+this.g+','+this.b+')';},toHSL:function(){var r=this.r/255;var g=this.g/255;var b=this.b/255;var max=Math.max(r,g,b);var min=Math.min(r,g,b);var h,s;var l=(max+min)/2;if(min===max){h=0;s=0;}else{var delta=max-min;if(l>0.5)
+s=delta/(2-max-min);else
+s=delta/(max+min);if(r===max){h=(g-b)/delta;if(g<b)
+h+=6;}else if(g===max){h=2+((b-r)/delta);}else{h=4+((r-g)/delta);}
+h/=6;}
+return{h:h,s:s,l:l,a:this.a};},toStringWithAlphaOverride:function(alpha){return'rgba('+
+this.r+','+this.g+','+
+this.b+','+alpha+')';}};return{Color:Color};});'use strict';tr.exportTo('tr.b',function(){var generalPurposeColors=[new tr.b.Color(122,98,135),new tr.b.Color(150,83,105),new tr.b.Color(44,56,189),new tr.b.Color(99,86,147),new tr.b.Color(104,129,107),new tr.b.Color(130,178,55),new tr.b.Color(87,109,147),new tr.b.Color(111,145,88),new tr.b.Color(81,152,131),new tr.b.Color(142,91,111),new tr.b.Color(81,163,70),new tr.b.Color(148,94,86),new tr.b.Color(144,89,118),new tr.b.Color(83,150,97),new tr.b.Color(105,94,139),new tr.b.Color(89,144,122),new tr.b.Color(105,119,128),new tr.b.Color(96,128,137),new tr.b.Color(145,88,145),new tr.b.Color(88,145,144),new tr.b.Color(90,100,143),new tr.b.Color(121,97,136),new tr.b.Color(111,160,73),new tr.b.Color(112,91,142),new tr.b.Color(86,147,86),new tr.b.Color(63,100,170),new tr.b.Color(81,152,107),new tr.b.Color(60,164,173),new tr.b.Color(143,72,161),new tr.b.Color(159,74,86)];var reservedColorsByName={thread_state_iowait:new tr.b.Color(182,125,143),thread_state_running:new tr.b.Color(126,200,148),thread_state_runnable:new tr.b.Color(133,160,210),thread_state_sleeping:new tr.b.Color(240,240,240),thread_state_unknown:new tr.b.Color(199,155,125),light_memory_dump:new tr.b.Color(0,0,180),detailed_memory_dump:new tr.b.Color(180,0,180),generic_work:new tr.b.Color(125,125,125),good:new tr.b.Color(0,125,0),bad:new tr.b.Color(180,125,0),terrible:new tr.b.Color(180,0,0),black:new tr.b.Color(0,0,0),rail_response:new tr.b.Color(67,135,253),rail_animate:new tr.b.Color(244,74,63),rail_idle:new tr.b.Color(238,142,0),rail_load:new tr.b.Color(13,168,97),used_memory_column:new tr.b.Color(0,0,255),older_used_memory_column:new tr.b.Color(153,204,255),tracing_memory_column:new tr.b.Color(153,153,153),cq_build_running:new tr.b.Color(255,255,119),cq_build_passed:new tr.b.Color(153,238,102),cq_build_failed:new tr.b.Color(238,136,136),cq_build_abandoned:new tr.b.Color(187,187,187),cq_build_attempt_runnig:new tr.b.Color(222,222,75),cq_build_attempt_passed:new tr.b.Color(103,218,35),cq_build_attempt_failed:new tr.b.Color(197,81,81)};var numGeneralPurposeColorIds=generalPurposeColors.length;var numReservedColorIds=tr.b.dictionaryLength(reservedColorsByName);var numColorsPerVariant=numGeneralPurposeColorIds+numReservedColorIds;function ColorScheme(){}
+var paletteBase=[];paletteBase.push.apply(paletteBase,generalPurposeColors);paletteBase.push.apply(paletteBase,tr.b.dictionaryValues(reservedColorsByName));ColorScheme.colors=[];ColorScheme.properties={};ColorScheme.properties={numColorsPerVariant:numColorsPerVariant};function pushVariant(func){var variantColors=paletteBase.map(func);ColorScheme.colors.push.apply(ColorScheme.colors,variantColors);}
+pushVariant(function(c){return c;});ColorScheme.properties.brightenedOffsets=[];ColorScheme.properties.brightenedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.lighten(0.3,0.9);});ColorScheme.properties.brightenedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.lighten(0.48,0.9);});ColorScheme.properties.brightenedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.lighten(0.65,0.9);});ColorScheme.properties.dimmedOffsets=[];ColorScheme.properties.dimmedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.desaturate();});ColorScheme.properties.dimmedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.desaturate(0.5);});ColorScheme.properties.dimmedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.desaturate(0.3);});ColorScheme.colorsAsStrings=ColorScheme.colors.map(function(c){return c.toString();});var reservedColorNameToIdMap=(function(){var m={};var i=generalPurposeColors.length;tr.b.iterItems(reservedColorsByName,function(key,value){m[key]=i++;});return m;})();ColorScheme.getColorIdForReservedName=function(name){var id=reservedColorNameToIdMap[name];if(id===undefined)
+throw new Error('Unrecognized color ')+name;return id;};ColorScheme.getColorForReservedNameAsString=function(reservedName){var id=ColorScheme.getColorIdForReservedName(reservedName);return ColorScheme.colorsAsStrings[id];};ColorScheme.getStringHash=function(name){var hash=0;for(var i=0;i<name.length;++i)
+hash=(hash+37*hash+11*name.charCodeAt(i))%0xFFFFFFFF;return hash;};var stringColorIdCache={};ColorScheme.getColorIdForGeneralPurposeString=function(string){if(stringColorIdCache[string]===undefined){var hash=ColorScheme.getStringHash(string);stringColorIdCache[string]=hash%numGeneralPurposeColorIds;}
+return stringColorIdCache[string];};return{ColorScheme:ColorScheme};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;function EventInfo(title,description,docLinks){this.title=title;this.description=description;this.docLinks=docLinks;this.colorId=ColorScheme.getColorIdForGeneralPurposeString(title);}
+return{EventInfo:EventInfo};});'use strict';tr.exportTo('tr.b',function(){var nextGUID=1;var GUID={allocate:function(){return nextGUID++;},getLastGuid:function(){return nextGUID-1;}};return{GUID:GUID};});'use strict';tr.exportTo('tr.model',function(){function EventRegistry(){}
+var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(EventRegistry,options);EventRegistry.addEventListener('will-register',function(e){var metadata=e.typeInfo.metadata;if(metadata.name===undefined)
+throw new Error('Registered events must provide name metadata');var i=tr.b.findFirstInArray(EventRegistry.getAllRegisteredTypeInfos(),function(x){return x.metadata.name===metadata.name;});if(i!==undefined)
+throw new Error('Event type with that name already registered');if(metadata.pluralName===undefined)
+throw new Error('Registered events must provide pluralName metadata');if(metadata.singleViewElementName===undefined){throw new Error('Registered events must provide '+'singleViewElementName metadata');}
+if(metadata.multiViewElementName===undefined){throw new Error('Registered events must provide '+'multiViewElementName metadata');}});var eventsByTypeName=undefined;EventRegistry.getEventTypeInfoByTypeName=function(typeName){if(eventsByTypeName===undefined){eventsByTypeName={};EventRegistry.getAllRegisteredTypeInfos().forEach(function(typeInfo){eventsByTypeName[typeInfo.metadata.name]=typeInfo;});}
+return eventsByTypeName[typeName];}
+EventRegistry.addEventListener('registry-changed',function(){eventsByTypeName=undefined;});function convertCamelCaseToTitleCase(name){var result=name.replace(/[A-Z]/g,' $&');result=result.charAt(0).toUpperCase()+result.slice(1);return result;}
+EventRegistry.getUserFriendlySingularName=function(typeName){var typeInfo=EventRegistry.getEventTypeInfoByTypeName(typeName);var str=typeInfo.metadata.name;return convertCamelCaseToTitleCase(str);};EventRegistry.getUserFriendlyPluralName=function(typeName){var typeInfo=EventRegistry.getEventTypeInfoByTypeName(typeName);var str=typeInfo.metadata.pluralName;return convertCamelCaseToTitleCase(str);};return{EventRegistry:EventRegistry};});'use strict';tr.exportTo('tr.model',function(){var EventRegistry=tr.model.EventRegistry;var RequestSelectionChangeEvent=tr.b.Event.bind(undefined,'requestSelectionChange',true,false);function EventSet(opt_events){this.bounds_dirty_=true;this.bounds_=new tr.b.Range();this.length_=0;this.guid_=tr.b.GUID.allocate();this.pushed_guids_={};if(opt_events){if(opt_events instanceof Array){for(var i=0;i<opt_events.length;i++)
+this.push(opt_events[i]);}else if(opt_events instanceof EventSet){this.addEventSet(opt_events);}else{this.push(opt_events);}}}
+EventSet.prototype={__proto__:Object.prototype,get bounds(){if(this.bounds_dirty_){this.bounds_.reset();for(var i=0;i<this.length_;i++)
+this[i].addBoundsToRange(this.bounds_);this.bounds_dirty_=false;}
+return this.bounds_;},get duration(){if(this.bounds_.isEmpty)
+return 0;return this.bounds_.max-this.bounds_.min;},get length(){return this.length_;},get guid(){return this.guid_;},clear:function(){for(var i=0;i<this.length_;++i)
+delete this[i];this.length_=0;this.bounds_dirty_=true;},push:function(event){if(event.guid==undefined)
+throw new Error('Event must have a GUID');if(this.contains(event))
+return event;this.pushed_guids_[event.guid]=true;this[this.length_++]=event;this.bounds_dirty_=true;return event;},contains:function(event){return this.pushed_guids_[event.guid];},addEventSet:function(eventSet){for(var i=0;i<eventSet.length;i++)
+this.push(eventSet[i]);},subEventSet:function(index,count){count=count||1;var eventSet=new EventSet();eventSet.bounds_dirty_=true;if(index<0||index+count>this.length_)
+throw new Error('Index out of bounds');for(var i=index;i<index+count;i++)
+eventSet.push(this[i]);return eventSet;},intersectionIsEmpty:function(otherEventSet){return!this.some(function(event){return otherEventSet.contains(event);});},equals:function(that){if(this.length!==that.length)
+return false;for(var i=0;i<this.length;i++){var event=this[i];if(that.pushed_guids_[event.guid]===undefined)
+return false;}
+return true;},getEventsOrganizedByBaseType:function(opt_pruneEmpty){var allTypeInfos=EventRegistry.getAllRegisteredTypeInfos();var events=this.getEventsOrganizedByCallback(function(event){var maxEventIndex=-1;var maxEventTypeInfo=undefined;allTypeInfos.forEach(function(eventTypeInfo,eventIndex){if(!(event instanceof eventTypeInfo.constructor))
+return;if(eventIndex>maxEventIndex){maxEventIndex=eventIndex;maxEventTypeInfo=eventTypeInfo;}});if(maxEventIndex==-1){console.log(event);throw new Error('Unrecognized event type');}
+return maxEventTypeInfo.metadata.name;});if(!opt_pruneEmpty){allTypeInfos.forEach(function(eventTypeInfo){if(events[eventTypeInfo.metadata.name]===undefined)
+events[eventTypeInfo.metadata.name]=new EventSet();});}
+return events;},getEventsOrganizedByTitle:function(){return this.getEventsOrganizedByCallback(function(event){if(event.title===undefined)
+throw new Error('An event didn\'t have a title!');return event.title;});},getEventsOrganizedByCallback:function(cb){var eventsByCallback={};for(var i=0;i<this.length;i++){var event=this[i];var key=cb(event);if(key===undefined)
+throw new Error('An event could not be organized');if(eventsByCallback[key]===undefined)
+eventsByCallback[key]=new EventSet();eventsByCallback[key].push(event);}
+return eventsByCallback;},enumEventsOfType:function(type,func){for(var i=0;i<this.length_;i++)
+if(this[i]instanceof type)
+func(this[i]);},get userFriendlyName(){if(this.length===0){throw new Error('Empty event set');}
+var eventsByBaseType=this.getEventsOrganizedByBaseType(true);var eventTypeName=tr.b.dictionaryKeys(eventsByBaseType)[0];if(this.length===1){var tmp=EventRegistry.getUserFriendlySingularName(eventTypeName);return this[0].userFriendlyName;}
+var numEventTypes=tr.b.dictionaryLength(eventsByBaseType);if(numEventTypes!==1){return this.length+' events of various types';}
+var tmp=EventRegistry.getUserFriendlyPluralName(eventTypeName);return this.length+' '+tmp;},filter:function(fn,opt_this){var res=new EventSet();this.forEach(function(slice){if(fn.call(this,slice))
+res.push(slice);},opt_this);return res;},toArray:function(){var ary=[];for(var i=0;i<this.length;i++)
+ary.push(this[i]);return ary;},forEach:function(fn,opt_this){for(var i=0;i<this.length;i++)
+fn.call(opt_this,this[i],i);},map:function(fn,opt_this){var res=[];for(var i=0;i<this.length;i++)
+res.push(fn.call(opt_this,this[i],i));return res;},every:function(fn,opt_this){for(var i=0;i<this.length;i++)
+if(!fn.call(opt_this,this[i],i))
+return false;return true;},some:function(fn,opt_this){for(var i=0;i<this.length;i++)
+if(fn.call(opt_this,this[i],i))
+return true;return false;},asDict:function(){var stable_ids=[];this.forEach(function(event){stable_ids.push(event.stableId);});return{'events':stable_ids};}};return{EventSet:EventSet,RequestSelectionChangeEvent:RequestSelectionChangeEvent};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;var SelectionState={NONE:0,SELECTED:ColorScheme.properties.brightenedOffsets[0],HIGHLIGHTED:ColorScheme.properties.brightenedOffsets[1],DIMMED:ColorScheme.properties.dimmedOffsets[0],BRIGHTENED0:ColorScheme.properties.brightenedOffsets[0],BRIGHTENED1:ColorScheme.properties.brightenedOffsets[1],BRIGHTENED2:ColorScheme.properties.brightenedOffsets[2],DIMMED0:ColorScheme.properties.dimmedOffsets[0],DIMMED1:ColorScheme.properties.dimmedOffsets[1],DIMMED2:ColorScheme.properties.dimmedOffsets[2]};var brighteningLevels=[SelectionState.NONE,SelectionState.BRIGHTENED0,SelectionState.BRIGHTENED1,SelectionState.BRIGHTENED2];SelectionState.getFromBrighteningLevel=function(level){return brighteningLevels[level];}
+var dimmingLevels=[SelectionState.DIMMED0,SelectionState.DIMMED1,SelectionState.DIMMED2];SelectionState.getFromDimmingLevel=function(level){return dimmingLevels[level];}
+return{SelectionState:SelectionState};});'use strict';tr.exportTo('tr.model',function(){var SelectionState=tr.model.SelectionState;function SelectableItem(modelItem){this.modelItem_=modelItem;}
+SelectableItem.prototype={get modelItem(){return this.modelItem_;},get selected(){return this.selectionState===SelectionState.SELECTED;},addToSelection:function(selection){var modelItem=this.modelItem_;if(!modelItem)
+return;selection.push(modelItem);},addToTrackMap:function(eventToTrackMap,track){var modelItem=this.modelItem_;if(!modelItem)
+return;eventToTrackMap.addEvent(modelItem,track);}};return{SelectableItem:SelectableItem};});'use strict';tr.exportTo('tr.model',function(){var SelectableItem=tr.model.SelectableItem;var SelectionState=tr.model.SelectionState;function Event(){SelectableItem.call(this,this);this.guid_=tr.b.GUID.allocate();this.selectionState=SelectionState.NONE;this.associatedAlerts=new tr.model.EventSet();this.info=undefined;}
+Event.prototype={__proto__:SelectableItem.prototype,get guid(){return this.guid_;},get stableId(){return undefined;},addBoundsToRange:function(range){throw new Error('Not implemented');}};return{Event:Event};});'use strict';tr.exportTo('tr.model',function(){function TimedEvent(start){tr.model.Event.call(this);this.start=start;this.duration=0;this.cpuStart=undefined;this.cpuDuration=undefined;}
+TimedEvent.prototype={__proto__:tr.model.Event.prototype,get end(){return this.start+this.duration;},addBoundsToRange:function(range){range.addValue(this.start);range.addValue(this.end);},bounds:function(that,precisionUnit){if(precisionUnit===undefined){precisionUnit=tr.b.u.TimeDisplayModes.ms;}
+var startsBefore=precisionUnit.roundedLess(that.start,this.start);var endsAfter=precisionUnit.roundedLess(this.end,that.end);return!startsBefore&&!endsAfter;}};return{TimedEvent:TimedEvent};});'use strict';tr.exportTo('tr.model',function(){function Alert(info,start,opt_associatedEvents,opt_args){tr.model.TimedEvent.call(this,start);this.info=info;this.args=opt_args||{};this.associatedEvents=new tr.model.EventSet(opt_associatedEvents);this.associatedEvents.forEach(function(event){event.associatedAlerts.push(this);},this);}
+Alert.prototype={__proto__:tr.model.TimedEvent.prototype,get title(){return this.info.title;},get colorId(){return this.info.colorId;},get userFriendlyName(){return'Alert '+this.title+' at '+
+tr.b.u.TimeStamp.format(this.start);}};tr.model.EventRegistry.register(Alert,{name:'alert',pluralName:'alerts',singleViewElementName:'tr-ui-a-alert-sub-view',multiViewElementName:'tr-ui-a-alert-sub-view'});return{Alert:Alert};});'use strict';tr.exportTo('tr.model',function(){function EventContainer(){this.guid_=tr.b.GUID.allocate();this.important=true;this.bounds_=new tr.b.Range();}
+EventContainer.prototype={get guid(){return this.guid_;},get stableId(){throw new Error('Not implemented');},get bounds(){return this.bounds_;},updateBounds:function(){throw new Error('Not implemented');},shiftTimestampsForward:function(amount){throw new Error('Not implemented');},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){throw new Error('Not implemented');},iterateAllChildEventContainers:function(callback,opt_this){throw new Error('Not implemented');},iterateAllEvents:function(callback,opt_this){this.iterateAllEventContainers(function(ec){ec.iterateAllEventsInThisContainer(function(eventType){return true;},callback,opt_this);});},iterateAllEventContainers:function(callback,opt_this){function visit(ec){callback.call(opt_this,ec);ec.iterateAllChildEventContainers(visit);}
+visit(this);}};return{EventContainer:EventContainer};});'use strict';tr.exportTo('tr.model',function(){var Event=tr.model.Event;var EventRegistry=tr.model.EventRegistry;function PowerSample(series,start,power){Event.call(this);this.series_=series;this.start_=start;this.power_=power;}
+PowerSample.prototype={__proto__:Event.prototype,get series(){return this.series_;},get start(){return this.start_;},set start(value){this.start_=value;},get power(){return this.power_;},set power(value){this.power_=value;},addBoundsToRange:function(range){range.addValue(this.start);}};EventRegistry.register(PowerSample,{name:'powerSample',pluralName:'powerSamples',singleViewElementName:'tr-ui-a-single-power-sample-sub-view',multiViewElementName:'tr-ui-a-multi-power-sample-sub-view'});return{PowerSample:PowerSample};});'use strict';tr.exportTo('tr.model',function(){var PowerSample=tr.model.PowerSample;function PowerSeries(device){tr.model.EventContainer.call(this);this.device_=device;this.samples_=[];}
+PowerSeries.prototype={__proto__:tr.model.EventContainer.prototype,get device(){return this.device_;},get samples(){return this.samples_;},get stableId(){return this.device_.stableId+'.PowerSeries';},addPowerSample:function(ts,val){var sample=new PowerSample(this,ts,val);this.samples_.push(sample);return sample;},getEnergyConsumed:function(start,end){var measurementRange=tr.b.Range.fromExplicitRange(start,end);var energyConsumed=0;for(var i=0;i<this.samples.length;i++){var sample=this.samples[i];var nextSample=this.samples[i+1];var sampleRange=new tr.b.Range();sampleRange.addValue(sample.start);sampleRange.addValue(nextSample?nextSample.start:Infinity);var timeIntersection=measurementRange.findIntersection(sampleRange);energyConsumed+=timeIntersection.duration/1000*sample.power;}
+return energyConsumed;},shiftTimestampsForward:function(amount){for(var i=0;i<this.samples_.length;++i)
+this.samples_[i].start+=amount;},updateBounds:function(){this.bounds.reset();if(this.samples_.length===0)
+return;this.bounds.addValue(this.samples_[0].start);this.bounds.addValue(this.samples_[this.samples_.length-1].start);},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,PowerSample))
+this.samples_.forEach(callback,opt_this);},iterateAllChildEventContainers:function(callback,opt_this){}};return{PowerSeries:PowerSeries};});'use strict';tr.exportTo('tr.model',function(){function Device(model){if(!model)
+throw new Error('Must provide a model.');tr.model.EventContainer.call(this);this.powerSeries_=undefined;this.vSyncTimestamps_=[];};Device.compare=function(x,y){return x.guid-y.guid;};Device.prototype={__proto__:tr.model.EventContainer.prototype,compareTo:function(that){return Device.compare(this,that);},get userFriendlyName(){return'Device';},get userFriendlyDetails(){return'Device';},get stableId(){return'Device';},getSettingsKey:function(){return'device';},get powerSeries(){return this.powerSeries_;},set powerSeries(powerSeries){this.powerSeries_=powerSeries;},get vSyncTimestamps(){return this.vSyncTimestamps_;},set vSyncTimestamps(value){this.vSyncTimestamps_=value;},updateBounds:function(){this.bounds.reset();this.iterateAllChildEventContainers(function(child){child.updateBounds();this.bounds.addRange(child.bounds);},this);},shiftTimestampsForward:function(amount){this.iterateAllChildEventContainers(function(child){child.shiftTimestampsForward(amount);});for(var i=0;i<this.vSyncTimestamps_.length;i++)
+this.vSyncTimestamps_[i]+=amount;},addCategoriesToDict:function(categoriesDict){},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){},iterateAllChildEventContainers:function(callback,opt_this){if(this.powerSeries_)
+callback.call(opt_this,this.powerSeries_);}};return{Device:Device};});'use strict';tr.exportTo('tr.model',function(){function FlowEvent(category,id,title,colorId,start,args,opt_duration){tr.model.TimedEvent.call(this,start);this.category=category||'';this.title=title;this.colorId=colorId;this.start=start;this.args=args;this.id=id;this.startSlice=undefined;this.endSlice=undefined;this.startStackFrame=undefined;this.endStackFrame=undefined;if(opt_duration!==undefined)
+this.duration=opt_duration;}
+FlowEvent.prototype={__proto__:tr.model.TimedEvent.prototype,get userFriendlyName(){return'Flow event named '+this.title+' at '+
+tr.b.u.TimeStamp.format(this.timestamp);}};tr.model.EventRegistry.register(FlowEvent,{name:'flowEvent',pluralName:'flowEvents',singleViewElementName:'tr-ui-a-single-flow-event-sub-view',multiViewElementName:'tr-ui-a-multi-flow-event-sub-view'});return{FlowEvent:FlowEvent};});'use strict';tr.exportTo('tr.b',function(){function identity(d){return d;}
+function Statistics(){}
+Statistics.divideIfPossibleOrZero=function(numerator,denominator){if(denominator===0)
+return 0;return numerator/denominator;}
+Statistics.sum=function(ary,opt_func,opt_this){var func=opt_func||identity;var ret=0;for(var i=0;i<ary.length;i++)
+ret+=func.call(opt_this,ary[i],i);return ret;};Statistics.mean=function(ary,opt_func,opt_this){return Statistics.sum(ary,opt_func,opt_this)/ary.length;};Statistics.variance=function(ary,opt_func,opt_this){var func=opt_func||identity;var mean=Statistics.mean(ary,func,opt_this);var sumOfSquaredDistances=Statistics.sum(ary,function(d,i){var v=func.call(this,d,i)-mean;return v*v;},opt_this);return sumOfSquaredDistances/(ary.length-1);};Statistics.stddev=function(ary,opt_func,opt_this){return Math.sqrt(Statistics.variance(ary,opt_func,opt_this));};Statistics.max=function(ary,opt_func,opt_this){var func=opt_func||identity;var ret=-Infinity;for(var i=0;i<ary.length;i++)
+ret=Math.max(ret,func.call(opt_this,ary[i],i));return ret;};Statistics.min=function(ary,opt_func,opt_this){var func=opt_func||identity;var ret=Infinity;for(var i=0;i<ary.length;i++)
+ret=Math.min(ret,func.call(opt_this,ary[i],i));return ret;};Statistics.range=function(ary,opt_func,opt_this){var func=opt_func||identity;var ret=new tr.b.Range();for(var i=0;i<ary.length;i++)
+ret.addValue(func.call(opt_this,ary[i],i));return ret;}
+Statistics.percentile=function(ary,percent,opt_func,opt_this){if(!(percent>=0&&percent<=1))
+throw new Error('percent must be [0,1]');var func=opt_func||identity;var tmp=new Array(ary.length);for(var i=0;i<ary.length;i++)
+tmp[i]=func.call(opt_this,ary[i],i);tmp.sort();var idx=Math.floor((ary.length-1)*percent);return tmp[idx];};Statistics.clamp=function(value,opt_low,opt_high){opt_low=opt_low||0.0;opt_high=opt_high||1.0;return Math.min(Math.max(value,opt_low),opt_high);}
+Statistics.normalizeSamples=function(samples){if(samples.length===0){return{normalized_samples:samples,scale:1.0};}
+samples=samples.slice().sort(function(a,b){return a-b;});var low=Math.min.apply(null,samples);var high=Math.max.apply(null,samples);var new_low=0.5/samples.length;var new_high=(samples.length-0.5)/samples.length;if(high-low===0.0){samples=Array.apply(null,new Array(samples.length)).map(function(){return 0.5;});return{normalized_samples:samples,scale:1.0};}
+var scale=(new_high-new_low)/(high-low);for(var i=0;i<samples.length;i++){samples[i]=(samples[i]-low)*scale+new_low;}
+return{normalized_samples:samples,scale:scale};}
+Statistics.discrepancy=function(samples,opt_location_count){if(samples.length===0)
+return 0.0;var max_local_discrepancy=0;var inv_sample_count=1.0/samples.length;var locations=[];var count_less=[];var count_less_equal=[];if(opt_location_count!==undefined){var sample_index=0;for(var i=0;i<opt_location_count;i++){var location=i/(opt_location_count-1);locations.push(location);while(sample_index<samples.length&&samples[sample_index]<location){sample_index+=1;}
+count_less.push(sample_index);while(sample_index<samples.length&&samples[sample_index]<=location){sample_index+=1;}
+count_less_equal.push(sample_index);}}else{if(samples[0]>0.0){locations.push(0.0);count_less.push(0);count_less_equal.push(0);}
+for(var i=0;i<samples.length;i++){locations.push(samples[i]);count_less.push(i);count_less_equal.push(i+1);}
+if(samples[-1]<1.0){locations.push(1.0);count_less.push(samples.length);count_less_equal.push(samples.length);}}
+for(var i=0;i<locations.length;i++){for(var j=i+1;j<locations.length;j++){var length=locations[j]-locations[i];var count_closed=count_less_equal[j]-count_less[i];var local_discrepancy_closed=Math.abs(count_closed*inv_sample_count-length);var max_local_discrepancy=Math.max(local_discrepancy_closed,max_local_discrepancy);var count_open=count_less[j]-count_less_equal[i];var local_discrepancy_open=Math.abs(count_open*inv_sample_count-length);var max_local_discrepancy=Math.max(local_discrepancy_open,max_local_discrepancy);}}
+return max_local_discrepancy;};Statistics.timestampsDiscrepancy=function(timestamps,opt_absolute,opt_location_count){if(timestamps.length===0)
+return 0.0;if(opt_absolute===undefined)
+opt_absolute=true;if(Array.isArray(timestamps[0])){var range_discrepancies=timestamps.map(function(r){return Statistics.timestampsDiscrepancy(r);});return Math.max.apply(null,range_discrepancies);}
+var s=Statistics.normalizeSamples(timestamps);var samples=s.normalized_samples;var sample_scale=s.scale;var discrepancy=Statistics.discrepancy(samples,opt_location_count);var inv_sample_count=1.0/samples.length;if(opt_absolute===true){discrepancy/=sample_scale;}else{discrepancy=Statistics.clamp((discrepancy-inv_sample_count)/(1.0-inv_sample_count));}
+return discrepancy;};Statistics.durationsDiscrepancy=function(durations,opt_absolute,opt_location_count){if(durations.length===0)
+return 0.0;var timestamps=durations.reduce(function(prev,curr,index,array){prev.push(prev[prev.length-1]+curr);return prev;},[0]);return Statistics.timestampsDiscrepancy(timestamps,opt_absolute,opt_location_count);};Statistics.uniformlySampleStream=function(samples,streamLength,newElement,numSamples){if(streamLength<=numSamples){if(samples.length>=streamLength)
+samples[streamLength-1]=newElement;else
+samples.push(newElement);return;}
+var probToKeep=numSamples/streamLength;if(Math.random()>probToKeep)
+return;var index=Math.floor(Math.random()*numSamples);samples[index]=newElement;};Statistics.mergeSampledStreams=function(samplesA,streamLengthA,samplesB,streamLengthB,numSamples){if(streamLengthB<numSamples){var nbElements=Math.min(streamLengthB,samplesB.length);for(var i=0;i<nbElements;++i){Statistics.uniformlySampleStream(samplesA,streamLengthA+i+1,samplesB[i],numSamples);}
+return;}
+if(streamLengthA<numSamples){var nbElements=Math.min(streamLengthA,samplesA.length);var tempSamples=samplesB.slice();for(var i=0;i<nbElements;++i){Statistics.uniformlySampleStream(tempSamples,streamLengthB+i+1,samplesA[i],numSamples);}
+for(var i=0;i<tempSamples.length;++i){samplesA[i]=tempSamples[i];}
+return;}
+var nbElements=Math.min(numSamples,samplesB.length);var probOfSwapping=streamLengthB/(streamLengthA+streamLengthB);for(var i=0;i<nbElements;++i){if(Math.random()<probOfSwapping){samplesA[i]=samplesB[i];}}}
+return{Statistics:Statistics};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;var Statistics=tr.b.Statistics;var FRAME_PERF_CLASS={GOOD:'good',BAD:'bad',TERRIBLE:'terrible',NEUTRAL:'generic_work'};function Frame(associatedEvents,threadTimeRanges,opt_args){tr.model.Event.call(this);this.threadTimeRanges=threadTimeRanges;this.associatedEvents=new tr.model.EventSet(associatedEvents);this.args=opt_args||{};this.title='Frame';this.start=Statistics.min(threadTimeRanges,function(x){return x.start;});this.end=Statistics.max(threadTimeRanges,function(x){return x.end;});this.totalDuration=Statistics.sum(threadTimeRanges,function(x){return x.end-x.start;});this.perfClass=FRAME_PERF_CLASS.NEUTRAL;};Frame.prototype={__proto__:tr.model.Event.prototype,set perfClass(perfClass){this.colorId=ColorScheme.getColorIdForReservedName(perfClass);this.perfClass_=perfClass;},get perfClass(){return this.perfClass_;},shiftTimestampsForward:function(amount){this.start+=amount;this.end+=amount;for(var i=0;i<this.threadTimeRanges.length;i++){this.threadTimeRanges[i].start+=amount;this.threadTimeRanges[i].end+=amount;}},addBoundsToRange:function(range){range.addValue(this.start);range.addValue(this.end);}};tr.model.EventRegistry.register(Frame,{name:'frame',pluralName:'frames',singleViewElementName:'tr-ui-a-single-frame-sub-view',multiViewElementName:'tr-ui-a-multi-frame-sub-view'});return{Frame:Frame,FRAME_PERF_CLASS:FRAME_PERF_CLASS};});'use strict';tr.exportTo('tr.model',function(){function Attribute(units){this.units=units;this.infos=[];}
+Attribute.fromDictIfPossible=function(dict,opt_model){var typeInfo=Attribute.findTypeInfoMatching(function(typeInfo){return typeInfo.metadata.type===dict.type;});if(typeInfo===undefined){if(opt_model){opt_model.importWarning({type:'attribute_parse_error',message:'Unknown attribute type \''+dict.type+'\'.'});}
+return UnknownAttribute.fromDict(dict,opt_model);}
+return typeInfo.constructor.fromDict(dict,opt_model);};Attribute.findCommonTraits=function(attributes,opt_model){var commonTraits;for(var i=0;i<attributes.length;i++){var attribute=attributes[i];if(attribute===undefined)
+continue;var attributeConstructor=attribute.constructor;var attributeUnits=attribute.units;if(commonTraits===undefined){commonTraits={constructor:attributeConstructor,units:attributeUnits};}else if(attributeConstructor!==commonTraits.constructor){if(opt_model){opt_model.importWarning({type:'attribute_parse_error',message:'Attribute with different types: '+
+commonTraits.constructor+' and '+attributeConstructor+'.'});}
+commonTraits={constructor:UnknownAttribute,units:undefined};break;}else if(attributeUnits!==commonTraits.units){if(opt_model){opt_model.importWarning({type:'attribute_parse_error',message:'Attribute with different units: '+commonTraits.units+' and '+attributeUnits+'.'});}
+commonTraits={constructor:UnknownAttribute,units:undefined};break;}}
+return commonTraits;};Attribute.aggregate=function(childAttributes,existingParentAttribute,opt_model){var definedChildAttributes=childAttributes.filter(function(childAttribute){return childAttribute!==undefined;});var traits=Attribute.findCommonTraits(definedChildAttributes,opt_model);if(traits===undefined)
+return existingParentAttribute;var constructor=traits.constructor;if(constructor.merge===undefined)
+return existingParentAttribute;var mergedAttribute=constructor.merge(definedChildAttributes,traits.units,opt_model);if(existingParentAttribute===undefined)
+return mergedAttribute;existingParentAttribute.useMergedAttribute(mergedAttribute,opt_model);return existingParentAttribute;}
+Attribute.fromTraceValue=function(dict,opt_model){throw new Error('Not implemented');};Attribute.prototype.useMergedAttribute=function(mergedAttribute,opt_model){if(mergedAttribute.constructor!==this.constructor){if(opt_model){opt_model.importWarning({type:'attribute_parse_error',message:'Attribute with different types: '+this.constructor+' and '+mergedAttribute.constructor+'.'});}}else if(mergedAttribute.units!==this.units){if(opt_model){opt_model.importWarning({type:'attribute_parse_error',message:'Attribute with different units: '+this.units+' and '+mergedAttribute.units+'.'});}}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(Attribute,options);Attribute.addEventListener('will-register',function(e){if(!e.typeInfo.constructor.hasOwnProperty('fromDict'))
+throw new Error('Attributes must have fromDict method');if(!e.typeInfo.metadata.type)
+throw new Error('Attributes must provide type');if(e.typeInfo.constructor.prototype.constructor!==e.typeInfo.constructor)
+throw new Error('Attribute prototypes must provide constructor.');});function ScalarAttribute(units,value){Attribute.call(this,units);this.value=value;}
+ScalarAttribute.fromDict=function(dict){return new ScalarAttribute(dict.units,parseInt(dict.value,16));};ScalarAttribute.merge=function(childAttributes,units){var sum=0;childAttributes.forEach(function(childAttribute){sum+=childAttribute.value;});return new ScalarAttribute(units,sum);}
+ScalarAttribute.prototype.__proto__=Attribute.prototype;Attribute.register(ScalarAttribute,{type:'scalar'});function StringAttribute(units,value){Attribute.call(this,units);this.value=value;}
+StringAttribute.fromDict=function(dict){return new StringAttribute(dict.units,dict.value);};Attribute.register(StringAttribute,{type:'string'});function UnknownAttribute(units,opt_value){Attribute.call(this,units,opt_value);this.value=opt_value;}
+UnknownAttribute.fromDict=function(dict){return new UnknownAttribute(dict.units);};UnknownAttribute.prototype.__proto__=Attribute.prototype;function AttributeInfo(type,message){this.type=type;this.message=message;}
+var AttributeInfoType={INFORMATION:0,WARNING:1,LINK:2,MEMORY_OWNER:3,MEMORY_OWNED:4,OVERALL_VALUE:5,RECENT_VALUE:6,HAS_HEAP_DUMP:7};return{Attribute:Attribute,ScalarAttribute:ScalarAttribute,StringAttribute:StringAttribute,UnknownAttribute:UnknownAttribute,AttributeInfo:AttributeInfo,AttributeInfoType:AttributeInfoType};});'use strict';tr.exportTo('tr.model',function(){function ContainerMemoryDump(start){tr.model.TimedEvent.call(this,start);this.levelOfDetail=undefined;this.memoryAllocatorDumps_=undefined;this.memoryAllocatorDumpsByFullName_=undefined;};ContainerMemoryDump.prototype={__proto__:tr.model.TimedEvent.prototype,shiftTimestampsForward:function(amount){this.start+=amount;},get memoryAllocatorDumps(){return this.memoryAllocatorDumps_;},set memoryAllocatorDumps(memoryAllocatorDumps){this.memoryAllocatorDumps_=memoryAllocatorDumps;this.memoryAllocatorDumpsByFullName_=undefined;},getMemoryAllocatorDumpByFullName:function(fullName){if(this.memoryAllocatorDumps_===undefined)
+return undefined;if(this.memoryAllocatorDumpsByFullName_===undefined){var index={};function addDumpsToIndex(dumps){dumps.forEach(function(dump){index[dump.fullName]=dump;addDumpsToIndex(dump.children);});};addDumpsToIndex(this.memoryAllocatorDumps_);this.memoryAllocatorDumpsByFullName_=index;}
+return this.memoryAllocatorDumpsByFullName_[fullName];},iterateRootAllocatorDumps:function(fn,opt_this){if(this.memoryAllocatorDumps===undefined)
+return;this.memoryAllocatorDumps.forEach(fn,opt_this||this);}};return{ContainerMemoryDump:ContainerMemoryDump};});'use strict';tr.exportTo('tr.model',function(){function MemoryAllocatorDump(containerMemoryDump,fullName,opt_guid){this.fullName=fullName;this.parent=undefined;this.children=[];this.attributes={};this.containerMemoryDump=containerMemoryDump;this.owns=undefined;this.ownedBy=[];this.retains=[];this.retainedBy=[];this.guid=opt_guid;};MemoryAllocatorDump.SIZE_ATTRIBUTE_NAME='size';MemoryAllocatorDump.EFFECTIVE_SIZE_ATTRIBUTE_NAME='effective_size';MemoryAllocatorDump.DISPLAYED_SIZE_ATTRIBUTE_NAME=MemoryAllocatorDump.EFFECTIVE_SIZE_ATTRIBUTE_NAME;MemoryAllocatorDump.prototype={get name(){return this.fullName.substring(this.fullName.lastIndexOf('/')+1);},get quantifiedName(){return'\''+this.fullName+'\' in '+
+this.containerMemoryDump.containerName;},isDescendantOf:function(otherDump){var dump=this;while(dump!==undefined){if(dump===otherDump)
+return true;dump=dump.parent;}
+return false;},addAttribute:function(name,value){if(name in this.attributes)
+throw new Error('Duplicate attribute name: '+name+'.');this.attributes[name]=value;},aggregateAttributes:function(opt_model){var attributes={};this.children.forEach(function(child){child.aggregateAttributes(opt_model);tr.b.iterItems(child.attributes,function(name){attributes[name]=true;},this);},this);tr.b.iterItems(attributes,function(name){var childAttributes=this.children.map(function(child){return child.attributes[name];},this);var currentAttribute=this.attributes[name];this.attributes[name]=tr.model.Attribute.aggregate(childAttributes,currentAttribute,opt_model);},this);},getValidSizeAttributeOrUndefined:function(sizeAttrName,opt_model){var sizeAttr=this.attributes[sizeAttrName];if(sizeAttr===undefined)
+return undefined;if(!(sizeAttr instanceof tr.model.ScalarAttribute)){if(opt_model!==undefined){opt_model.importWarning({type:'memory_dump_parse_error',message:'\''+sizeAttrName+'\' attribute of memory allocator '+'dump \''+memoryAllocatorDump.fullName+'\' is not a scalar.'});}
+return undefined;}
+return sizeAttr;}};function MemoryAllocatorDumpLink(source,target,opt_importance){this.source=source;this.target=target;this.importance=opt_importance;}
+return{MemoryAllocatorDump:MemoryAllocatorDump,MemoryAllocatorDumpLink:MemoryAllocatorDumpLink};});'use strict';tr.exportTo('tr.model',function(){function GlobalMemoryDump(model,start){tr.model.ContainerMemoryDump.call(this,start);this.model=model;this.processMemoryDumps={};}
+var SIZE_ATTRIBUTE_NAME=tr.model.MemoryAllocatorDump.SIZE_ATTRIBUTE_NAME;var EFFECTIVE_SIZE_ATTRIBUTE_NAME=tr.model.MemoryAllocatorDump.EFFECTIVE_SIZE_ATTRIBUTE_NAME;function getSize(dump){var attr=dump.attributes[SIZE_ATTRIBUTE_NAME];if(attr===undefined)
+return 0;return attr.value;}
+function hasSize(dump){return dump.attributes[SIZE_ATTRIBUTE_NAME]!==undefined;}
+function optional(value,defaultValue){if(value===undefined)
+return defaultValue;return value;}
+function ownershipToUserFriendlyString(dump,importance){return dump.quantifiedName+' (importance: '+
+optional(importance,0)+')';}
+GlobalMemoryDump.prototype={__proto__:tr.model.ContainerMemoryDump.prototype,get userFriendlyName(){return'Global memory dump at '+tr.b.u.TimeStamp.format(this.start);},get containerName(){return'global space';},calculateGraphAttributes:function(){this.calculateSizes();this.calculateEffectiveSizes();this.aggregateAttributes();this.discountTracingOverhead();},calculateSizes:function(){this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateMemoryAllocatorDumpSize_.bind(this));},calculateMemoryAllocatorDumpSize_:function(dump){var shouldDefineSize=false;function getDependencySize(dependencyDump){var attr=dependencyDump.attributes[SIZE_ATTRIBUTE_NAME];if(attr===undefined)
+return 0;shouldDefineSize=true;return attr.value;}
+var sizeAttribute=dump.getValidSizeAttributeOrUndefined(SIZE_ATTRIBUTE_NAME,this.model);var size=0;var infos=[];var checkDependentSizeIsConsistent=function(){};if(sizeAttribute!==undefined){size=sizeAttribute.value;shouldDefineSize=true;checkDependentSizeIsConsistent=function(dependentSize,dependentName){if(size>=dependentSize)
+return;var messageSuffix=' ('+tr.b.u.Units.sizeInBytes.format(size)+') is less than '+dependentName+' ('+
+tr.b.u.Units.sizeInBytes.format(dependentSize)+').';this.model.importWarning({type:'memory_dump_parse_error',message:'Size provided by memory allocator dump \''+
+dump.fullName+'\''+messageSuffix});infos.push(new tr.model.AttributeInfo(tr.model.AttributeInfoType.WARNING,'Size provided by this memory allocator dump'+messageSuffix));}.bind(this);}
+var aggregatedChildrenSize=0;var allOverlaps={};dump.children.forEach(function(childDump){function aggregateDescendantDump(descendantDump){var ownedDumpLink=descendantDump.owns;if(ownedDumpLink!==undefined&&ownedDumpLink.target.isDescendantOf(dump)){var ownedDescendantDump=ownedDumpLink.target;var ownedChildDump=ownedDescendantDump;while(ownedChildDump.parent!==dump)
+ownedChildDump=ownedChildDump.parent;if(childDump!==ownedChildDump){var overlap=getDependencySize(descendantDump);if(overlap>0){var ownedChildOverlaps=allOverlaps[ownedChildDump.name];if(ownedChildOverlaps===undefined)
+allOverlaps[ownedChildDump.name]=ownedChildOverlaps={};var previousTotalOverlap=ownedChildOverlaps[childDump.name]||0;var updatedTotalOverlap=previousTotalOverlap+overlap;ownedChildOverlaps[childDump.name]=updatedTotalOverlap;}}
+return;}
+if(descendantDump.children.length===0){aggregatedChildrenSize+=getDependencySize(descendantDump);return;}
+descendantDump.children.forEach(aggregateDescendantDump);}
+aggregateDescendantDump(childDump);});dump.children.forEach(function(childDump){var childOverlaps=allOverlaps[childDump.name];if(childOverlaps===undefined)
+return;var message=tr.b.dictionaryValues(tr.b.mapItems(childOverlaps,function(ownerChildName,overlap){return'overlaps with its sibling \''+ownerChildName+'\' ('+
+tr.b.u.Units.sizeInBytes.format(overlap)+')';})).join(' ');childDump.attributes[SIZE_ATTRIBUTE_NAME].infos.push(new tr.model.AttributeInfo(tr.model.AttributeInfoType.INFORMATION,message));});checkDependentSizeIsConsistent(aggregatedChildrenSize,'the aggregated size of its children');var largestOwnerSize=0;dump.ownedBy.forEach(function(ownershipLink){var owner=ownershipLink.source;var ownerSize=getDependencySize(owner);largestOwnerSize=Math.max(largestOwnerSize,ownerSize);});checkDependentSizeIsConsistent(largestOwnerSize,'the size of its largest owner');if(!shouldDefineSize){dump.attributes[SIZE_ATTRIBUTE_NAME]=undefined;return;}
+size=Math.max(size,aggregatedChildrenSize,largestOwnerSize);var sizeAttribute=new tr.model.ScalarAttribute('bytes',size);sizeAttribute.infos=infos;dump.attributes[SIZE_ATTRIBUTE_NAME]=sizeAttribute;if(aggregatedChildrenSize<size&&dump.children!==undefined&&dump.children.length>0){var virtualChild=new tr.model.MemoryAllocatorDump(dump.containerMemoryDump,dump.fullName+'/<unspecified>');virtualChild.parent=dump;dump.children.unshift(virtualChild);virtualChild.attributes[SIZE_ATTRIBUTE_NAME]=new tr.model.ScalarAttribute('bytes',size-aggregatedChildrenSize);}},calculateEffectiveSizes:function(){this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateDumpSubSizes_.bind(this));this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateDumpOwnershipCoefficient_.bind(this));this.traverseAllocatorDumpsInDepthFirstPreOrder(this.calculateDumpCumulativeOwnershipCoefficient_.bind(this));this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateDumpEffectiveSize_.bind(this));},calculateDumpSubSizes_:function(dump){if(!hasSize(dump))
+return;if(dump.children===undefined||dump.children.length===0){var size=getSize(dump);dump.notOwningSubSize_=size;dump.notOwnedSubSize_=size;return;}
+var notOwningSubSize=0;dump.children.forEach(function(childDump){if(childDump.owns!==undefined)
+return;notOwningSubSize+=optional(childDump.notOwningSubSize_,0);});dump.notOwningSubSize_=notOwningSubSize;var notOwnedSubSize=0;dump.children.forEach(function(childDump){if(childDump.ownedBy.length===0){notOwnedSubSize+=optional(childDump.notOwnedSubSize_,0);return;}
+var largestChildOwnerSize=0;childDump.ownedBy.forEach(function(ownershipLink){largestChildOwnerSize=Math.max(largestChildOwnerSize,getSize(ownershipLink.source));});notOwnedSubSize+=getSize(childDump)-largestChildOwnerSize;});dump.notOwnedSubSize_=notOwnedSubSize;},calculateDumpOwnershipCoefficient_:function(dump){if(!hasSize(dump))
+return;if(dump.ownedBy.length===0)
+return;var owners=dump.ownedBy.map(function(ownershipLink){return{dump:ownershipLink.source,importance:optional(ownershipLink.importance,0),notOwningSubSize:optional(ownershipLink.source.notOwningSubSize_,0)};});owners.sort(function(a,b){if(a.importance===b.importance)
+return a.notOwningSubSize-b.notOwningSubSize;return b.importance-a.importance;});var currentImportanceStartPos=0;var alreadyAttributedSubSize=0;while(currentImportanceStartPos<owners.length){var currentImportance=owners[currentImportanceStartPos].importance;var nextImportanceStartPos=currentImportanceStartPos+1;while(nextImportanceStartPos<owners.length&&owners[nextImportanceStartPos].importance===currentImportance){nextImportanceStartPos++;}
+var attributedNotOwningSubSize=0;for(var pos=currentImportanceStartPos;pos<nextImportanceStartPos;pos++){var owner=owners[pos];var notOwningSubSize=owner.notOwningSubSize;if(notOwningSubSize>alreadyAttributedSubSize){attributedNotOwningSubSize+=(notOwningSubSize-alreadyAttributedSubSize)/(nextImportanceStartPos-pos);alreadyAttributedSubSize=notOwningSubSize;}
+var owningCoefficient=0;if(notOwningSubSize!==0)
+owningCoefficient=attributedNotOwningSubSize/notOwningSubSize;owner.dump.owningCoefficient_=owningCoefficient;}
+currentImportanceStartPos=nextImportanceStartPos;}
+var notOwnedSubSize=optional(dump.notOwnedSubSize_,0);var remainderSubSize=notOwnedSubSize-alreadyAttributedSubSize;var ownedCoefficient=0;if(notOwnedSubSize!==0)
+ownedCoefficient=remainderSubSize/notOwnedSubSize;dump.ownedCoefficient_=ownedCoefficient;},calculateDumpCumulativeOwnershipCoefficient_:function(dump){if(!hasSize(dump))
+return;var cumulativeOwnedCoefficient=optional(dump.ownedCoefficient_,1);var parent=dump.parent;if(dump.parent!==undefined)
+cumulativeOwnedCoefficient*=dump.parent.cumulativeOwnedCoefficient_;dump.cumulativeOwnedCoefficient_=cumulativeOwnedCoefficient;var cumulativeOwningCoefficient;if(dump.owns!==undefined){cumulativeOwningCoefficient=dump.owningCoefficient_*dump.owns.target.cumulativeOwningCoefficient_;}else if(dump.parent!==undefined){cumulativeOwningCoefficient=dump.parent.cumulativeOwningCoefficient_;}else{cumulativeOwningCoefficient=1;}
+dump.cumulativeOwningCoefficient_=cumulativeOwningCoefficient;},calculateDumpEffectiveSize_:function(dump){if(!hasSize(dump)){dump.attributes[EFFECTIVE_SIZE_ATTRIBUTE_NAME]=undefined;return;}
+var effectiveSize;if(dump.children===undefined||dump.children.length===0){effectiveSize=getSize(dump)*dump.cumulativeOwningCoefficient_*dump.cumulativeOwnedCoefficient_;}else{effectiveSize=0;dump.children.forEach(function(childDump){if(!hasSize(childDump))
+return;effectiveSize+=childDump.attributes[EFFECTIVE_SIZE_ATTRIBUTE_NAME].value;});}
+var attribute=new tr.model.ScalarAttribute('bytes',effectiveSize);dump.attributes[EFFECTIVE_SIZE_ATTRIBUTE_NAME]=attribute;if(dump.ownedBy.length>0){var message='shared by:'+
+dump.ownedBy.map(function(ownershipLink){return'\n  - '+ownershipToUserFriendlyString(ownershipLink.source,ownershipLink.importance);}).join();attribute.infos.push(new tr.model.AttributeInfo(tr.model.AttributeInfoType.MEMORY_OWNED,message));}
+if(dump.owns!==undefined){var target=dump.owns.target;var message='shares '+
+ownershipToUserFriendlyString(target,dump.owns.importance)+' with';var otherOwnershipLinks=target.ownedBy.filter(function(ownershipLink){return ownershipLink.source!==dump;});if(otherOwnershipLinks.length>0){message+=':';message+=otherOwnershipLinks.map(function(ownershipLink){return'\n  - '+ownershipToUserFriendlyString(ownershipLink.source,ownershipLink.importance);}).join();}else{message+=' no other dumps';}
+attribute.infos.push(new tr.model.AttributeInfo(tr.model.AttributeInfoType.MEMORY_OWNER,message));}},aggregateAttributes:function(){this.iterateRootAllocatorDumps(function(dump){dump.aggregateAttributes(this.model);});this.iterateRootAllocatorDumps(this.propagateAttributesRecursively);tr.b.iterItems(this.processMemoryDumps,function(pid,processMemoryDump){processMemoryDump.iterateRootAllocatorDumps(function(dump){dump.aggregateAttributes(this.model);},this);},this);},propagateAttributesRecursively:function(globalAllocatorDump){tr.b.iterItems(globalAllocatorDump.attributes,function(attrName,attr){if(attrName===SIZE_ATTRIBUTE_NAME||attrName===EFFECTIVE_SIZE_ATTRIBUTE_NAME){return;}
+globalAllocatorDump.ownedBy.forEach(function(ownershipLink){var processAllocatorDump=ownershipLink.source;if(processAllocatorDump.attributes[attrName]!==undefined){return;}
+processAllocatorDump.attributes[attrName]=attr;});});globalAllocatorDump.children.forEach(this.propagateAttributesRecursively,this);},discountTracingOverhead:function(){tr.b.iterItems(this.processMemoryDumps,function(pid,dump){dump.discountTracingOverhead(this.model);},this);},iterateContainerDumps:function(fn){fn.call(this,this);tr.b.iterItems(this.processMemoryDumps,function(pid,processDump){fn.call(this,processDump);},this);},iterateAllRootAllocatorDumps:function(fn){this.iterateContainerDumps(function(containerDump){containerDump.iterateRootAllocatorDumps(fn,this);});},traverseAllocatorDumpsInDepthFirstPostOrder:function(fn){var visitedDumps=new WeakSet();var openDumps=new WeakSet();function visit(dump){if(visitedDumps.has(dump))
+return;if(openDumps.has(dump))
+throw new Error(dump.userFriendlyName+' contains a cycle');openDumps.add(dump);dump.ownedBy.forEach(function(ownershipLink){visit.call(this,ownershipLink.source);},this);dump.children.forEach(visit,this);fn.call(this,dump);visitedDumps.add(dump);openDumps.delete(dump);}
+this.iterateAllRootAllocatorDumps(visit);},traverseAllocatorDumpsInDepthFirstPreOrder:function(fn){var visitedDumps=new WeakSet();function visit(dump){if(visitedDumps.has(dump))
+return;if(dump.owns!==undefined&&!visitedDumps.has(dump.owns.target))
+return;if(dump.parent!==undefined&&!visitedDumps.has(dump.parent))
+return;fn.call(this,dump);visitedDumps.add(dump);dump.ownedBy.forEach(function(ownershipLink){visit.call(this,ownershipLink.source);},this);dump.children.forEach(visit,this);}
+this.iterateAllRootAllocatorDumps(visit);}};tr.model.EventRegistry.register(GlobalMemoryDump,{name:'globalMemoryDump',pluralName:'globalMemoryDumps',singleViewElementName:'tr-ui-a-container-memory-dump-sub-view',multiViewElementName:'tr-ui-a-container-memory-dump-sub-view'});return{GlobalMemoryDump:GlobalMemoryDump};});'use strict';tr.exportTo('tr.model',function(){var InstantEventType={GLOBAL:1,PROCESS:2};function InstantEvent(category,title,colorId,start,args){tr.model.TimedEvent.call(this);this.category=category||'';this.title=title;this.colorId=colorId;this.start=start;this.args=args;this.type=undefined;};InstantEvent.prototype={__proto__:tr.model.TimedEvent.prototype};function GlobalInstantEvent(category,title,colorId,start,args){InstantEvent.apply(this,arguments);this.type=InstantEventType.GLOBAL;};GlobalInstantEvent.prototype={__proto__:InstantEvent.prototype,get userFriendlyName(){return'Global instant event '+this.title+' @ '+
+tr.b.u.TimeStamp.format(start);}};function ProcessInstantEvent(category,title,colorId,start,args){InstantEvent.apply(this,arguments);this.type=InstantEventType.PROCESS;};ProcessInstantEvent.prototype={__proto__:InstantEvent.prototype,get userFriendlyName(){return'Process-level instant event '+this.title+' @ '+
+tr.b.u.TimeStamp.format(start);}};tr.model.EventRegistry.register(InstantEvent,{name:'instantEvent',pluralName:'instantEvents',singleViewElementName:'tr-ui-a-single-instant-event-sub-view',multiViewElementName:'tr-ui-a-multi-instant-event-sub-view'});return{GlobalInstantEvent:GlobalInstantEvent,ProcessInstantEvent:ProcessInstantEvent,InstantEventType:InstantEventType,InstantEvent:InstantEvent};});'use strict';tr.exportTo('tr.model',function(){var CompoundEventSelectionState={NOT_SELECTED:0,EVENT_SELECTED:0x1,SOME_ASSOCIATED_EVENTS_SELECTED:0x2,ALL_ASSOCIATED_EVENTS_SELECTED:0x4,EVENT_AND_SOME_ASSOCIATED_SELECTED:0x1|0x2,EVENT_AND_ALL_ASSOCIATED_SELECTED:0x1|0x4};return{CompoundEventSelectionState:CompoundEventSelectionState};});'use strict';tr.exportTo('tr.model',function(){var CompoundEventSelectionState=tr.model.CompoundEventSelectionState;function InteractionRecord(parentModel,title,colorId,start,duration){tr.model.TimedEvent.call(this,start);this.title=title;this.colorId=colorId;this.duration=duration;this.args={};this.associatedEvents=new tr.model.EventSet();this.parentModel=parentModel;this.sourceEvents=new tr.model.EventSet();}
+InteractionRecord.prototype={__proto__:tr.model.TimedEvent.prototype,get subSlices(){return[];},get userFriendlyName(){return this.title+' interaction at '+
+tr.b.u.TimeStamp.format(this.start);},get stableId(){return'IR.'+this.parentModel.interactionRecords.indexOf(this);},computeCompoundEvenSelectionState:function(selection){var cess=CompoundEventSelectionState.NOT_SELECTED;if(selection.contains(this))
+cess|=CompoundEventSelectionState.EVENT_SELECTED;if(this.associatedEvents.intersectionIsEmpty(selection))
+return cess;var allContained=this.associatedEvents.every(function(event){return selection.contains(event);});if(allContained)
+cess|=CompoundEventSelectionState.ALL_ASSOCIATED_EVENTS_SELECTED;else
+cess|=CompoundEventSelectionState.SOME_ASSOCIATED_EVENTS_SELECTED;return cess;}};tr.model.EventRegistry.register(InteractionRecord,{name:'interaction',pluralName:'interactions',singleViewElementName:'tr-ui-a-single-interaction-record-sub-view',multiViewElementName:'tr-ui-a-multi-interaction-record-sub-view'});return{InteractionRecord:InteractionRecord};});'use strict';tr.exportTo('tr.b',function(){function findLowIndexInSortedArray(ary,mapFn,loVal){if(ary.length==0)
+return 1;var low=0;var high=ary.length-1;var i,comparison;var hitPos=-1;while(low<=high){i=Math.floor((low+high)/2);comparison=mapFn(ary[i])-loVal;if(comparison<0){low=i+1;continue;}else if(comparison>0){high=i-1;continue;}else{hitPos=i;high=i-1;}}
+return hitPos!=-1?hitPos:low;}
+function findHighIndexInSortedArray(ary,mapFn,loVal,hiVal){var lo=loVal||0;var hi=hiVal!==undefined?hiVal:ary.length;while(lo<hi){var mid=(lo+hi)>>1;if(mapFn(ary[mid])>=0)
+lo=mid+1;else
+hi=mid;}
+return hi;}
+function findIndexInSortedIntervals(ary,mapLoFn,mapWidthFn,loVal){var first=findLowIndexInSortedArray(ary,mapLoFn,loVal);if(first==0){if(loVal>=mapLoFn(ary[0])&&loVal<mapLoFn(ary[0])+mapWidthFn(ary[0],0)){return 0;}else{return-1;}}else if(first<ary.length){if(loVal>=mapLoFn(ary[first])&&loVal<mapLoFn(ary[first])+mapWidthFn(ary[first],first)){return first;}else if(loVal>=mapLoFn(ary[first-1])&&loVal<mapLoFn(ary[first-1])+
+mapWidthFn(ary[first-1],first-1)){return first-1;}else{return ary.length;}}else if(first==ary.length){if(loVal>=mapLoFn(ary[first-1])&&loVal<mapLoFn(ary[first-1])+
+mapWidthFn(ary[first-1],first-1)){return first-1;}else{return ary.length;}}else{return ary.length;}}
+function findIndexInSortedClosedIntervals(ary,mapLoFn,mapHiFn,val){var i=findLowIndexInSortedArray(ary,mapLoFn,val);if(i===0){if(val>=mapLoFn(ary[0],0)&&val<=mapHiFn(ary[0],0)){return 0;}else{return-1;}}else if(i<ary.length){if(val>=mapLoFn(ary[i-1],i-1)&&val<=mapHiFn(ary[i-1],i-1)){return i-1;}else if(val>=mapLoFn(ary[i],i)&&val<=mapHiFn(ary[i],i)){return i;}else{return ary.length;}}else if(i==ary.length){if(val>=mapLoFn(ary[i-1],i-1)&&val<=mapHiFn(ary[i-1],i-1)){return i-1;}else{return ary.length;}}else{return ary.length;}}
+function iterateOverIntersectingIntervals(ary,mapLoFn,mapWidthFn,loVal,hiVal,cb){if(ary.length==0)
+return;if(loVal>hiVal)return;var i=findLowIndexInSortedArray(ary,mapLoFn,loVal);if(i==-1){return;}
+if(i>0){var hi=mapLoFn(ary[i-1])+mapWidthFn(ary[i-1],i-1);if(hi>=loVal){cb(ary[i-1],i-1);}}
+if(i==ary.length){return;}
+for(var n=ary.length;i<n;i++){var lo=mapLoFn(ary[i]);if(lo>=hiVal)
+break;cb(ary[i],i);}}
+function getIntersectingIntervals(ary,mapLoFn,mapWidthFn,loVal,hiVal){var tmp=[];iterateOverIntersectingIntervals(ary,mapLoFn,mapWidthFn,loVal,hiVal,function(d){tmp.push(d);});return tmp;}
+function findClosestElementInSortedArray(ary,mapFn,val,maxDiff){if(ary.length===0)
+return null;var aftIdx=findLowIndexInSortedArray(ary,mapFn,val);var befIdx=aftIdx>0?aftIdx-1:0;if(aftIdx===ary.length)
+aftIdx-=1;var befDiff=Math.abs(val-mapFn(ary[befIdx]));var aftDiff=Math.abs(val-mapFn(ary[aftIdx]));if(befDiff>maxDiff&&aftDiff>maxDiff)
+return null;var idx=befDiff<aftDiff?befIdx:aftIdx;return ary[idx];}
+function findClosestIntervalInSortedIntervals(ary,mapLoFn,mapHiFn,val,maxDiff){if(ary.length===0)
+return null;var idx=findLowIndexInSortedArray(ary,mapLoFn,val);if(idx>0)
+idx-=1;var hiInt=ary[idx];var loInt=hiInt;if(val>mapHiFn(hiInt)&&idx+1<ary.length)
+loInt=ary[idx+1];var loDiff=Math.abs(val-mapLoFn(loInt));var hiDiff=Math.abs(val-mapHiFn(hiInt));if(loDiff>maxDiff&&hiDiff>maxDiff)
+return null;if(loDiff<hiDiff)
+return loInt;else
+return hiInt;}
+return{findLowIndexInSortedArray:findLowIndexInSortedArray,findHighIndexInSortedArray:findHighIndexInSortedArray,findIndexInSortedIntervals:findIndexInSortedIntervals,findIndexInSortedClosedIntervals:findIndexInSortedClosedIntervals,iterateOverIntersectingIntervals:iterateOverIntersectingIntervals,getIntersectingIntervals:getIntersectingIntervals,findClosestElementInSortedArray:findClosestElementInSortedArray,findClosestIntervalInSortedIntervals:findClosestIntervalInSortedIntervals};});'use strict';tr.exportTo('tr.model',function(){function CounterSample(series,timestamp,value){tr.model.Event.call(this);this.series_=series;this.timestamp_=timestamp;this.value_=value;}
+CounterSample.groupByTimestamp=function(samples){var samplesByTimestamp=tr.b.group(samples,function(sample){return sample.timestamp;});var timestamps=tr.b.dictionaryKeys(samplesByTimestamp);timestamps.sort();var groups=[];for(var i=0;i<timestamps.length;i++){var ts=timestamps[i];var group=samplesByTimestamp[ts];group.sort(function(x,y){return x.series.seriesIndex-y.series.seriesIndex;});groups.push(group);}
+return groups;}
+CounterSample.prototype={__proto__:tr.model.Event.prototype,get series(){return this.series_;},get timestamp(){return this.timestamp_;},get value(){return this.value_;},set timestamp(timestamp){this.timestamp_=timestamp;},addBoundsToRange:function(range){range.addValue(this.timestamp);},getSampleIndex:function(){return tr.b.findLowIndexInSortedArray(this.series.timestamps,function(x){return x;},this.timestamp_);},get userFriendlyName(){return'Counter sample from '+this.series_.title+' at '+
+tr.b.u.TimeStamp.format(this.timestamp);}};tr.model.EventRegistry.register(CounterSample,{name:'counterSample',pluralName:'counterSamples',singleViewElementName:'tr-ui-a-counter-sample-sub-view',multiViewElementName:'tr-ui-a-counter-sample-sub-view'});return{CounterSample:CounterSample};});'use strict';tr.exportTo('tr.model',function(){var CounterSample=tr.model.CounterSample;function CounterSeries(name,color){tr.model.EventContainer.call(this);this.name_=name;this.color_=color;this.timestamps_=[];this.samples_=[];this.counter=undefined;this.seriesIndex=undefined;}
+CounterSeries.prototype={__proto__:tr.model.EventContainer.prototype,get length(){return this.timestamps_.length;},get name(){return this.name_;},get color(){return this.color_;},get samples(){return this.samples_;},get timestamps(){return this.timestamps_;},getSample:function(idx){return this.samples_[idx];},getTimestamp:function(idx){return this.timestamps_[idx];},addCounterSample:function(ts,val){var sample=new CounterSample(this,ts,val);this.addSample(sample);return sample;},addSample:function(sample){this.timestamps_.push(sample.timestamp);this.samples_.push(sample);},getStatistics:function(sampleIndices){var sum=0;var min=Number.MAX_VALUE;var max=-Number.MAX_VALUE;for(var i=0;i<sampleIndices.length;++i){var sample=this.getSample(sampleIndices[i]).value;sum+=sample;min=Math.min(sample,min);max=Math.max(sample,max);}
+return{min:min,max:max,avg:(sum/sampleIndices.length),start:this.getSample(sampleIndices[0]).value,end:this.getSample(sampleIndices.length-1).value};},shiftTimestampsForward:function(amount){for(var i=0;i<this.timestamps_.length;++i){this.timestamps_[i]+=amount;this.samples_[i].timestamp=this.timestamps_[i];}},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,tr.model.CounterSample)){this.samples_.forEach(callback,opt_this);}},iterateAllChildEventContainers:function(callback,opt_this){}};return{CounterSeries:CounterSeries};});'use strict';tr.exportTo('tr.model',function(){function Counter(parent,id,category,name){tr.model.EventContainer.call(this);this.parent_=parent;this.id_=id;this.category_=category||'';this.name_=name;this.series_=[];this.totals=[];}
+Counter.prototype={__proto__:tr.model.EventContainer.prototype,get parent(){return this.parent_;},get id(){return this.id_;},get category(){return this.category_;},get name(){return this.name_;},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){},iterateAllChildEventContainers:function(callback,opt_this){for(var i=0;i<this.series_.length;i++)
+callback.call(opt_this,this.series_[i]);},set timestamps(arg){throw new Error('Bad counter API. No cookie.');},set seriesNames(arg){throw new Error('Bad counter API. No cookie.');},set seriesColors(arg){throw new Error('Bad counter API. No cookie.');},set samples(arg){throw new Error('Bad counter API. No cookie.');},addSeries:function(series){series.counter=this;series.seriesIndex=this.series_.length;this.series_.push(series);return series;},getSeries:function(idx){return this.series_[idx];},get series(){return this.series_;},get numSeries(){return this.series_.length;},get numSamples(){if(this.series_.length===0)
+return 0;return this.series_[0].length;},get timestamps(){if(this.series_.length===0)
+return[];return this.series_[0].timestamps;},getSampleStatistics:function(sampleIndices){sampleIndices.sort();var ret=[];this.series_.forEach(function(series){ret.push(series.getStatistics(sampleIndices));});return ret;},shiftTimestampsForward:function(amount){for(var i=0;i<this.series_.length;++i)
+this.series_[i].shiftTimestampsForward(amount);},updateBounds:function(){this.totals=[];this.maxTotal=0;this.bounds.reset();if(this.series_.length===0)
+return;var firstSeries=this.series_[0];var lastSeries=this.series_[this.series_.length-1];this.bounds.addValue(firstSeries.getTimestamp(0));this.bounds.addValue(lastSeries.getTimestamp(lastSeries.length-1));var numSeries=this.numSeries;this.maxTotal=-Infinity;for(var i=0;i<firstSeries.length;++i){var total=0;this.series_.forEach(function(series){total+=series.getSample(i).value;this.totals.push(total);}.bind(this));this.maxTotal=Math.max(total,this.maxTotal);}}};Counter.compare=function(x,y){var tmp=x.parent.compareTo(y);if(tmp!=0)
+return tmp;var tmp=x.name.localeCompare(y.name);if(tmp==0)
+return x.tid-y.tid;return tmp;};return{Counter:Counter};});'use strict';tr.exportTo('tr.model',function(){function Slice(category,title,colorId,start,args,opt_duration,opt_cpuStart,opt_cpuDuration,opt_argsStripped,opt_bind_id){tr.model.TimedEvent.call(this,start);this.category=category||'';this.title=title;this.colorId=colorId;this.args=args;this.startStackFrame=undefined;this.endStackFrame=undefined;this.didNotFinish=false;this.inFlowEvents=[];this.outFlowEvents=[];this.subSlices=[];this.selfTime=undefined;this.cpuSelfTime=undefined;this.important=false;this.parentContainer=undefined;this.argsStripped=false;this.bind_id_=opt_bind_id;this.parentSlice=undefined;this.isTopLevel=false;if(opt_duration!==undefined)
+this.duration=opt_duration;if(opt_cpuStart!==undefined)
+this.cpuStart=opt_cpuStart;if(opt_cpuDuration!==undefined)
+this.cpuDuration=opt_cpuDuration;if(opt_argsStripped!==undefined)
+this.argsStripped=true;}
+Slice.prototype={__proto__:tr.model.TimedEvent.prototype,get analysisTypeName(){return this.title;},get userFriendlyName(){return'Slice '+this.title+' at '+
+tr.b.u.TimeStamp.format(this.start);},get stableId(){var parentSliceGroup=this.parentContainer.sliceGroup;return parentSliceGroup.stableId+'.'+
+parentSliceGroup.slices.indexOf(this);},findDescendentSlice:function(targetTitle){if(!this.subSlices)
+return undefined;for(var i=0;i<this.subSlices.length;i++){if(this.subSlices[i].title==targetTitle)
+return this.subSlices[i];var slice=this.subSlices[i].findDescendentSlice(targetTitle);if(slice)return slice;}
+return undefined;},get mostTopLevelSlice(){var curSlice=this;while(curSlice.parentSlice)
+curSlice=curSlice.parentSlice;return curSlice;},iterateAllSubsequentSlices:function(callback,opt_this){var parentStack=[];var started=false;var topmostSlice=this.mostTopLevelSlice;parentStack.push(topmostSlice);while(parentStack.length!==0){var curSlice=parentStack.pop();if(started)
+callback.call(opt_this,curSlice);else
+started=(curSlice.guid===this.guid);for(var i=curSlice.subSlices.length-1;i>=0;i--){parentStack.push(curSlice.subSlices[i]);}}},get subsequentSlices(){var res=[];this.iterateAllSubsequentSlices(function(subseqSlice){res.push(subseqSlice);});return res;},iterateAllAncestors:function(callback,opt_this){var curSlice=this;while(curSlice.parentSlice){curSlice=curSlice.parentSlice;callback.call(opt_this,curSlice);}},get ancestorSlices(){var res=[];this.iterateAllAncestors(function(ancestor){res.push(ancestor);});return res;},iterateEntireHierarchy:function(callback,opt_this){var mostTopLevelSlice=this.mostTopLevelSlice;callback.call(opt_this,mostTopLevelSlice);mostTopLevelSlice.iterateAllSubsequentSlices(callback,opt_this);},get entireHierarchy(){var res=[];this.iterateEntireHierarchy(function(slice){res.push(slice);});return res;},get ancestorAndSubsequentSlices(){var res=[];res.push(this);this.iterateAllAncestors(function(aSlice){res.push(aSlice);});this.iterateAllSubsequentSlices(function(sSlice){res.push(sSlice);});return res;},iterateAllDescendents:function(callback,opt_this){this.subSlices.forEach(callback,opt_this);this.subSlices.forEach(function(subSlice){subSlice.iterateAllDescendents(callback,opt_this);},opt_this);},get descendentSlices(){var res=[];this.iterateAllDescendents(function(des){res.push(des);});return res;}};return{Slice:Slice};});'use strict';tr.exportTo('tr.model',function(){var Slice=tr.model.Slice;var SCHEDULING_STATE={DEBUG:'Debug',EXIT_DEAD:'Exit Dead',RUNNABLE:'Runnable',RUNNING:'Running',SLEEPING:'Sleeping',STOPPED:'Stopped',TASK_DEAD:'Task Dead',UNINTR_SLEEP:'Uninterruptible Sleep',UNINTR_SLEEP_WAKE_KILL:'Uninterruptible Sleep | WakeKill',UNINTR_SLEEP_WAKING:'Uninterruptible Sleep | Waking',UNKNOWN:'UNKNOWN',WAKE_KILL:'Wakekill',WAKING:'Waking',ZOMBIE:'Zombie'};function ThreadTimeSlice(thread,schedulingState,cat,start,args,opt_duration){Slice.call(this,cat,schedulingState,this.getColorForState_(schedulingState),start,args,opt_duration);this.thread=thread;this.schedulingState=schedulingState;this.cpuOnWhichThreadWasRunning=undefined;}
+ThreadTimeSlice.prototype={__proto__:Slice.prototype,getColorForState_:function(state){var getColorIdForReservedName=tr.b.ColorScheme.getColorIdForReservedName;switch(state){case SCHEDULING_STATE.RUNNABLE:return getColorIdForReservedName('thread_state_runnable');case SCHEDULING_STATE.RUNNING:return getColorIdForReservedName('thread_state_running');case SCHEDULING_STATE.SLEEPING:return getColorIdForReservedName('thread_state_sleeping');case SCHEDULING_STATE.DEBUG:case SCHEDULING_STATE.EXIT_DEAD:case SCHEDULING_STATE.STOPPED:case SCHEDULING_STATE.TASK_DEAD:case SCHEDULING_STATE.UNINTR_SLEEP:case SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL:case SCHEDULING_STATE.UNINTR_SLEEP_WAKING:case SCHEDULING_STATE.UNKNOWN:case SCHEDULING_STATE.WAKE_KILL:case SCHEDULING_STATE.WAKING:case SCHEDULING_STATE.ZOMBIE:return getColorIdForReservedName('thread_state_iowait');default:return getColorIdForReservedName('thread_state_unknown');}},get analysisTypeName(){return'tr.ui.analysis.ThreadTimeSlice';},getAssociatedCpuSlice:function(){if(!this.cpuOnWhichThreadWasRunning)
+return undefined;var cpuSlices=this.cpuOnWhichThreadWasRunning.slices;for(var i=0;i<cpuSlices.length;i++){var cpuSlice=cpuSlices[i];if(cpuSlice.start!==this.start)
+continue;if(cpuSlice.duration!==this.duration)
+continue;return cpuSlice;}
+return undefined;},getCpuSliceThatTookCpu:function(){if(this.cpuOnWhichThreadWasRunning)
+return undefined;var curIndex=this.thread.indexOfTimeSlice(this);var cpuSliceWhenLastRunning;while(curIndex>=0){var curSlice=this.thread.timeSlices[curIndex];if(!curSlice.cpuOnWhichThreadWasRunning){curIndex--;continue;}
+cpuSliceWhenLastRunning=curSlice.getAssociatedCpuSlice();break;}
+if(!cpuSliceWhenLastRunning)
+return undefined;var cpu=cpuSliceWhenLastRunning.cpu;var indexOfSliceOnCpuWhenLastRunning=cpu.indexOf(cpuSliceWhenLastRunning);var nextRunningSlice=cpu.slices[indexOfSliceOnCpuWhenLastRunning+1];if(!nextRunningSlice)
+return undefined;if(Math.abs(nextRunningSlice.start-cpuSliceWhenLastRunning.end)<0.00001)
+return nextRunningSlice;return undefined;}};tr.model.EventRegistry.register(ThreadTimeSlice,{name:'threadTimeSlice',pluralName:'threadTimeSlices',singleViewElementName:'tr-ui-a-single-thread-time-slice-sub-view',multiViewElementName:'tr-ui-a-multi-thread-time-slice-sub-view'});return{ThreadTimeSlice:ThreadTimeSlice,SCHEDULING_STATE:SCHEDULING_STATE};});'use strict';tr.exportTo('tr.model',function(){var Slice=tr.model.Slice;function CpuSlice(cat,title,colorId,start,args,opt_duration){Slice.apply(this,arguments);this.threadThatWasRunning=undefined;this.cpu=undefined;}
+CpuSlice.prototype={__proto__:Slice.prototype,get analysisTypeName(){return'tr.ui.analysis.CpuSlice';},getAssociatedTimeslice:function(){if(!this.threadThatWasRunning)
+return undefined;var timeSlices=this.threadThatWasRunning.timeSlices;for(var i=0;i<timeSlices.length;i++){var timeSlice=timeSlices[i];if(timeSlice.start!==this.start)
+continue;if(timeSlice.duration!==this.duration)
+continue;return timeSlice;}
+return undefined;}};tr.model.EventRegistry.register(CpuSlice,{name:'cpuSlice',pluralName:'cpuSlices',singleViewElementName:'tr-ui-a-single-cpu-slice-sub-view',multiViewElementName:'tr-ui-a-multi-cpu-slice-sub-view'});return{CpuSlice:CpuSlice};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;var Counter=tr.model.Counter;var CpuSlice=tr.model.CpuSlice;var Slice=tr.model.Slice;function Cpu(kernel,number){if(kernel===undefined||number===undefined)
+throw new Error('Missing arguments');this.kernel=kernel;this.cpuNumber=number;this.slices=[];this.counters={};this.bounds=new tr.b.Range();this.samples_=undefined;this.lastActiveTimestamp_=undefined;this.lastActiveThread_=undefined;this.lastActiveName_=undefined;this.lastActiveArgs_=undefined;};Cpu.prototype={get samples(){return this.samples_;},get userFriendlyName(){return'CPU '+this.cpuNumber;},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,tr.model.CpuSlice))
+this.slices.forEach(callback,opt_this);if(this.samples_){if(eventTypePredicate.call(opt_this,tr.model.Sample))
+this.samples_.forEach(callback,opt_this);}},iterateAllChildEventContainers:function(callback,opt_this){for(var id in this.counters)
+callback.call(opt_this,this.counters[id]);},getOrCreateCounter:function(cat,name){var id=cat+'.'+name;if(!this.counters[id])
+this.counters[id]=new Counter(this,id,cat,name);return this.counters[id];},getCounter:function(cat,name){var id=cat+'.'+name;if(!this.counters[id])
+return undefined;return this.counters[id];},shiftTimestampsForward:function(amount){for(var sI=0;sI<this.slices.length;sI++)
+this.slices[sI].start=(this.slices[sI].start+amount);for(var id in this.counters)
+this.counters[id].shiftTimestampsForward(amount);},updateBounds:function(){this.bounds.reset();if(this.slices.length){this.bounds.addValue(this.slices[0].start);this.bounds.addValue(this.slices[this.slices.length-1].end);}
+for(var id in this.counters){this.counters[id].updateBounds();this.bounds.addRange(this.counters[id].bounds);}
+if(this.samples_&&this.samples_.length){this.bounds.addValue(this.samples_[0].start);this.bounds.addValue(this.samples_[this.samples_.length-1].end);}},createSubSlices:function(){this.samples_=this.kernel.model.samples.filter(function(sample){return sample.cpu==this;},this);},addCategoriesToDict:function(categoriesDict){for(var i=0;i<this.slices.length;i++)
+categoriesDict[this.slices[i].category]=true;for(var id in this.counters)
+categoriesDict[this.counters[id].category]=true;for(var i=0;i<this.samples_.length;i++)
+categoriesDict[this.samples_[i].category]=true;},indexOf:function(cpuSlice){var i=tr.b.findLowIndexInSortedArray(this.slices,function(slice){return slice.start;},cpuSlice.start);if(this.slices[i]!==cpuSlice)
+return undefined;return i;},closeActiveThread:function(end_timestamp,args){if(this.lastActiveThread_==undefined||this.lastActiveThread_==0)
+return;if(end_timestamp<this.lastActiveTimestamp_){throw new Error('The end timestamp of a thread running on CPU '+
+this.cpuNumber+' is before its start timestamp.');}
+for(var key in args){this.lastActiveArgs_[key]=args[key];}
+var duration=end_timestamp-this.lastActiveTimestamp_;var slice=new tr.model.CpuSlice('',this.lastActiveName_,ColorScheme.getColorIdForGeneralPurposeString(this.lastActiveName_),this.lastActiveTimestamp_,this.lastActiveArgs_,duration);slice.cpu=this;this.slices.push(slice);this.lastActiveTimestamp_=undefined;this.lastActiveThread_=undefined;this.lastActiveName_=undefined;this.lastActiveArgs_=undefined;},switchActiveThread:function(timestamp,old_thread_args,new_thread_id,new_thread_name,new_thread_args){this.closeActiveThread(timestamp,old_thread_args);this.lastActiveTimestamp_=timestamp;this.lastActiveThread_=new_thread_id;this.lastActiveName_=new_thread_name;this.lastActiveArgs_=new_thread_args;},getFreqStatsForRange:function(range){var stats={};function addStatsForFreq(freqSample,index){var freqEnd=(index<freqSample.series_.length-1)?freqSample.series_.samples_[index+1].timestamp:range.max;var freqRange=tr.b.Range.fromExplicitRange(freqSample.timestamp,freqEnd);var intersection=freqRange.findIntersection(range);if(!(freqSample.value in stats))
+stats[freqSample.value]=0;stats[freqSample.value]+=intersection.duration;}
+var freqCounter=this.getCounter('','Clock Frequency');if(freqCounter!==undefined){var freqSeries=freqCounter.getSeries(0);if(!freqSeries)
+return;tr.b.iterateOverIntersectingIntervals(freqSeries.samples_,function(x){return x.timestamp;},function(x,index){return index<freqSeries.length-1?freqSeries.samples_[index+1].timestamp:range.max;},range.min,range.max,addStatsForFreq);}
+return stats;}};Cpu.compare=function(x,y){return x.cpuNumber-y.cpuNumber;};return{Cpu:Cpu};});'use strict';tr.exportTo('tr.model',function(){function ObjectSnapshot(objectInstance,ts,args){tr.model.Event.call(this);this.objectInstance=objectInstance;this.ts=ts;this.args=args;}
+ObjectSnapshot.prototype={__proto__:tr.model.Event.prototype,preInitialize:function(){},initialize:function(){},addBoundsToRange:function(range){range.addValue(this.ts);},get userFriendlyName(){return'Snapshot of '+
+this.objectInstance.typeName+' '+
+this.objectInstance.id+' @ '+
+tr.b.u.TimeStamp.format(this.ts);}};tr.model.EventRegistry.register(ObjectSnapshot,{name:'objectSnapshot',pluralName:'objectSnapshots',singleViewElementName:'tr-ui-a-single-object-snapshot-sub-view',multiViewElementName:'tr-ui-a-multi-object-sub-view'});var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectSnapshot;options.defaultConstructor=ObjectSnapshot;tr.b.decorateExtensionRegistry(ObjectSnapshot,options);return{ObjectSnapshot:ObjectSnapshot};});'use strict';tr.exportTo('tr.model',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function ObjectInstance(parent,id,category,name,creationTs,opt_baseTypeName){tr.model.Event.call(this);this.parent=parent;this.id=id;this.category=category;this.baseTypeName=opt_baseTypeName?opt_baseTypeName:name;this.name=name;this.creationTs=creationTs;this.creationTsWasExplicit=false;this.deletionTs=Number.MAX_VALUE;this.deletionTsWasExplicit=false;this.colorId=0;this.bounds=new tr.b.Range();this.snapshots=[];this.hasImplicitSnapshots=false;}
+ObjectInstance.prototype={__proto__:tr.model.Event.prototype,get typeName(){return this.name;},addBoundsToRange:function(range){range.addRange(this.bounds);},addSnapshot:function(ts,args,opt_name,opt_baseTypeName){if(ts<this.creationTs)
+throw new Error('Snapshots must be >= instance.creationTs');if(ts>=this.deletionTs)
+throw new Error('Snapshots cannot be added after '+'an objects deletion timestamp.');var lastSnapshot;if(this.snapshots.length>0){lastSnapshot=this.snapshots[this.snapshots.length-1];if(lastSnapshot.ts==ts)
+throw new Error('Snapshots already exists at this time!');if(ts<lastSnapshot.ts){throw new Error('Snapshots must be added in increasing timestamp order');}}
+if(opt_name&&(this.name!=opt_name)){if(!opt_baseTypeName)
+throw new Error('Must provide base type name for name update');if(this.baseTypeName!=opt_baseTypeName)
+throw new Error('Cannot update type name: base types dont match');this.name=opt_name;}
+var snapshotConstructor=tr.model.ObjectSnapshot.getConstructor(this.category,this.name);var snapshot=new snapshotConstructor(this,ts,args);this.snapshots.push(snapshot);return snapshot;},wasDeleted:function(ts){var lastSnapshot;if(this.snapshots.length>0){lastSnapshot=this.snapshots[this.snapshots.length-1];if(lastSnapshot.ts>ts)
+throw new Error('Instance cannot be deleted at ts='+
+ts+'. A snapshot exists that is older.');}
+this.deletionTs=ts;this.deletionTsWasExplicit=true;},preInitialize:function(){for(var i=0;i<this.snapshots.length;i++)
+this.snapshots[i].preInitialize();},initialize:function(){for(var i=0;i<this.snapshots.length;i++)
+this.snapshots[i].initialize();},getSnapshotAt:function(ts){if(ts<this.creationTs){if(this.creationTsWasExplicit)
+throw new Error('ts must be within lifetime of this instance');return this.snapshots[0];}
+if(ts>this.deletionTs)
+throw new Error('ts must be within lifetime of this instance');var snapshots=this.snapshots;var i=tr.b.findIndexInSortedIntervals(snapshots,function(snapshot){return snapshot.ts;},function(snapshot,i){if(i==snapshots.length-1)
+return snapshots[i].objectInstance.deletionTs;return snapshots[i+1].ts-snapshots[i].ts;},ts);if(i<0){return this.snapshots[0];}
+if(i>=this.snapshots.length)
+return this.snapshots[this.snapshots.length-1];return this.snapshots[i];},updateBounds:function(){this.bounds.reset();this.bounds.addValue(this.creationTs);if(this.deletionTs!=Number.MAX_VALUE)
+this.bounds.addValue(this.deletionTs);else if(this.snapshots.length>0)
+this.bounds.addValue(this.snapshots[this.snapshots.length-1].ts);},shiftTimestampsForward:function(amount){this.creationTs+=amount;if(this.deletionTs!=Number.MAX_VALUE)
+this.deletionTs+=amount;this.snapshots.forEach(function(snapshot){snapshot.ts+=amount;});},get userFriendlyName(){return this.typeName+' object '+this.id;}};tr.model.EventRegistry.register(ObjectInstance,{name:'objectInstance',pluralName:'objectInstances',singleViewElementName:'tr-ui-a-single-object-instance-sub-view',multiViewElementName:'tr-ui-a-multi-object-sub-view'});var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectInstance;options.defaultConstructor=ObjectInstance;tr.b.decorateExtensionRegistry(ObjectInstance,options);return{ObjectInstance:ObjectInstance};});'use strict';tr.exportTo('tr.model',function(){function TimeToObjectInstanceMap(createObjectInstanceFunction,parent,id){this.createObjectInstanceFunction_=createObjectInstanceFunction;this.parent=parent;this.id=id;this.instances=[];}
+TimeToObjectInstanceMap.prototype={idWasCreated:function(category,name,ts){if(this.instances.length==0){this.instances.push(this.createObjectInstanceFunction_(this.parent,this.id,category,name,ts));this.instances[0].creationTsWasExplicit=true;return this.instances[0];}
+var lastInstance=this.instances[this.instances.length-1];if(ts<lastInstance.deletionTs){throw new Error('Mutation of the TimeToObjectInstanceMap must be '+'done in ascending timestamp order.');}
+lastInstance=this.createObjectInstanceFunction_(this.parent,this.id,category,name,ts);lastInstance.creationTsWasExplicit=true;this.instances.push(lastInstance);return lastInstance;},addSnapshot:function(category,name,ts,args,opt_baseTypeName){if(this.instances.length==0){this.instances.push(this.createObjectInstanceFunction_(this.parent,this.id,category,name,ts,opt_baseTypeName));}
+var i=tr.b.findIndexInSortedIntervals(this.instances,function(inst){return inst.creationTs;},function(inst){return inst.deletionTs-inst.creationTs;},ts);var instance;if(i<0){instance=this.instances[0];if(ts>instance.deletionTs||instance.creationTsWasExplicit){throw new Error('At the provided timestamp, no instance was still alive');}
+if(instance.snapshots.length!=0){throw new Error('Cannot shift creationTs forward, '+'snapshots have been added. First snap was at ts='+
+instance.snapshots[0].ts+' and creationTs was '+
+instance.creationTs);}
+instance.creationTs=ts;}else if(i>=this.instances.length){instance=this.instances[this.instances.length-1];if(ts>=instance.deletionTs){instance=this.createObjectInstanceFunction_(this.parent,this.id,category,name,ts,opt_baseTypeName);this.instances.push(instance);}else{var lastValidIndex;for(var i=this.instances.length-1;i>=0;i--){var tmp=this.instances[i];if(ts>=tmp.deletionTs)
+break;if(tmp.creationTsWasExplicit==false&&tmp.snapshots.length==0)
+lastValidIndex=i;}
+if(lastValidIndex===undefined){throw new Error('Cannot add snapshot. No instance was alive that was mutable.');}
+instance=this.instances[lastValidIndex];instance.creationTs=ts;}}else{instance=this.instances[i];}
+return instance.addSnapshot(ts,args,name,opt_baseTypeName);},get lastInstance(){if(this.instances.length==0)
+return undefined;return this.instances[this.instances.length-1];},idWasDeleted:function(category,name,ts){if(this.instances.length==0){this.instances.push(this.createObjectInstanceFunction_(this.parent,this.id,category,name,ts));}
+var lastInstance=this.instances[this.instances.length-1];if(ts<lastInstance.creationTs)
+throw new Error('Cannot delete a id before it was crated');if(lastInstance.deletionTs==Number.MAX_VALUE){lastInstance.wasDeleted(ts);return lastInstance;}
+if(ts<lastInstance.deletionTs)
+throw new Error('id was already deleted earlier.');lastInstance=this.createObjectInstanceFunction_(this.parent,this.id,category,name,ts);this.instances.push(lastInstance);lastInstance.wasDeleted(ts);return lastInstance;},getInstanceAt:function(ts){var i=tr.b.findIndexInSortedIntervals(this.instances,function(inst){return inst.creationTs;},function(inst){return inst.deletionTs-inst.creationTs;},ts);if(i<0){if(this.instances[0].creationTsWasExplicit)
+return undefined;return this.instances[0];}else if(i>=this.instances.length){return undefined;}
+return this.instances[i];},logToConsole:function(){for(var i=0;i<this.instances.length;i++){var instance=this.instances[i];var cEF='';var dEF='';if(instance.creationTsWasExplicit)
+cEF='(explicitC)';if(instance.deletionTsWasExplicit)
+dEF='(explicit)';console.log(instance.creationTs,cEF,instance.deletionTs,dEF,instance.category,instance.name,instance.snapshots.length+' snapshots');}}};return{TimeToObjectInstanceMap:TimeToObjectInstanceMap};});'use strict';tr.exportTo('tr.model',function(){var ObjectInstance=tr.model.ObjectInstance;var ObjectSnapshot=tr.model.ObjectSnapshot;function ObjectCollection(parent){tr.model.EventContainer.call(this);this.parent=parent;this.instanceMapsById_={};this.instancesByTypeName_={};this.createObjectInstance_=this.createObjectInstance_.bind(this);}
+ObjectCollection.prototype={__proto__:tr.model.EventContainer.prototype,iterateAllChildEventContainers:function(callback,opt_this){},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){var bI=!!eventTypePredicate.call(opt_this,ObjectInstance);var bS=!!eventTypePredicate.call(opt_this,ObjectSnapshot);if(bI===false&&bS===false)
+return;this.iterObjectInstances(function(instance){if(bI)
+callback.call(opt_this,instance);if(bS)
+instance.snapshots.forEach(callback,opt_this);},opt_this);},createObjectInstance_:function(parent,id,category,name,creationTs,opt_baseTypeName){var constructor=tr.model.ObjectInstance.getConstructor(category,name);var instance=new constructor(parent,id,category,name,creationTs,opt_baseTypeName);var typeName=instance.typeName;var instancesOfTypeName=this.instancesByTypeName_[typeName];if(!instancesOfTypeName){instancesOfTypeName=[];this.instancesByTypeName_[typeName]=instancesOfTypeName;}
+instancesOfTypeName.push(instance);return instance;},getOrCreateInstanceMap_:function(id){var instanceMap=this.instanceMapsById_[id];if(instanceMap)
+return instanceMap;instanceMap=new tr.model.TimeToObjectInstanceMap(this.createObjectInstance_,this.parent,id);this.instanceMapsById_[id]=instanceMap;return instanceMap;},idWasCreated:function(id,category,name,ts){var instanceMap=this.getOrCreateInstanceMap_(id);return instanceMap.idWasCreated(category,name,ts);},addSnapshot:function(id,category,name,ts,args,opt_baseTypeName){var instanceMap=this.getOrCreateInstanceMap_(id);var snapshot=instanceMap.addSnapshot(category,name,ts,args,opt_baseTypeName);if(snapshot.objectInstance.category!=category){var msg='Added snapshot name='+name+' with cat='+category+' impossible. It instance was created/snapshotted with cat='+
+snapshot.objectInstance.category+' name='+
+snapshot.objectInstance.name;throw new Error(msg);}
+if(opt_baseTypeName&&snapshot.objectInstance.baseTypeName!=opt_baseTypeName){throw new Error('Could not add snapshot with baseTypeName='+
+opt_baseTypeName+'. It '+'was previously created with name='+
+snapshot.objectInstance.baseTypeName);}
+if(snapshot.objectInstance.name!=name){throw new Error('Could not add snapshot with name='+name+'. It '+'was previously created with name='+
+snapshot.objectInstance.name);}
+return snapshot;},idWasDeleted:function(id,category,name,ts){var instanceMap=this.getOrCreateInstanceMap_(id);var deletedInstance=instanceMap.idWasDeleted(category,name,ts);if(!deletedInstance)
+return;if(deletedInstance.category!=category){var msg='Deleting object '+deletedInstance.name+' with a different category '+'than when it was created. It previous had cat='+
+deletedInstance.category+' but the delete command '+'had cat='+category;throw new Error(msg);}
+if(deletedInstance.baseTypeName!=name){throw new Error('Deletion requested for name='+
+name+' could not proceed: '+'An existing object with baseTypeName='+
+deletedInstance.baseTypeName+' existed.');}},autoDeleteObjects:function(maxTimestamp){tr.b.iterItems(this.instanceMapsById_,function(id,i2imap){var lastInstance=i2imap.lastInstance;if(lastInstance.deletionTs!=Number.MAX_VALUE)
+return;i2imap.idWasDeleted(lastInstance.category,lastInstance.name,maxTimestamp);lastInstance.deletionTsWasExplicit=false;});},getObjectInstanceAt:function(id,ts){var instanceMap=this.instanceMapsById_[id];if(!instanceMap)
+return undefined;return instanceMap.getInstanceAt(ts);},getSnapshotAt:function(id,ts){var instance=this.getObjectInstanceAt(id,ts);if(!instance)
+return undefined;return instance.getSnapshotAt(ts);},iterObjectInstances:function(iter,opt_this){opt_this=opt_this||this;tr.b.iterItems(this.instanceMapsById_,function(id,i2imap){i2imap.instances.forEach(iter,opt_this);});},getAllObjectInstances:function(){var instances=[];this.iterObjectInstances(function(i){instances.push(i);});return instances;},getAllInstancesNamed:function(name){return this.instancesByTypeName_[name];},getAllInstancesByTypeName:function(){return this.instancesByTypeName_;},preInitializeAllObjects:function(){this.iterObjectInstances(function(instance){instance.preInitialize();});},initializeAllObjects:function(){this.iterObjectInstances(function(instance){instance.initialize();});},initializeInstances:function(){this.iterObjectInstances(function(instance){instance.initialize();});},updateBounds:function(){this.bounds.reset();this.iterObjectInstances(function(instance){instance.updateBounds();this.bounds.addRange(instance.bounds);},this);},shiftTimestampsForward:function(amount){this.iterObjectInstances(function(instance){instance.shiftTimestampsForward(amount);});},addCategoriesToDict:function(categoriesDict){this.iterObjectInstances(function(instance){categoriesDict[instance.category]=true;});}};return{ObjectCollection:ObjectCollection};});'use strict';tr.exportTo('tr.model',function(){function AsyncSlice(category,title,colorId,start,args,duration,opt_isTopLevel,opt_cpuStart,opt_cpuDuration,opt_argsStripped){tr.model.TimedEvent.call(this,start);this.category=category||'';this.title=title;this.colorId=colorId;this.args=args;this.startStackFrame=undefined;this.endStackFrame=undefined;this.didNotFinish=false;this.important=false;this.subSlices=[];this.parentContainer=undefined;this.id=undefined;this.startThread=undefined;this.endThread=undefined;this.cpuStart=undefined;this.cpuDuration=undefined;this.argsStripped=false;this.startStackFrame=undefined;this.endStackFrame=undefined;this.duration=duration;this.isTopLevel=(opt_isTopLevel===true);if(opt_cpuStart!==undefined)
+this.cpuStart=opt_cpuStart;if(opt_cpuDuration!==undefined)
+this.cpuDuration=opt_cpuDuration;if(opt_argsStripped!==undefined)
+this.argsStripped=opt_argsStripped;};AsyncSlice.prototype={__proto__:tr.model.TimedEvent.prototype,get analysisTypeName(){return this.title;},get viewSubGroupTitle(){return this.title;},get userFriendlyName(){return'Async slice '+this.title+' at '+
+tr.b.u.TimeStamp.format(this.start);},get stableId(){var parentAsyncSliceGroup=this.parentContainer.asyncSliceGroup;return parentAsyncSliceGroup.stableId+'.'+
+parentAsyncSliceGroup.slices.indexOf(this);},findDescendentSlice:function(targetTitle){if(!this.subSlices)
+return undefined;for(var i=0;i<this.subSlices.length;i++){if(this.subSlices[i].title==targetTitle)
+return this.subSlices[i];var slice=this.subSlices[i].findDescendentSlice(targetTitle);if(slice)return slice;}
+return undefined;},iterateAllDescendents:function(callback,opt_this){this.subSlices.forEach(callback,opt_this);this.subSlices.forEach(function(subSlice){subSlice.iterateAllDescendents(callback,opt_this);},opt_this);},compareTo:function(that){return this.title.localeCompare(that.title);}};tr.model.EventRegistry.register(AsyncSlice,{name:'asyncSlice',pluralName:'asyncSlices',singleViewElementName:'tr-ui-a-single-async-slice-sub-view',multiViewElementName:'tr-ui-a-multi-async-slice-sub-view'});var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=AsyncSlice;options.defaultConstructor=AsyncSlice;tr.b.decorateExtensionRegistry(AsyncSlice,options);return{AsyncSlice:AsyncSlice};});'use strict';tr.exportTo('tr.model',function(){function AsyncSliceGroup(parentContainer,opt_name){tr.model.EventContainer.call(this);this.parentContainer_=parentContainer;this.slices=[];this.name_=opt_name;this.viewSubGroups_=undefined;}
+AsyncSliceGroup.prototype={__proto__:tr.model.EventContainer.prototype,get parentContainer(){return this.parentContainer_;},get model(){return this.parentContainer_.parent.model;},get stableId(){return this.parentContainer_.stableId+'.AsyncSliceGroup';},getSettingsKey:function(){if(!this.name_)
+return undefined;var parentKey=this.parentContainer_.getSettingsKey();if(!parentKey)
+return undefined;return parentKey+'.'+this.name_;},push:function(slice){slice.parentContainer=this.parentContainer;this.slices.push(slice);return slice;},get length(){return this.slices.length;},shiftTimestampsForward:function(amount){for(var sI=0;sI<this.slices.length;sI++){var slice=this.slices[sI];slice.start=(slice.start+amount);var shiftSubSlices=function(subSlices){if(subSlices===undefined||subSlices.length===0)
+return;for(var sJ=0;sJ<subSlices.length;sJ++){subSlices[sJ].start+=amount;shiftSubSlices(subSlices[sJ].subSlices);}};shiftSubSlices(slice.subSlices);}},updateBounds:function(){this.bounds.reset();for(var i=0;i<this.slices.length;i++){this.bounds.addValue(this.slices[i].start);this.bounds.addValue(this.slices[i].end);}},get viewSubGroups(){if(this.viewSubGroups_===undefined){var prefix='';if(this.name!==undefined)
+prefix=this.name+'.';else
+prefix='';var subGroupsByTitle={};for(var i=0;i<this.slices.length;++i){var slice=this.slices[i];var subGroupTitle=slice.viewSubGroupTitle;if(!subGroupsByTitle[subGroupTitle]){subGroupsByTitle[subGroupTitle]=new AsyncSliceGroup(this.parentContainer_,prefix+subGroupTitle);}
+subGroupsByTitle[subGroupTitle].push(slice);}
+this.viewSubGroups_=tr.b.dictionaryValues(subGroupsByTitle);this.viewSubGroups_.sort(function(a,b){return a.slices[0].compareTo(b.slices[0]);});}
+return this.viewSubGroups_;},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,tr.model.AsyncSlice)){for(var i=0;i<this.slices.length;i++){var slice=this.slices[i];callback.call(opt_this,slice);if(slice.subSlices)
+slice.subSlices.forEach(callback,opt_this);}}},iterateAllChildEventContainers:function(callback,opt_this){}};return{AsyncSliceGroup:AsyncSliceGroup};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;var Slice=tr.model.Slice;function getSliceLo(s){return s.start;}
+function getSliceHi(s){return s.end;}
+function SliceGroup(parentContainer,opt_sliceConstructor,opt_name){tr.model.EventContainer.call(this);this.parentContainer_=parentContainer;var sliceConstructor=opt_sliceConstructor||Slice;this.sliceConstructor=sliceConstructor;this.openPartialSlices_=[];this.slices=[];this.topLevelSlices=[];this.haveTopLevelSlicesBeenBuilt=false;this.name_=opt_name;if(this.model===undefined)
+throw new Error('SliceGroup must have model defined.');}
+SliceGroup.prototype={__proto__:tr.model.EventContainer.prototype,get parentContainer(){return this.parentContainer_;},get model(){return this.parentContainer_.model;},get stableId(){return this.parentContainer_.stableId+'.SliceGroup';},getSettingsKey:function(){if(!this.name_)
+return undefined;var parentKey=this.parentContainer_.getSettingsKey();if(!parentKey)
+return undefined;return parentKey+'.'+this.name;},get length(){return this.slices.length;},pushSlice:function(slice){this.haveTopLevelSlicesBeenBuilt=false;slice.parentContainer=this.parentContainer_;this.slices.push(slice);return slice;},pushSlices:function(slices){this.haveTopLevelSlicesBeenBuilt=false;slices.forEach(function(slice){slice.parentContainer=this.parentContainer_;this.slices.push(slice);},this);},beginSlice:function(category,title,ts,opt_args,opt_tts,opt_argsStripped,opt_colorId){if(this.openPartialSlices_.length){var prevSlice=this.openPartialSlices_[this.openPartialSlices_.length-1];if(ts<prevSlice.start)
+throw new Error('Slices must be added in increasing timestamp order');}
+var colorId=opt_colorId||ColorScheme.getColorIdForGeneralPurposeString(title);var slice=new this.sliceConstructor(category,title,colorId,ts,opt_args?opt_args:{},null,opt_tts,undefined,opt_argsStripped);this.openPartialSlices_.push(slice);slice.didNotFinish=true;this.pushSlice(slice);return slice;},isTimestampValidForBeginOrEnd:function(ts){if(!this.openPartialSlices_.length)
+return true;var top=this.openPartialSlices_[this.openPartialSlices_.length-1];return ts>=top.start;},get openSliceCount(){return this.openPartialSlices_.length;},get mostRecentlyOpenedPartialSlice(){if(!this.openPartialSlices_.length)
+return undefined;return this.openPartialSlices_[this.openPartialSlices_.length-1];},endSlice:function(ts,opt_tts,opt_colorId){if(!this.openSliceCount)
+throw new Error('endSlice called without an open slice');var slice=this.openPartialSlices_[this.openSliceCount-1];this.openPartialSlices_.splice(this.openSliceCount-1,1);if(ts<slice.start)
+throw new Error('Slice '+slice.title+' end time is before its start.');slice.duration=ts-slice.start;slice.didNotFinish=false;slice.colorId=opt_colorId||slice.colorId;if(opt_tts&&slice.cpuStart!==undefined)
+slice.cpuDuration=opt_tts-slice.cpuStart;return slice;},pushCompleteSlice:function(category,title,ts,duration,tts,cpuDuration,opt_args,opt_argsStripped,opt_colorId,opt_bind_id){var colorId=opt_colorId||ColorScheme.getColorIdForGeneralPurposeString(title);var slice=new this.sliceConstructor(category,title,colorId,ts,opt_args?opt_args:{},duration,tts,cpuDuration,opt_argsStripped,opt_bind_id);if(duration===undefined)
+slice.didNotFinish=true;this.pushSlice(slice);return slice;},autoCloseOpenSlices:function(opt_maxTimestamp){if(!opt_maxTimestamp){this.updateBounds();opt_maxTimestamp=this.bounds.max;}
+for(var sI=0;sI<this.slices.length;sI++){var slice=this.slices[sI];if(slice.didNotFinish)
+slice.duration=opt_maxTimestamp-slice.start;}
+this.openPartialSlices_=[];},shiftTimestampsForward:function(amount){for(var sI=0;sI<this.slices.length;sI++){var slice=this.slices[sI];slice.start=(slice.start+amount);}},updateBounds:function(){this.bounds.reset();for(var i=0;i<this.slices.length;i++){this.bounds.addValue(this.slices[i].start);this.bounds.addValue(this.slices[i].end);}},copySlice:function(slice){var newSlice=new this.sliceConstructor(slice.category,slice.title,slice.colorId,slice.start,slice.args,slice.duration,slice.cpuStart,slice.cpuDuration);newSlice.didNotFinish=slice.didNotFinish;return newSlice;},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,this.sliceConstructor))
+this.slices.forEach(callback,opt_this);},iterateAllChildEventContainers:function(callback,opt_this){},getSlicesOfName:function(title){var slices=[];for(var i=0;i<this.slices.length;i++){if(this.slices[i].title==title){slices.push(this.slices[i]);}}
+return slices;},iterSlicesInTimeRange:function(callback,start,end){var ret=[];tr.b.iterateOverIntersectingIntervals(this.topLevelSlices,function(s){return s.start;},function(s){return s.duration;},start,end,function(topLevelSlice){callback(topLevelSlice);topLevelSlice.iterateAllDescendents(callback);});return ret;},findFirstSlice:function(){if(!this.haveTopLevelSlicesBeenBuilt)
+throw new Error('Nope');if(0===this.slices.length)
+return undefined;return this.slices[0];},findSliceAtTs:function(ts){if(!this.haveTopLevelSlicesBeenBuilt)
+throw new Error('Nope');var i=tr.b.findIndexInSortedClosedIntervals(this.topLevelSlices,getSliceLo,getSliceHi,ts);if(i==-1||i==this.topLevelSlices.length)
+return undefined;var curSlice=this.topLevelSlices[i];while(true){var i=tr.b.findIndexInSortedClosedIntervals(curSlice.subSlices,getSliceLo,getSliceHi,ts);if(i==-1||i==curSlice.subSlices.length)
+return curSlice;curSlice=curSlice.subSlices[i];}},findNextSliceAfter:function(ts,refGuid){var i=tr.b.findLowIndexInSortedArray(this.slices,getSliceLo,ts);if(i===this.slices.length)
+return undefined;for(;i<this.slices.length;i++){var slice=this.slices[i];if(slice.start>ts)
+return slice;if(slice.guid<=refGuid)
+continue;return slice;}
+return undefined;},createSubSlices:function(){this.haveTopLevelSlicesBeenBuilt=true;this.createSubSlicesImpl_();if(this.parentContainer.timeSlices)
+this.addCpuTimeToSubslices_(this.parentContainer.timeSlices);this.slices.forEach(function(slice){var selfTime=slice.duration;for(var i=0;i<slice.subSlices.length;i++)
+selfTime-=slice.subSlices[i].duration;slice.selfTime=selfTime;if(slice.cpuDuration===undefined)
+return;var cpuSelfTime=slice.cpuDuration;for(var i=0;i<slice.subSlices.length;i++){if(slice.subSlices[i].cpuDuration!==undefined)
+cpuSelfTime-=slice.subSlices[i].cpuDuration;}
+slice.cpuSelfTime=cpuSelfTime;});},createSubSlicesImpl_:function(){var precisionUnit=this.model.intrinsicTimeUnit;function addSliceIfBounds(root,child){if(root.bounds(child,precisionUnit)){if(root.subSlices&&root.subSlices.length>0){if(addSliceIfBounds(root.subSlices[root.subSlices.length-1],child))
+return true;}
+child.parentSlice=root;if(root.subSlices===undefined)
+root.subSlices=[];root.subSlices.push(child);return true;}
+return false;}
+if(!this.slices.length)
+return;var ops=[];for(var i=0;i<this.slices.length;i++){if(this.slices[i].subSlices)
+this.slices[i].subSlices.splice(0,this.slices[i].subSlices.length);ops.push(i);}
+var originalSlices=this.slices;ops.sort(function(ix,iy){var x=originalSlices[ix];var y=originalSlices[iy];if(x.start!=y.start)
+return x.start-y.start;return ix-iy;});var slices=new Array(this.slices.length);for(var i=0;i<ops.length;i++){slices[i]=originalSlices[ops[i]];}
+var rootSlice=slices[0];this.topLevelSlices=[];this.topLevelSlices.push(rootSlice);rootSlice.isTopLevel=true;for(var i=1;i<slices.length;i++){var slice=slices[i];if(!addSliceIfBounds(rootSlice,slice)){rootSlice=slice;rootSlice.isTopLevel=true;this.topLevelSlices.push(rootSlice);}}
+this.slices=slices;},addCpuTimeToSubslices_:function(timeSlices){var SCHEDULING_STATE=tr.model.SCHEDULING_STATE;var sliceIdx=0;timeSlices.forEach(function(timeSlice){if(timeSlice.schedulingState==SCHEDULING_STATE.RUNNING){while(sliceIdx<this.topLevelSlices.length){if(this.addCpuTimeToSubslice_(this.topLevelSlices[sliceIdx],timeSlice)){sliceIdx++;}else{break;}}}},this);},addCpuTimeToSubslice_:function(slice,timeSlice){if(slice.start>timeSlice.end||slice.end<timeSlice.start)
+return slice.end<=timeSlice.end;var duration=timeSlice.duration;if(slice.start>timeSlice.start)
+duration-=slice.start-timeSlice.start;if(timeSlice.end>slice.end)
+duration-=timeSlice.end-slice.end;if(slice.cpuDuration){slice.cpuDuration+=duration;}else{slice.cpuDuration=duration;}
+for(var i=0;i<slice.subSlices.length;i++){this.addCpuTimeToSubslice_(slice.subSlices[i],timeSlice);}
+return slice.end<=timeSlice.end;}};SliceGroup.merge=function(groupA,groupB){if(groupA.openPartialSlices_.length>0)
+throw new Error('groupA has open partial slices');if(groupB.openPartialSlices_.length>0)
+throw new Error('groupB has open partial slices');if(groupA.parentContainer!=groupB.parentContainer)
+throw new Error('Different parent threads. Cannot merge');if(groupA.sliceConstructor!=groupB.sliceConstructor)
+throw new Error('Different slice constructors. Cannot merge');var result=new SliceGroup(groupA.parentContainer,groupA.sliceConstructor,groupA.name_);var slicesA=groupA.slices;var slicesB=groupB.slices;var idxA=0;var idxB=0;var openA=[];var openB=[];var splitOpenSlices=function(when){for(var i=0;i<openB.length;i++){var oldSlice=openB[i];var oldEnd=oldSlice.end;if(when<oldSlice.start||oldEnd<when){throw new Error('slice should not be split');}
+var newSlice=result.copySlice(oldSlice);newSlice.start=when;newSlice.duration=oldEnd-when;if(newSlice.title.indexOf(' (cont.)')==-1)
+newSlice.title+=' (cont.)';oldSlice.duration=when-oldSlice.start;openB[i]=newSlice;result.pushSlice(newSlice);}};var closeOpenSlices=function(upTo){while(openA.length>0||openB.length>0){var nextA=openA[openA.length-1];var nextB=openB[openB.length-1];var endA=nextA&&nextA.end;var endB=nextB&&nextB.end;if((endA===undefined||endA>upTo)&&(endB===undefined||endB>upTo)){return;}
+if(endB===undefined||endA<endB){splitOpenSlices(endA);openA.pop();}else{openB.pop();}}};while(idxA<slicesA.length||idxB<slicesB.length){var sA=slicesA[idxA];var sB=slicesB[idxB];var nextSlice,isFromB;if(sA===undefined||(sB!==undefined&&sA.start>sB.start)){nextSlice=result.copySlice(sB);isFromB=true;idxB++;}else{nextSlice=result.copySlice(sA);isFromB=false;idxA++;}
+closeOpenSlices(nextSlice.start);result.pushSlice(nextSlice);if(isFromB){openB.push(nextSlice);}else{splitOpenSlices(nextSlice.start);openA.push(nextSlice);}}
+closeOpenSlices();return result;};return{SliceGroup:SliceGroup};});'use strict';tr.exportTo('tr.model',function(){var Slice=tr.model.Slice;function ThreadSlice(cat,title,colorId,start,args,opt_duration,opt_cpuStart,opt_cpuDuration,opt_argsStripped,opt_bind_id){Slice.call(this,cat,title,colorId,start,args,opt_duration,opt_cpuStart,opt_cpuDuration,opt_argsStripped,opt_bind_id);this.subSlices=[];}
+ThreadSlice.prototype={__proto__:Slice.prototype,getProcess:function(){var thread=this.parentContainer;if(thread&&thread.getProcess)
+return thread.getProcess();return undefined;}};tr.model.EventRegistry.register(ThreadSlice,{name:'slice',pluralName:'slices',singleViewElementName:'tr-ui-a-single-thread-slice-sub-view',multiViewElementName:'tr-ui-a-multi-thread-slice-sub-view'});return{ThreadSlice:ThreadSlice};});'use strict';tr.exportTo('tr.model',function(){var AsyncSlice=tr.model.AsyncSlice;var AsyncSliceGroup=tr.model.AsyncSliceGroup;var Slice=tr.model.Slice;var SliceGroup=tr.model.SliceGroup;var ThreadSlice=tr.model.ThreadSlice;var ThreadTimeSlice=tr.model.ThreadTimeSlice;function Thread(parent,tid){if(!parent)
+throw new Error('Parent must be provided.');tr.model.EventContainer.call(this);this.parent=parent;this.sortIndex=0;this.tid=tid;this.name=undefined;this.samples_=undefined;var that=this;this.sliceGroup=new SliceGroup(this,ThreadSlice,'slices');this.timeSlices=undefined;this.kernelSliceGroup=new SliceGroup(this,ThreadSlice,'kernel-slices');this.asyncSliceGroup=new AsyncSliceGroup(this,'async-slices');}
+Thread.prototype={__proto__:tr.model.EventContainer.prototype,get model(){return this.parent.model;},get stableId(){return this.parent.stableId+'.'+this.tid;},compareTo:function(that){return Thread.compare(this,that);},iterateAllChildEventContainers:function(callback,opt_this){if(this.sliceGroup.length)
+callback.call(opt_this,this.sliceGroup);if(this.kernelSliceGroup.length)
+callback.call(opt_this,this.kernelSliceGroup);if(this.asyncSliceGroup.length)
+callback.call(opt_this,this.asyncSliceGroup);},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(this.timeSlices&&this.timeSlices.length){if(eventTypePredicate.call(opt_this,ThreadTimeSlice))
+this.timeSlices.forEach(callback,opt_this);}},iterateAllPersistableObjects:function(cb){cb(this);if(this.sliceGroup.length)
+cb(this.sliceGroup);this.asyncSliceGroup.viewSubGroups.forEach(cb);},shiftTimestampsForward:function(amount){this.sliceGroup.shiftTimestampsForward(amount);if(this.timeSlices){for(var i=0;i<this.timeSlices.length;i++){var slice=this.timeSlices[i];slice.start+=amount;}}
+this.kernelSliceGroup.shiftTimestampsForward(amount);this.asyncSliceGroup.shiftTimestampsForward(amount);},get isEmpty(){if(this.sliceGroup.length)
+return false;if(this.sliceGroup.openSliceCount)
+return false;if(this.timeSlices&&this.timeSlices.length)
+return false;if(this.kernelSliceGroup.length)
+return false;if(this.asyncSliceGroup.length)
+return false;if(this.samples_.length)
+return false;return true;},updateBounds:function(){this.bounds.reset();this.sliceGroup.updateBounds();this.bounds.addRange(this.sliceGroup.bounds);this.kernelSliceGroup.updateBounds();this.bounds.addRange(this.kernelSliceGroup.bounds);this.asyncSliceGroup.updateBounds();this.bounds.addRange(this.asyncSliceGroup.bounds);if(this.timeSlices&&this.timeSlices.length){this.bounds.addValue(this.timeSlices[0].start);this.bounds.addValue(this.timeSlices[this.timeSlices.length-1].end);}
+if(this.samples_&&this.samples_.length){this.bounds.addValue(this.samples_[0].start);this.bounds.addValue(this.samples_[this.samples_.length-1].end);}},addCategoriesToDict:function(categoriesDict){for(var i=0;i<this.sliceGroup.length;i++)
+categoriesDict[this.sliceGroup.slices[i].category]=true;for(var i=0;i<this.kernelSliceGroup.length;i++)
+categoriesDict[this.kernelSliceGroup.slices[i].category]=true;for(var i=0;i<this.asyncSliceGroup.length;i++)
+categoriesDict[this.asyncSliceGroup.slices[i].category]=true;if(this.samples_){for(var i=0;i<this.samples_.length;i++)
+categoriesDict[this.samples_[i].category]=true;}},autoCloseOpenSlices:function(opt_maxTimestamp){this.sliceGroup.autoCloseOpenSlices(opt_maxTimestamp);this.kernelSliceGroup.autoCloseOpenSlices(opt_maxTimestamp);},mergeKernelWithUserland:function(){if(this.kernelSliceGroup.length>0){var newSlices=SliceGroup.merge(this.sliceGroup,this.kernelSliceGroup);this.sliceGroup.slices=newSlices.slices;this.kernelSliceGroup=new SliceGroup(this);this.updateBounds();}},createSubSlices:function(){this.sliceGroup.createSubSlices();this.samples_=this.parent.model.samples.filter(function(sample){return sample.thread==this;},this);},get userFriendlyName(){return this.name||this.tid;},get userFriendlyDetails(){return'tid: '+this.tid+
+(this.name?', name: '+this.name:'');},getSettingsKey:function(){if(!this.name)
+return undefined;var parentKey=this.parent.getSettingsKey();if(!parentKey)
+return undefined;return parentKey+'.'+this.name;},getProcess:function(){return this.parent;},indexOfTimeSlice:function(timeSlice){var i=tr.b.findLowIndexInSortedArray(this.timeSlices,function(slice){return slice.start;},timeSlice.start);if(this.timeSlices[i]!==timeSlice)
+return undefined;return i;},getCpuStatsForRange:function(range){var stats={};stats.total=0;if(!this.timeSlices)
+return stats;function addStatsForSlice(threadTimeSlice){var freqRange=tr.b.Range.fromExplicitRange(threadTimeSlice.start,threadTimeSlice.end);var intersection=freqRange.findIntersection(range);if(threadTimeSlice.schedulingState==tr.model.SCHEDULING_STATE.RUNNING){var cpu=threadTimeSlice.cpuOnWhichThreadWasRunning;if(!(cpu.cpuNumber in stats))
+stats[cpu.cpuNumber]=0;stats[cpu.cpuNumber]+=intersection.duration;stats.total+=intersection.duration;}}
+tr.b.iterateOverIntersectingIntervals(this.timeSlices,function(x){return x.start;},function(x){return x.end;},range.min,range.max,addStatsForSlice);return stats;},getSchedulingStatsForRange:function(start,end){var stats={};if(!this.timeSlices)return stats;function addStatsForSlice(threadTimeSlice){var overlapStart=Math.max(threadTimeSlice.start,start);var overlapEnd=Math.min(threadTimeSlice.end,end);var schedulingState=threadTimeSlice.schedulingState;if(!(schedulingState in stats))
+stats[schedulingState]=0;stats[schedulingState]+=overlapEnd-overlapStart;}
+tr.b.iterateOverIntersectingIntervals(this.timeSlices,function(x){return x.start;},function(x){return x.end;},start,end,addStatsForSlice);return stats;},get samples(){return this.samples_;}};Thread.compare=function(x,y){var tmp=x.parent.compareTo(y.parent);if(tmp)
+return tmp;tmp=x.sortIndex-y.sortIndex;if(tmp)
+return tmp;tmp=tr.b.comparePossiblyUndefinedValues(x.name,y.name,function(x,y){return x.localeCompare(y);});if(tmp)
+return tmp;return x.tid-y.tid;};return{Thread:Thread};});'use strict';tr.exportTo('tr.model',function(){var Thread=tr.model.Thread;var Counter=tr.model.Counter;function ProcessBase(model){if(!model)
+throw new Error('Must provide a model');tr.model.EventContainer.call(this);this.model=model;this.threads={};this.counters={};this.objects=new tr.model.ObjectCollection(this);this.sortIndex=0;};ProcessBase.compare=function(x,y){return x.sortIndex-y.sortIndex;};ProcessBase.prototype={__proto__:tr.model.EventContainer.prototype,get stableId(){throw new Error('Not implemented');},iterateAllChildEventContainers:function(callback,opt_this){for(var tid in this.threads)
+callback.call(opt_this,this.threads[tid]);for(var id in this.counters)
+callback.call(opt_this,this.counters[id]);callback.call(opt_this,this.objects);},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){},iterateAllPersistableObjects:function(cb){cb(this);for(var tid in this.threads)
+this.threads[tid].iterateAllPersistableObjects(cb);},get numThreads(){var n=0;for(var p in this.threads){n++;}
+return n;},shiftTimestampsForward:function(amount){this.iterateAllChildEventContainers(function(child){child.shiftTimestampsForward(amount);});},autoCloseOpenSlices:function(opt_maxTimestamp){for(var tid in this.threads){var thread=this.threads[tid];thread.autoCloseOpenSlices(opt_maxTimestamp);}},autoDeleteObjects:function(maxTimestamp){this.objects.autoDeleteObjects(maxTimestamp);},preInitializeObjects:function(){this.objects.preInitializeAllObjects();},initializeObjects:function(){this.objects.initializeAllObjects();},mergeKernelWithUserland:function(){for(var tid in this.threads){var thread=this.threads[tid];thread.mergeKernelWithUserland();}},updateBounds:function(){this.bounds.reset();for(var tid in this.threads){this.threads[tid].updateBounds();this.bounds.addRange(this.threads[tid].bounds);}
+for(var id in this.counters){this.counters[id].updateBounds();this.bounds.addRange(this.counters[id].bounds);}
+this.objects.updateBounds();this.bounds.addRange(this.objects.bounds);},addCategoriesToDict:function(categoriesDict){for(var tid in this.threads)
+this.threads[tid].addCategoriesToDict(categoriesDict);for(var id in this.counters)
+categoriesDict[this.counters[id].category]=true;this.objects.addCategoriesToDict(categoriesDict);},findAllThreadsMatching:function(predicate,opt_this){var threads=[];for(var tid in this.threads){var thread=this.threads[tid];if(predicate.call(opt_this,thread))
+threads.push(thread);}
+return threads;},findAllThreadsNamed:function(name){var threads=this.findAllThreadsMatching(function(thread){if(!thread.name)
+return false;return thread.name===name;});return threads;},findAtMostOneThreadNamed:function(name){var threads=this.findAllThreadsNamed(name);if(threads.length===0)
+return undefined;if(threads.length>1)
+throw new Error('Expected no more than one '+name);return threads[0];},pruneEmptyContainers:function(){var threadsToKeep={};for(var tid in this.threads){var thread=this.threads[tid];if(!thread.isEmpty)
+threadsToKeep[tid]=thread;}
+this.threads=threadsToKeep;},getThread:function(tid){return this.threads[tid];},getOrCreateThread:function(tid){if(!this.threads[tid])
+this.threads[tid]=new Thread(this,tid);return this.threads[tid];},getOrCreateCounter:function(cat,name){var id=cat+'.'+name;if(!this.counters[id])
+this.counters[id]=new Counter(this,id,cat,name);return this.counters[id];},getSettingsKey:function(){throw new Error('Not implemented');},createSubSlices:function(){for(var tid in this.threads)
+this.threads[tid].createSubSlices();}};return{ProcessBase:ProcessBase};});'use strict';tr.exportTo('tr.model',function(){var Cpu=tr.model.Cpu;var ProcessBase=tr.model.ProcessBase;function Kernel(model){ProcessBase.call(this,model);this.cpus={};this.softwareMeasuredCpuCount_=undefined;};Kernel.compare=function(x,y){return 0;};Kernel.prototype={__proto__:ProcessBase.prototype,compareTo:function(that){return Kernel.compare(this,that);},get userFriendlyName(){return'Kernel';},get userFriendlyDetails(){return'Kernel';},get stableId(){return'Kernel';},getOrCreateCpu:function(cpuNumber){if(!this.cpus[cpuNumber])
+this.cpus[cpuNumber]=new Cpu(this,cpuNumber);return this.cpus[cpuNumber];},get softwareMeasuredCpuCount(){return this.softwareMeasuredCpuCount_;},set softwareMeasuredCpuCount(softwareMeasuredCpuCount){if(this.softwareMeasuredCpuCount_!==undefined&&this.softwareMeasuredCpuCount_!==softwareMeasuredCpuCount){throw new Error('Cannot change the softwareMeasuredCpuCount once it is set');}
+this.softwareMeasuredCpuCount_=softwareMeasuredCpuCount;},get bestGuessAtCpuCount(){var realCpuCount=tr.b.dictionaryLength(this.cpus);if(realCpuCount!==0)
+return realCpuCount;return this.softwareMeasuredCpuCount;},updateBounds:function(){ProcessBase.prototype.updateBounds.call(this);for(var cpuNumber in this.cpus){var cpu=this.cpus[cpuNumber];cpu.updateBounds();this.bounds.addRange(cpu.bounds);}},createSubSlices:function(){ProcessBase.prototype.createSubSlices.call(this);for(var cpuNumber in this.cpus){var cpu=this.cpus[cpuNumber];cpu.createSubSlices();}},addCategoriesToDict:function(categoriesDict){ProcessBase.prototype.addCategoriesToDict.call(this,categoriesDict);for(var cpuNumber in this.cpus)
+this.cpus[cpuNumber].addCategoriesToDict(categoriesDict);},getSettingsKey:function(){return'kernel';},iterateAllChildEventContainers:function(callback,opt_this){ProcessBase.prototype.iterateAllChildEventContainers.call(this,callback,opt_this);for(var cpuId in this.cpus)
+callback.call(opt_this,this.cpus[cpuId]);},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){ProcessBase.prototype.iterateAllEventsInThisContainer.call(this,eventTypePredicate,callback,opt_this);}};return{Kernel:Kernel};});'use strict';tr.exportTo('tr.model',function(){function ModelIndices(model){this.flowEventsById_={};model.flowEvents.forEach(function(fe){if(fe.id!==undefined){if(!this.flowEventsById_.hasOwnProperty(fe.id)){this.flowEventsById_[fe.id]=new Array();}
+this.flowEventsById_[fe.id].push(fe);}},this);}
+ModelIndices.prototype={addEventWithId:function(id,event){if(!this.flowEventsById_.hasOwnProperty(id)){this.flowEventsById_[id]=new Array();}
+this.flowEventsById_[id].push(event);},getFlowEventsWithId:function(id){if(!this.flowEventsById_.hasOwnProperty(id))
+return[];return this.flowEventsById_[id];}};return{ModelIndices:ModelIndices};});'use strict';tr.exportTo('tr.model',function(){var DISCOUNTED_ALLOCATOR_NAMES=['winheap','malloc'];var SIZE_ATTRIBUTE_NAME=tr.model.MemoryAllocatorDump.SIZE_ATTRIBUTE_NAME;var EFFECTIVE_SIZE_ATTRIBUTE_NAME=tr.model.MemoryAllocatorDump.EFFECTIVE_SIZE_ATTRIBUTE_NAME;function ProcessMemoryDump(globalMemoryDump,process,start){tr.model.ContainerMemoryDump.call(this,start);this.process=process;this.globalMemoryDump=globalMemoryDump;this.totals=undefined;this.vmRegions_=undefined;this.heapDumps=undefined;this.tracingMemoryDiscounted_=false;};ProcessMemoryDump.prototype={__proto__:tr.model.ContainerMemoryDump.prototype,get userFriendlyName(){return'Process memory dump at '+
+tr.b.u.TimeStamp.format(this.start);},get containerName(){return this.process.userFriendlyName;},get processMemoryDumps(){var dumps={};dumps[this.process.pid]=this;return dumps;},get vmRegions(){throw new Error('VM regions must be accessed through the mostRecentVmRegions field');},set vmRegions(vmRegions){this.vmRegions_=vmRegions;},get hasOwnVmRegions(){return this.vmRegions_!==undefined;},getMostRecentTotalVmRegionStat:function(statName){if(this.mostRecentVmRegions===undefined)
+return undefined;var total=0;this.mostRecentVmRegions.forEach(function(vmRegion){var statValue=vmRegion.byteStats[statName];if(statValue===undefined)
+return;total+=statValue;});return total;},discountTracingOverhead:function(opt_model){if(this.tracingMemoryDiscounted_)
+return;this.tracingMemoryDiscounted_=true;var tracingDump=this.getMemoryAllocatorDumpByFullName('tracing');if(tracingDump===undefined)
+return;function getDiscountedSize(sizeAttrName){var sizeAttr=tracingDump.getValidSizeAttributeOrUndefined(sizeAttrName,opt_model);if(sizeAttr===undefined)
+return 0;return sizeAttr.value;}
+var discountedSize=getDiscountedSize(SIZE_ATTRIBUTE_NAME);var discountedEffectiveSize=getDiscountedSize(EFFECTIVE_SIZE_ATTRIBUTE_NAME);var discountedResidentSize=getDiscountedSize('resident_size');if(discountedResidentSize>0){if(this.totals!==undefined){if(this.totals.residentBytes!==undefined)
+this.totals.residentBytes-=discountedResidentSize;if(this.totals.peakResidentBytes!==undefined)
+this.totals.peakResidentBytes-=discountedResidentSize;}
+if(this.vmRegions_!==undefined){var hasPrivateDirtyResident=false;var hasProportionalResident=false;for(var i=0;i<this.vmRegions_.length;i++){var byteStats=this.vmRegions_[i].byteStats;if(byteStats.privateDirtyResident!==undefined)
+hasPrivateDirtyResident=true;if(byteStats.proportionalResident!==undefined)
+hasProportionalResident=true;if(hasPrivateDirtyResident&&hasProportionalResident)
+break;}
+if(hasPrivateDirtyResident||hasProportionalResident){this.vmRegions_.push(VMRegion.fromDict({mappedFile:'[discounted tracing overhead]',byteStats:{privateDirtyResident:hasPrivateDirtyResident?-discountedResidentSize:undefined,proportionalResident:hasProportionalResident?-discountedResidentSize:undefined}}));}}}
+if(discountedSize>0||discountedEffectiveSize>0){function discountSizeAndEffectiveSize(dump){var dumpSizeAttr=dump.getValidSizeAttributeOrUndefined(SIZE_ATTRIBUTE_NAME,opt_model);if(dumpSizeAttr!==undefined)
+dumpSizeAttr.value-=discountedSize;var dumpEffectiveSizeAttr=dump.getValidSizeAttributeOrUndefined(EFFECTIVE_SIZE_ATTRIBUTE_NAME,opt_model);if(dumpEffectiveSizeAttr!==undefined)
+dumpEffectiveSizeAttr.value-=discountedEffectiveSize;}
+var hasDiscountedFromAllocatorDumps=DISCOUNTED_ALLOCATOR_NAMES.some(function(allocatorName){var allocatorDump=this.getMemoryAllocatorDumpByFullName(allocatorName);if(allocatorDump===undefined)
+return false;discountSizeAndEffectiveSize(allocatorDump);var allocatedObjectsDumpName=allocatorName+'/allocated_objects';var allocatedObjectsDump=this.getMemoryAllocatorDumpByFullName(allocatedObjectsDumpName);if(allocatedObjectsDump===undefined)
+return true;discountSizeAndEffectiveSize(allocatedObjectsDump);var discountDumpName=allocatedObjectsDumpName+'/discounted_tracing_overhead';var discountDump=new tr.model.MemoryAllocatorDump(this,discountDumpName);discountDump.parent=allocatedObjectsDump;discountDump.addAttribute(SIZE_ATTRIBUTE_NAME,new tr.model.ScalarAttribute('bytes',-discountedSize));discountDump.addAttribute(EFFECTIVE_SIZE_ATTRIBUTE_NAME,new tr.model.ScalarAttribute('bytes',-discountedEffectiveSize));allocatedObjectsDump.children.push(discountDump);return true;},this);if(hasDiscountedFromAllocatorDumps)
+this.memoryAllocatorDumps=this.memoryAllocatorDumps;}}};ProcessMemoryDump.hookUpMostRecentVmRegionsLinks=function(processDumps){var mostRecentVmRegions=undefined;processDumps.forEach(function(processDump){if(processDump.vmRegions_!==undefined)
+mostRecentVmRegions=processDump.vmRegions_;processDump.mostRecentVmRegions=mostRecentVmRegions;});};function VMRegion(startAddress,sizeInBytes,protectionFlags,mappedFile,byteStats){this.startAddress=startAddress;this.sizeInBytes=sizeInBytes;this.protectionFlags=protectionFlags;this.mappedFile=mappedFile;this.byteStats=byteStats;};VMRegion.PROTECTION_FLAG_READ=4;VMRegion.PROTECTION_FLAG_WRITE=2;VMRegion.PROTECTION_FLAG_EXECUTE=1;VMRegion.prototype={get protectionFlagsToString(){if(this.protectionFlags===undefined)
+return undefined;return((this.protectionFlags&VMRegion.PROTECTION_FLAG_READ?'r':'-')+
+(this.protectionFlags&VMRegion.PROTECTION_FLAG_WRITE?'w':'-')+
+(this.protectionFlags&VMRegion.PROTECTION_FLAG_EXECUTE?'x':'-'));}};VMRegion.fromDict=function(dict){return new VMRegion(dict.startAddress,dict.sizeInBytes,dict.protectionFlags,dict.mappedFile,VMRegionByteStats.fromDict(dict.byteStats));};function VMRegionByteStats(privateCleanResident,privateDirtyResident,sharedCleanResident,sharedDirtyResident,proportionalResident,swapped){this.privateCleanResident=privateCleanResident;this.privateDirtyResident=privateDirtyResident;this.sharedCleanResident=sharedCleanResident;this.sharedDirtyResident=sharedDirtyResident;this.proportionalResident=proportionalResident;this.swapped=swapped;}
+VMRegionByteStats.fromDict=function(dict){return new VMRegionByteStats(dict.privateCleanResident,dict.privateDirtyResident,dict.sharedCleanResident,dict.sharedDirtyResident,dict.proportionalResident,dict.swapped);}
+tr.model.EventRegistry.register(ProcessMemoryDump,{name:'processMemoryDump',pluralName:'processMemoryDumps',singleViewElementName:'tr-ui-a-container-memory-dump-sub-view',multiViewElementName:'tr-ui-a-container-memory-dump-sub-view'});return{ProcessMemoryDump:ProcessMemoryDump,VMRegion:VMRegion,VMRegionByteStats:VMRegionByteStats};});'use strict';tr.exportTo('tr.model',function(){var ProcessBase=tr.model.ProcessBase;var ProcessInstantEvent=tr.model.ProcessInstantEvent;var Frame=tr.model.Frame;var ProcessMemoryDump=tr.model.ProcessMemoryDump;function Process(model,pid){if(model===undefined)
+throw new Error('model must be provided');if(pid===undefined)
+throw new Error('pid must be provided');tr.model.ProcessBase.call(this,model);this.pid=pid;this.name=undefined;this.labels=[];this.instantEvents=[];this.memoryDumps=[];this.frames=[];this.activities=[];};Process.compare=function(x,y){var tmp=tr.model.ProcessBase.compare(x,y);if(tmp)
+return tmp;tmp=tr.b.comparePossiblyUndefinedValues(x.name,y.name,function(x,y){return x.localeCompare(y);});if(tmp)
+return tmp;tmp=tr.b.compareArrays(x.labels,y.labels,function(x,y){return x.localeCompare(y);});if(tmp)
+return tmp;return x.pid-y.pid;};Process.prototype={__proto__:tr.model.ProcessBase.prototype,get stableId(){return this.pid;},compareTo:function(that){return Process.compare(this,that);},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){ProcessBase.prototype.iterateAllEventsInThisContainer.call(this,eventTypePredicate,callback,opt_this);if(eventTypePredicate.call(opt_this,ProcessInstantEvent))
+this.instantEvents.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,Frame))
+this.frames.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,ProcessMemoryDump))
+this.memoryDumps.forEach(callback,opt_this);},pushInstantEvent:function(instantEvent){this.instantEvents.push(instantEvent);},addLabelIfNeeded:function(labelName){for(var i=0;i<this.labels.length;i++){if(this.labels[i]===labelName)
+return;}
+this.labels.push(labelName);},get userFriendlyName(){var res;if(this.name)
+res=this.name+' (pid '+this.pid+')';else
+res='Process '+this.pid;if(this.labels.length)
+res+=': '+this.labels.join(', ');return res;},get userFriendlyDetails(){if(this.name)
+return this.name+' (pid '+this.pid+')';return'pid: '+this.pid;},getSettingsKey:function(){if(!this.name)
+return undefined;if(!this.labels.length)
+return'processes.'+this.name;return'processes.'+this.name+'.'+this.labels.join('.');},shiftTimestampsForward:function(amount){for(var id in this.instantEvents)
+this.instantEvents[id].start+=amount;for(var i=0;i<this.frames.length;i++)
+this.frames[i].shiftTimestampsForward(amount);for(var i=0;i<this.memoryDumps.length;i++)
+this.memoryDumps[i].shiftTimestampsForward(amount);for(var i=0;i<this.activities.length;i++)
+this.activities[i].shiftTimestampsForward(amount);tr.model.ProcessBase.prototype.shiftTimestampsForward.apply(this,arguments);},updateBounds:function(){tr.model.ProcessBase.prototype.updateBounds.apply(this);for(var i=0;i<this.frames.length;i++)
+this.frames[i].addBoundsToRange(this.bounds);for(var i=0;i<this.memoryDumps.length;i++)
+this.memoryDumps[i].addBoundsToRange(this.bounds);for(var i=0;i<this.activities.length;i++)
+this.activities[i].addBoundsToRange(this.bounds);},sortMemoryDumps:function(){this.memoryDumps.sort(function(x,y){return x.start-y.start;});tr.model.ProcessMemoryDump.hookUpMostRecentVmRegionsLinks(this.memoryDumps);}};return{Process:Process};});'use strict';tr.exportTo('tr.model',function(){function Sample(cpu,thread,title,start,leafStackFrame,opt_weight,opt_args){tr.model.TimedEvent.call(this,start);this.title=title;this.cpu=cpu;this.thread=thread;this.leafStackFrame=leafStackFrame;this.weight=opt_weight;this.args=opt_args||{};}
+Sample.prototype={__proto__:tr.model.TimedEvent.prototype,get colorId(){return this.leafStackFrame.colorId;},get stackTrace(){return this.leafStackFrame.stackTrace;},getUserFriendlyStackTrace:function(){return this.leafStackFrame.getUserFriendlyStackTrace();},get userFriendlyName(){return'Sample at '+tr.b.u.TimeStamp.format(this.start);}};tr.model.EventRegistry.register(Sample,{name:'sample',pluralName:'samples',singleViewElementName:'tr-ui-a-single-sample-sub-view',multiViewElementName:'tr-ui-a-multi-sample-sub-view'});return{Sample:Sample};});'use strict';tr.exportTo('tr.model',function(){function StackFrame(parentFrame,id,title,colorId,opt_sourceInfo){if(id===undefined)
+throw new Error('id must be given');this.parentFrame_=parentFrame;this.id=id;this.title_=title;this.colorId=colorId;this.children=[];this.sourceInfo_=opt_sourceInfo;if(this.parentFrame_)
+this.parentFrame_.addChild(this);}
+StackFrame.prototype={get parentFrame(){return this.parentFrame_;},get title(){if(this.sourceInfo_){var src=this.sourceInfo_.toString();return this.title_+(src===''?'':' '+src);}
+return this.title_;},get domain(){var result='unknown';if(this.sourceInfo_&&this.sourceInfo_.domain)
+result=this.sourceInfo_.domain;if(result==='unknown'&&this.parentFrame)
+result=this.parentFrame.domain;return result;},get sourceInfo(){return this.sourceInfo_;},set parentFrame(parentFrame){if(this.parentFrame_)
+this.parentFrame_.removeChild(this);this.parentFrame_=parentFrame;if(this.parentFrame_)
+this.parentFrame_.addChild(this);},addChild:function(child){this.children.push(child);},removeChild:function(child){var i=this.children.indexOf(child.id);if(i==-1)
+throw new Error('omg');this.children.splice(i,1);},removeAllChildren:function(){for(var i=0;i<this.children.length;i++)
+this.children[i].parentFrame_=undefined;this.children.splice(0,this.children.length);},get stackTrace(){var stack=[];var cur=this;while(cur){stack.push(cur);cur=cur.parentFrame;}
+return stack;},getUserFriendlyStackTrace:function(){return this.stackTrace.map(function(x){return x.title;});}};return{StackFrame:StackFrame};});'use strict';tr.exportTo('tr.ui.b',function(){function decorate(source,constr){var elements;if(typeof source=='string')
+elements=tr.doc.querySelectorAll(source);else
+elements=[source];for(var i=0,el;el=elements[i];i++){if(!(el instanceof constr))
+constr.decorate(el);}}
+function define(className,opt_parentConstructor,opt_tagNS){if(typeof className=='function'){throw new Error('Passing functions as className is deprecated. Please '+'use (className, opt_parentConstructor) to subclass');}
+var className=className.toLowerCase();if(opt_parentConstructor&&!opt_parentConstructor.tagName)
+throw new Error('opt_parentConstructor was not '+'created by tr.ui.b.define');var tagName=className;var tagNS=undefined;if(opt_parentConstructor){if(opt_tagNS)
+throw new Error('Must not specify tagNS if parentConstructor is given');var parent=opt_parentConstructor;while(parent&&parent.tagName){tagName=parent.tagName;tagNS=parent.tagNS;parent=parent.parentConstructor;}}else{tagNS=opt_tagNS;}
+function f(){if(opt_parentConstructor&&f.prototype.__proto__!=opt_parentConstructor.prototype){throw new Error(className+' prototye\'s __proto__ field is messed up. '+'It MUST be the prototype of '+opt_parentConstructor.tagName);}
+var el;if(tagNS===undefined)
+el=tr.doc.createElement(tagName);else
+el=tr.doc.createElementNS(tagNS,tagName);f.decorate.call(this,el,arguments);return el;}
+f.decorate=function(el){el.__proto__=f.prototype;el.decorate.apply(el,arguments[1]);el.constructor=f;};f.className=className;f.tagName=tagName;f.tagNS=tagNS;f.parentConstructor=(opt_parentConstructor?opt_parentConstructor:undefined);f.toString=function(){if(!f.parentConstructor)
+return f.tagName;return f.parentConstructor.toString()+'::'+f.className;};return f;}
+function elementIsChildOf(el,potentialParent){if(el==potentialParent)
+return false;var cur=el;while(cur.parentNode){if(cur==potentialParent)
+return true;cur=cur.parentNode;}
+return false;};return{decorate:decorate,define:define,elementIsChildOf:elementIsChildOf};});!function(t,n){if("object"==typeof exports&&"object"==typeof module)module.exports=n();else if("function"==typeof define&&define.amd)define(n);else{var r=n();for(var a in r)("object"==typeof exports?exports:t)[a]=r[a]}}(this,function(){return function(t){function n(a){if(r[a])return r[a].exports;var e=r[a]={exports:{},id:a,loaded:!1};return t[a].call(e.exports,e,e.exports,n),e.loaded=!0,e.exports}var r={};return n.m=t,n.c=r,n.p="",n(0)}([function(t,n,r){n.glMatrix=r(1),n.mat2=r(2),n.mat2d=r(3),n.mat3=r(4),n.mat4=r(5),n.quat=r(6),n.vec2=r(9),n.vec3=r(7),n.vec4=r(8)},function(t,n,r){var a={};a.EPSILON=1e-6,a.ARRAY_TYPE="undefined"!=typeof Float32Array?Float32Array:Array,a.RANDOM=Math.random,a.setMatrixArrayType=function(t){GLMAT_ARRAY_TYPE=t};var e=Math.PI/180;a.toRadian=function(t){return t*e},t.exports=a},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(4);return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t},e.clone=function(t){var n=new a.ARRAY_TYPE(4);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t},e.transpose=function(t,n){if(t===n){var r=n[1];t[1]=n[2],t[2]=r}else t[0]=n[0],t[1]=n[2],t[2]=n[1],t[3]=n[3];return t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*u-e*a;return o?(o=1/o,t[0]=u*o,t[1]=-a*o,t[2]=-e*o,t[3]=r*o,t):null},e.adjoint=function(t,n){var r=n[0];return t[0]=n[3],t[1]=-n[1],t[2]=-n[2],t[3]=r,t},e.determinant=function(t){return t[0]*t[3]-t[2]*t[1]},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],c=r[1],f=r[2],s=r[3];return t[0]=a*i+u*c,t[1]=e*i+o*c,t[2]=a*f+u*s,t[3]=e*f+o*s,t},e.mul=e.multiply,e.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c+u*i,t[1]=e*c+o*i,t[2]=a*-i+u*c,t[3]=e*-i+o*c,t},e.scale=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],c=r[1];return t[0]=a*i,t[1]=e*i,t[2]=u*c,t[3]=o*c,t},e.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=-r,t[3]=a,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=n[1],t},e.str=function(t){return"mat2("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2))},e.LDU=function(t,n,r,a){return t[2]=a[2]/a[0],r[0]=a[0],r[1]=a[1],r[3]=a[3]-t[2]*r[1],[t,n,r]},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(6);return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(6);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=r*u-a*e;return c?(c=1/c,t[0]=u*c,t[1]=-a*c,t[2]=-e*c,t[3]=r*c,t[4]=(e*i-u*o)*c,t[5]=(a*o-r*i)*c,t):null},e.determinant=function(t){return t[0]*t[3]-t[1]*t[2]},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=r[0],s=r[1],h=r[2],M=r[3],l=r[4],v=r[5];return t[0]=a*f+u*s,t[1]=e*f+o*s,t[2]=a*h+u*M,t[3]=e*h+o*M,t[4]=a*l+u*v+i,t[5]=e*l+o*v+c,t},e.mul=e.multiply,e.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=Math.sin(r),s=Math.cos(r);return t[0]=a*s+u*f,t[1]=e*s+o*f,t[2]=a*-f+u*s,t[3]=e*-f+o*s,t[4]=i,t[5]=c,t},e.scale=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=r[0],s=r[1];return t[0]=a*f,t[1]=e*f,t[2]=u*s,t[3]=o*s,t[4]=i,t[5]=c,t},e.translate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=r[0],s=r[1];return t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=a*f+u*s+i,t[5]=e*f+o*s+c,t},e.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=-r,t[3]=a,t[4]=0,t[5]=0,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=n[1],t[4]=0,t[5]=0,t},e.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=n[0],t[5]=n[1],t},e.str=function(t){return"mat2d("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+1)},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(9);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromMat4=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[4],t[4]=n[5],t[5]=n[6],t[6]=n[8],t[7]=n[9],t[8]=n[10],t},e.clone=function(t){var n=new a.ARRAY_TYPE(9);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.transpose=function(t,n){if(t===n){var r=n[1],a=n[2],e=n[5];t[1]=n[3],t[2]=n[6],t[3]=r,t[5]=n[7],t[6]=a,t[7]=e}else t[0]=n[0],t[1]=n[3],t[2]=n[6],t[3]=n[1],t[4]=n[4],t[5]=n[7],t[6]=n[2],t[7]=n[5],t[8]=n[8];return t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=s*o-i*f,M=-s*u+i*c,l=f*u-o*c,v=r*h+a*M+e*l;return v?(v=1/v,t[0]=h*v,t[1]=(-s*a+e*f)*v,t[2]=(i*a-e*o)*v,t[3]=M*v,t[4]=(s*r-e*c)*v,t[5]=(-i*r+e*u)*v,t[6]=l*v,t[7]=(-f*r+a*c)*v,t[8]=(o*r-a*u)*v,t):null},e.adjoint=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8];return t[0]=o*s-i*f,t[1]=e*f-a*s,t[2]=a*i-e*o,t[3]=i*c-u*s,t[4]=r*s-e*c,t[5]=e*u-r*i,t[6]=u*f-o*c,t[7]=a*c-r*f,t[8]=r*o-a*u,t},e.determinant=function(t){var n=t[0],r=t[1],a=t[2],e=t[3],u=t[4],o=t[5],i=t[6],c=t[7],f=t[8];return n*(f*u-o*c)+r*(-f*e+o*i)+a*(c*e-u*i)},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=r[0],l=r[1],v=r[2],m=r[3],p=r[4],d=r[5],A=r[6],R=r[7],w=r[8];return t[0]=M*a+l*o+v*f,t[1]=M*e+l*i+v*s,t[2]=M*u+l*c+v*h,t[3]=m*a+p*o+d*f,t[4]=m*e+p*i+d*s,t[5]=m*u+p*c+d*h,t[6]=A*a+R*o+w*f,t[7]=A*e+R*i+w*s,t[8]=A*u+R*c+w*h,t},e.mul=e.multiply,e.translate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=r[0],l=r[1];return t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=i,t[5]=c,t[6]=M*a+l*o+f,t[7]=M*e+l*i+s,t[8]=M*u+l*c+h,t},e.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=Math.sin(r),l=Math.cos(r);return t[0]=l*a+M*o,t[1]=l*e+M*i,t[2]=l*u+M*c,t[3]=l*o-M*a,t[4]=l*i-M*e,t[5]=l*c-M*u,t[6]=f,t[7]=s,t[8]=h,t},e.scale=function(t,n,r){var a=r[0],e=r[1];return t[0]=a*n[0],t[1]=a*n[1],t[2]=a*n[2],t[3]=e*n[3],t[4]=e*n[4],t[5]=e*n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t},e.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=n[0],t[7]=n[1],t[8]=1,t},e.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=0,t[3]=-r,t[4]=a,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=0,t[4]=n[1],t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromMat2d=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=0,t[3]=n[2],t[4]=n[3],t[5]=0,t[6]=n[4],t[7]=n[5],t[8]=1,t},e.fromQuat=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r+r,i=a+a,c=e+e,f=r*o,s=a*o,h=a*i,M=e*o,l=e*i,v=e*c,m=u*o,p=u*i,d=u*c;return t[0]=1-h-v,t[3]=s-d,t[6]=M+p,t[1]=s+d,t[4]=1-f-v,t[7]=l-m,t[2]=M-p,t[5]=l+m,t[8]=1-f-h,t},e.normalFromMat4=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=n[9],M=n[10],l=n[11],v=n[12],m=n[13],p=n[14],d=n[15],A=r*i-a*o,R=r*c-e*o,w=r*f-u*o,q=a*c-e*i,Y=a*f-u*i,g=e*f-u*c,y=s*m-h*v,x=s*p-M*v,P=s*d-l*v,E=h*p-M*m,T=h*d-l*m,b=M*d-l*p,D=A*b-R*T+w*E+q*P-Y*x+g*y;return D?(D=1/D,t[0]=(i*b-c*T+f*E)*D,t[1]=(c*P-o*b-f*x)*D,t[2]=(o*T-i*P+f*y)*D,t[3]=(e*T-a*b-u*E)*D,t[4]=(r*b-e*P+u*x)*D,t[5]=(a*P-r*T-u*y)*D,t[6]=(m*g-p*Y+d*q)*D,t[7]=(p*w-v*g-d*R)*D,t[8]=(v*Y-m*w+d*A)*D,t):null},e.str=function(t){return"mat3("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+Math.pow(t[6],2)+Math.pow(t[7],2)+Math.pow(t[8],2))},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(16);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.clone=function(t){var n=new a.ARRAY_TYPE(16);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t[9]=n[9],t[10]=n[10],t[11]=n[11],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.transpose=function(t,n){if(t===n){var r=n[1],a=n[2],e=n[3],u=n[6],o=n[7],i=n[11];t[1]=n[4],t[2]=n[8],t[3]=n[12],t[4]=r,t[6]=n[9],t[7]=n[13],t[8]=a,t[9]=u,t[11]=n[14],t[12]=e,t[13]=o,t[14]=i}else t[0]=n[0],t[1]=n[4],t[2]=n[8],t[3]=n[12],t[4]=n[1],t[5]=n[5],t[6]=n[9],t[7]=n[13],t[8]=n[2],t[9]=n[6],t[10]=n[10],t[11]=n[14],t[12]=n[3],t[13]=n[7],t[14]=n[11],t[15]=n[15];return t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=n[9],M=n[10],l=n[11],v=n[12],m=n[13],p=n[14],d=n[15],A=r*i-a*o,R=r*c-e*o,w=r*f-u*o,q=a*c-e*i,Y=a*f-u*i,g=e*f-u*c,y=s*m-h*v,x=s*p-M*v,P=s*d-l*v,E=h*p-M*m,T=h*d-l*m,b=M*d-l*p,D=A*b-R*T+w*E+q*P-Y*x+g*y;return D?(D=1/D,t[0]=(i*b-c*T+f*E)*D,t[1]=(e*T-a*b-u*E)*D,t[2]=(m*g-p*Y+d*q)*D,t[3]=(M*Y-h*g-l*q)*D,t[4]=(c*P-o*b-f*x)*D,t[5]=(r*b-e*P+u*x)*D,t[6]=(p*w-v*g-d*R)*D,t[7]=(s*g-M*w+l*R)*D,t[8]=(o*T-i*P+f*y)*D,t[9]=(a*P-r*T-u*y)*D,t[10]=(v*Y-m*w+d*A)*D,t[11]=(h*w-s*Y-l*A)*D,t[12]=(i*x-o*E-c*y)*D,t[13]=(r*E-a*x+e*y)*D,t[14]=(m*R-v*q-p*A)*D,t[15]=(s*q-h*R+M*A)*D,t):null},e.adjoint=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=n[9],M=n[10],l=n[11],v=n[12],m=n[13],p=n[14],d=n[15];return t[0]=i*(M*d-l*p)-h*(c*d-f*p)+m*(c*l-f*M),t[1]=-(a*(M*d-l*p)-h*(e*d-u*p)+m*(e*l-u*M)),t[2]=a*(c*d-f*p)-i*(e*d-u*p)+m*(e*f-u*c),t[3]=-(a*(c*l-f*M)-i*(e*l-u*M)+h*(e*f-u*c)),t[4]=-(o*(M*d-l*p)-s*(c*d-f*p)+v*(c*l-f*M)),t[5]=r*(M*d-l*p)-s*(e*d-u*p)+v*(e*l-u*M),t[6]=-(r*(c*d-f*p)-o*(e*d-u*p)+v*(e*f-u*c)),t[7]=r*(c*l-f*M)-o*(e*l-u*M)+s*(e*f-u*c),t[8]=o*(h*d-l*m)-s*(i*d-f*m)+v*(i*l-f*h),t[9]=-(r*(h*d-l*m)-s*(a*d-u*m)+v*(a*l-u*h)),t[10]=r*(i*d-f*m)-o*(a*d-u*m)+v*(a*f-u*i),t[11]=-(r*(i*l-f*h)-o*(a*l-u*h)+s*(a*f-u*i)),t[12]=-(o*(h*p-M*m)-s*(i*p-c*m)+v*(i*M-c*h)),t[13]=r*(h*p-M*m)-s*(a*p-e*m)+v*(a*M-e*h),t[14]=-(r*(i*p-c*m)-o*(a*p-e*m)+v*(a*c-e*i)),t[15]=r*(i*M-c*h)-o*(a*M-e*h)+s*(a*c-e*i),t},e.determinant=function(t){var n=t[0],r=t[1],a=t[2],e=t[3],u=t[4],o=t[5],i=t[6],c=t[7],f=t[8],s=t[9],h=t[10],M=t[11],l=t[12],v=t[13],m=t[14],p=t[15],d=n*o-r*u,A=n*i-a*u,R=n*c-e*u,w=r*i-a*o,q=r*c-e*o,Y=a*c-e*i,g=f*v-s*l,y=f*m-h*l,x=f*p-M*l,P=s*m-h*v,E=s*p-M*v,T=h*p-M*m;return d*T-A*E+R*P+w*x-q*y+Y*g},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=n[9],l=n[10],v=n[11],m=n[12],p=n[13],d=n[14],A=n[15],R=r[0],w=r[1],q=r[2],Y=r[3];return t[0]=R*a+w*i+q*h+Y*m,t[1]=R*e+w*c+q*M+Y*p,t[2]=R*u+w*f+q*l+Y*d,t[3]=R*o+w*s+q*v+Y*A,R=r[4],w=r[5],q=r[6],Y=r[7],t[4]=R*a+w*i+q*h+Y*m,t[5]=R*e+w*c+q*M+Y*p,t[6]=R*u+w*f+q*l+Y*d,t[7]=R*o+w*s+q*v+Y*A,R=r[8],w=r[9],q=r[10],Y=r[11],t[8]=R*a+w*i+q*h+Y*m,t[9]=R*e+w*c+q*M+Y*p,t[10]=R*u+w*f+q*l+Y*d,t[11]=R*o+w*s+q*v+Y*A,R=r[12],w=r[13],q=r[14],Y=r[15],t[12]=R*a+w*i+q*h+Y*m,t[13]=R*e+w*c+q*M+Y*p,t[14]=R*u+w*f+q*l+Y*d,t[15]=R*o+w*s+q*v+Y*A,t},e.mul=e.multiply,e.translate=function(t,n,r){var a,e,u,o,i,c,f,s,h,M,l,v,m=r[0],p=r[1],d=r[2];return n===t?(t[12]=n[0]*m+n[4]*p+n[8]*d+n[12],t[13]=n[1]*m+n[5]*p+n[9]*d+n[13],t[14]=n[2]*m+n[6]*p+n[10]*d+n[14],t[15]=n[3]*m+n[7]*p+n[11]*d+n[15]):(a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=n[9],l=n[10],v=n[11],t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=i,t[5]=c,t[6]=f,t[7]=s,t[8]=h,t[9]=M,t[10]=l,t[11]=v,t[12]=a*m+i*p+h*d+n[12],t[13]=e*m+c*p+M*d+n[13],t[14]=u*m+f*p+l*d+n[14],t[15]=o*m+s*p+v*d+n[15]),t},e.scale=function(t,n,r){var a=r[0],e=r[1],u=r[2];return t[0]=n[0]*a,t[1]=n[1]*a,t[2]=n[2]*a,t[3]=n[3]*a,t[4]=n[4]*e,t[5]=n[5]*e,t[6]=n[6]*e,t[7]=n[7]*e,t[8]=n[8]*u,t[9]=n[9]*u,t[10]=n[10]*u,t[11]=n[11]*u,t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15],t},e.rotate=function(t,n,r,e){var u,o,i,c,f,s,h,M,l,v,m,p,d,A,R,w,q,Y,g,y,x,P,E,T,b=e[0],D=e[1],L=e[2],_=Math.sqrt(b*b+D*D+L*L);return Math.abs(_)<a.EPSILON?null:(_=1/_,b*=_,D*=_,L*=_,u=Math.sin(r),o=Math.cos(r),i=1-o,c=n[0],f=n[1],s=n[2],h=n[3],M=n[4],l=n[5],v=n[6],m=n[7],p=n[8],d=n[9],A=n[10],R=n[11],w=b*b*i+o,q=D*b*i+L*u,Y=L*b*i-D*u,g=b*D*i-L*u,y=D*D*i+o,x=L*D*i+b*u,P=b*L*i+D*u,E=D*L*i-b*u,T=L*L*i+o,t[0]=c*w+M*q+p*Y,t[1]=f*w+l*q+d*Y,t[2]=s*w+v*q+A*Y,t[3]=h*w+m*q+R*Y,t[4]=c*g+M*y+p*x,t[5]=f*g+l*y+d*x,t[6]=s*g+v*y+A*x,t[7]=h*g+m*y+R*x,t[8]=c*P+M*E+p*T,t[9]=f*P+l*E+d*T,t[10]=s*P+v*E+A*T,t[11]=h*P+m*E+R*T,n!==t&&(t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t)},e.rotateX=function(t,n,r){var a=Math.sin(r),e=Math.cos(r),u=n[4],o=n[5],i=n[6],c=n[7],f=n[8],s=n[9],h=n[10],M=n[11];return n!==t&&(t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t[4]=u*e+f*a,t[5]=o*e+s*a,t[6]=i*e+h*a,t[7]=c*e+M*a,t[8]=f*e-u*a,t[9]=s*e-o*a,t[10]=h*e-i*a,t[11]=M*e-c*a,t},e.rotateY=function(t,n,r){var a=Math.sin(r),e=Math.cos(r),u=n[0],o=n[1],i=n[2],c=n[3],f=n[8],s=n[9],h=n[10],M=n[11];return n!==t&&(t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t[0]=u*e-f*a,t[1]=o*e-s*a,t[2]=i*e-h*a,t[3]=c*e-M*a,t[8]=u*a+f*e,t[9]=o*a+s*e,t[10]=i*a+h*e,t[11]=c*a+M*e,t},e.rotateZ=function(t,n,r){var a=Math.sin(r),e=Math.cos(r),u=n[0],o=n[1],i=n[2],c=n[3],f=n[4],s=n[5],h=n[6],M=n[7];return n!==t&&(t[8]=n[8],t[9]=n[9],t[10]=n[10],t[11]=n[11],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t[0]=u*e+f*a,t[1]=o*e+s*a,t[2]=i*e+h*a,t[3]=c*e+M*a,t[4]=f*e-u*a,t[5]=s*e-o*a,t[6]=h*e-i*a,t[7]=M*e-c*a,t},e.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=n[0],t[13]=n[1],t[14]=n[2],t[15]=1,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=n[1],t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=n[2],t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromRotation=function(t,n,r){var e,u,o,i=r[0],c=r[1],f=r[2],s=Math.sqrt(i*i+c*c+f*f);return Math.abs(s)<a.EPSILON?null:(s=1/s,i*=s,c*=s,f*=s,e=Math.sin(n),u=Math.cos(n),o=1-u,t[0]=i*i*o+u,t[1]=c*i*o+f*e,t[2]=f*i*o-c*e,t[3]=0,t[4]=i*c*o-f*e,t[5]=c*c*o+u,t[6]=f*c*o+i*e,t[7]=0,t[8]=i*f*o+c*e,t[9]=c*f*o-i*e,t[10]=f*f*o+u,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t)},e.fromXRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=a,t[6]=r,t[7]=0,t[8]=0,t[9]=-r,t[10]=a,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromYRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=0,t[2]=-r,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=r,t[9]=0,t[10]=a,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromZRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=0,t[3]=0,t[4]=-r,t[5]=a,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromRotationTranslation=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=a+a,c=e+e,f=u+u,s=a*i,h=a*c,M=a*f,l=e*c,v=e*f,m=u*f,p=o*i,d=o*c,A=o*f;return t[0]=1-(l+m),t[1]=h+A,t[2]=M-d,t[3]=0,t[4]=h-A,t[5]=1-(s+m),t[6]=v+p,t[7]=0,t[8]=M+d,t[9]=v-p,t[10]=1-(s+l),t[11]=0,t[12]=r[0],t[13]=r[1],t[14]=r[2],t[15]=1,t},e.fromRotationTranslationScale=function(t,n,r,a){var e=n[0],u=n[1],o=n[2],i=n[3],c=e+e,f=u+u,s=o+o,h=e*c,M=e*f,l=e*s,v=u*f,m=u*s,p=o*s,d=i*c,A=i*f,R=i*s,w=a[0],q=a[1],Y=a[2];return t[0]=(1-(v+p))*w,t[1]=(M+R)*w,t[2]=(l-A)*w,t[3]=0,t[4]=(M-R)*q,t[5]=(1-(h+p))*q,t[6]=(m+d)*q,t[7]=0,t[8]=(l+A)*Y,t[9]=(m-d)*Y,t[10]=(1-(h+v))*Y,t[11]=0,t[12]=r[0],t[13]=r[1],t[14]=r[2],t[15]=1,t},e.fromRotationTranslationScaleOrigin=function(t,n,r,a,e){var u=n[0],o=n[1],i=n[2],c=n[3],f=u+u,s=o+o,h=i+i,M=u*f,l=u*s,v=u*h,m=o*s,p=o*h,d=i*h,A=c*f,R=c*s,w=c*h,q=a[0],Y=a[1],g=a[2],y=e[0],x=e[1],P=e[2];return t[0]=(1-(m+d))*q,t[1]=(l+w)*q,t[2]=(v-R)*q,t[3]=0,t[4]=(l-w)*Y,t[5]=(1-(M+d))*Y,t[6]=(p+A)*Y,t[7]=0,t[8]=(v+R)*g,t[9]=(p-A)*g,t[10]=(1-(M+m))*g,t[11]=0,t[12]=r[0]+y-(t[0]*y+t[4]*x+t[8]*P),t[13]=r[1]+x-(t[1]*y+t[5]*x+t[9]*P),t[14]=r[2]+P-(t[2]*y+t[6]*x+t[10]*P),t[15]=1,t},e.fromQuat=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r+r,i=a+a,c=e+e,f=r*o,s=a*o,h=a*i,M=e*o,l=e*i,v=e*c,m=u*o,p=u*i,d=u*c;return t[0]=1-h-v,t[1]=s+d,t[2]=M-p,t[3]=0,t[4]=s-d,t[5]=1-f-v,t[6]=l+m,t[7]=0,t[8]=M+p,t[9]=l-m,t[10]=1-f-h,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.frustum=function(t,n,r,a,e,u,o){var i=1/(r-n),c=1/(e-a),f=1/(u-o);return t[0]=2*u*i,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=2*u*c,t[6]=0,t[7]=0,t[8]=(r+n)*i,t[9]=(e+a)*c,t[10]=(o+u)*f,t[11]=-1,t[12]=0,t[13]=0,t[14]=o*u*2*f,t[15]=0,t},e.perspective=function(t,n,r,a,e){var u=1/Math.tan(n/2),o=1/(a-e);return t[0]=u/r,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=u,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=(e+a)*o,t[11]=-1,t[12]=0,t[13]=0,t[14]=2*e*a*o,t[15]=0,t},e.perspectiveFromFieldOfView=function(t,n,r,a){var e=Math.tan(n.upDegrees*Math.PI/180),u=Math.tan(n.downDegrees*Math.PI/180),o=Math.tan(n.leftDegrees*Math.PI/180),i=Math.tan(n.rightDegrees*Math.PI/180),c=2/(o+i),f=2/(e+u);return t[0]=c,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=f,t[6]=0,t[7]=0,t[8]=-((o-i)*c*.5),t[9]=(e-u)*f*.5,t[10]=a/(r-a),t[11]=-1,t[12]=0,t[13]=0,t[14]=a*r/(r-a),t[15]=0,t},e.ortho=function(t,n,r,a,e,u,o){var i=1/(n-r),c=1/(a-e),f=1/(u-o);return t[0]=-2*i,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=-2*c,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=2*f,t[11]=0,t[12]=(n+r)*i,t[13]=(e+a)*c,t[14]=(o+u)*f,t[15]=1,t},e.lookAt=function(t,n,r,u){var o,i,c,f,s,h,M,l,v,m,p=n[0],d=n[1],A=n[2],R=u[0],w=u[1],q=u[2],Y=r[0],g=r[1],y=r[2];return Math.abs(p-Y)<a.EPSILON&&Math.abs(d-g)<a.EPSILON&&Math.abs(A-y)<a.EPSILON?e.identity(t):(M=p-Y,l=d-g,v=A-y,m=1/Math.sqrt(M*M+l*l+v*v),M*=m,l*=m,v*=m,o=w*v-q*l,i=q*M-R*v,c=R*l-w*M,m=Math.sqrt(o*o+i*i+c*c),m?(m=1/m,o*=m,i*=m,c*=m):(o=0,i=0,c=0),f=l*c-v*i,s=v*o-M*c,h=M*i-l*o,m=Math.sqrt(f*f+s*s+h*h),m?(m=1/m,f*=m,s*=m,h*=m):(f=0,s=0,h=0),t[0]=o,t[1]=f,t[2]=M,t[3]=0,t[4]=i,t[5]=s,t[6]=l,t[7]=0,t[8]=c,t[9]=h,t[10]=v,t[11]=0,t[12]=-(o*p+i*d+c*A),t[13]=-(f*p+s*d+h*A),t[14]=-(M*p+l*d+v*A),t[15]=1,t)},e.str=function(t){return"mat4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+", "+t[9]+", "+t[10]+", "+t[11]+", "+t[12]+", "+t[13]+", "+t[14]+", "+t[15]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+Math.pow(t[6],2)+Math.pow(t[7],2)+Math.pow(t[8],2)+Math.pow(t[9],2)+Math.pow(t[10],2)+Math.pow(t[11],2)+Math.pow(t[12],2)+Math.pow(t[13],2)+Math.pow(t[14],2)+Math.pow(t[15],2))},t.exports=e},function(t,n,r){var a=r(1),e=r(4),u=r(7),o=r(8),i={};i.create=function(){var t=new a.ARRAY_TYPE(4);return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},i.rotationTo=function(){var t=u.create(),n=u.fromValues(1,0,0),r=u.fromValues(0,1,0);return function(a,e,o){var c=u.dot(e,o);return-.999999>c?(u.cross(t,n,e),u.length(t)<1e-6&&u.cross(t,r,e),u.normalize(t,t),i.setAxisAngle(a,t,Math.PI),a):c>.999999?(a[0]=0,a[1]=0,a[2]=0,a[3]=1,a):(u.cross(t,e,o),a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=1+c,i.normalize(a,a))}}(),i.setAxes=function(){var t=e.create();return function(n,r,a,e){return t[0]=a[0],t[3]=a[1],t[6]=a[2],t[1]=e[0],t[4]=e[1],t[7]=e[2],t[2]=-r[0],t[5]=-r[1],t[8]=-r[2],i.normalize(n,i.fromMat3(n,t))}}(),i.clone=o.clone,i.fromValues=o.fromValues,i.copy=o.copy,i.set=o.set,i.identity=function(t){return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},i.setAxisAngle=function(t,n,r){r=.5*r;var a=Math.sin(r);return t[0]=a*n[0],t[1]=a*n[1],t[2]=a*n[2],t[3]=Math.cos(r),t},i.add=o.add,i.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],c=r[1],f=r[2],s=r[3];return t[0]=a*s+o*i+e*f-u*c,t[1]=e*s+o*c+u*i-a*f,t[2]=u*s+o*f+a*c-e*i,t[3]=o*s-a*i-e*c-u*f,t},i.mul=i.multiply,i.scale=o.scale,i.rotateX=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c+o*i,t[1]=e*c+u*i,t[2]=u*c-e*i,t[3]=o*c-a*i,t},i.rotateY=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c-u*i,t[1]=e*c+o*i,t[2]=u*c+a*i,t[3]=o*c-e*i,t},i.rotateZ=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c+e*i,t[1]=e*c-a*i,t[2]=u*c+o*i,t[3]=o*c-u*i,t},i.calculateW=function(t,n){var r=n[0],a=n[1],e=n[2];return t[0]=r,t[1]=a,t[2]=e,t[3]=Math.sqrt(Math.abs(1-r*r-a*a-e*e)),t},i.dot=o.dot,i.lerp=o.lerp,i.slerp=function(t,n,r,a){var e,u,o,i,c,f=n[0],s=n[1],h=n[2],M=n[3],l=r[0],v=r[1],m=r[2],p=r[3];return u=f*l+s*v+h*m+M*p,0>u&&(u=-u,l=-l,v=-v,m=-m,p=-p),1-u>1e-6?(e=Math.acos(u),o=Math.sin(e),i=Math.sin((1-a)*e)/o,c=Math.sin(a*e)/o):(i=1-a,c=a),t[0]=i*f+c*l,t[1]=i*s+c*v,t[2]=i*h+c*m,t[3]=i*M+c*p,t},i.sqlerp=function(){var t=i.create(),n=i.create();return function(r,a,e,u,o,c){return i.slerp(t,a,o,c),i.slerp(n,e,u,c),i.slerp(r,t,n,2*c*(1-c)),r}}(),i.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*r+a*a+e*e+u*u,i=o?1/o:0;return t[0]=-r*i,t[1]=-a*i,t[2]=-e*i,t[3]=u*i,t},i.conjugate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t[3]=n[3],t},i.length=o.length,i.len=i.length,i.squaredLength=o.squaredLength,i.sqrLen=i.squaredLength,i.normalize=o.normalize,i.fromMat3=function(t,n){var r,a=n[0]+n[4]+n[8];if(a>0)r=Math.sqrt(a+1),t[3]=.5*r,r=.5/r,t[0]=(n[5]-n[7])*r,t[1]=(n[6]-n[2])*r,t[2]=(n[1]-n[3])*r;else{var e=0;n[4]>n[0]&&(e=1),n[8]>n[3*e+e]&&(e=2);var u=(e+1)%3,o=(e+2)%3;r=Math.sqrt(n[3*e+e]-n[3*u+u]-n[3*o+o]+1),t[e]=.5*r,r=.5/r,t[3]=(n[3*u+o]-n[3*o+u])*r,t[u]=(n[3*u+e]+n[3*e+u])*r,t[o]=(n[3*o+e]+n[3*e+o])*r}return t},i.str=function(t){return"quat("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},t.exports=i},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(3);return t[0]=0,t[1]=0,t[2]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(3);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n},e.fromValues=function(t,n,r){var e=new a.ARRAY_TYPE(3);return e[0]=t,e[1]=n,e[2]=r,e},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t},e.set=function(t,n,r,a){return t[0]=n,t[1]=r,t[2]=a,t},e.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t[2]=n[2]+r[2],t},e.subtract=function(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t[2]=n[2]-r[2],t},e.sub=e.subtract,e.multiply=function(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t[2]=n[2]*r[2],t},e.mul=e.multiply,e.divide=function(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t[2]=n[2]/r[2],t},e.div=e.divide,e.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t[2]=Math.min(n[2],r[2]),t},e.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t[2]=Math.max(n[2],r[2]),t},e.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t},e.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t[2]=n[2]+r[2]*a,t},e.distance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2];return Math.sqrt(r*r+a*a+e*e)},e.dist=e.distance,e.squaredDistance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2];return r*r+a*a+e*e},e.sqrDist=e.squaredDistance,e.length=function(t){var n=t[0],r=t[1],a=t[2];return Math.sqrt(n*n+r*r+a*a)},e.len=e.length,e.squaredLength=function(t){var n=t[0],r=t[1],a=t[2];return n*n+r*r+a*a},e.sqrLen=e.squaredLength,e.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t},e.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t[2]=1/n[2],t},e.normalize=function(t,n){var r=n[0],a=n[1],e=n[2],u=r*r+a*a+e*e;return u>0&&(u=1/Math.sqrt(u),t[0]=n[0]*u,t[1]=n[1]*u,t[2]=n[2]*u),t},e.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]},e.cross=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],c=r[2];return t[0]=e*c-u*i,t[1]=u*o-a*c,t[2]=a*i-e*o,t},e.lerp=function(t,n,r,a){var e=n[0],u=n[1],o=n[2];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t[2]=o+a*(r[2]-o),t},e.hermite=function(t,n,r,a,e,u){var o=u*u,i=o*(2*u-3)+1,c=o*(u-2)+u,f=o*(u-1),s=o*(3-2*u);return t[0]=n[0]*i+r[0]*c+a[0]*f+e[0]*s,t[1]=n[1]*i+r[1]*c+a[1]*f+e[1]*s,t[2]=n[2]*i+r[2]*c+a[2]*f+e[2]*s,t},e.bezier=function(t,n,r,a,e,u){var o=1-u,i=o*o,c=u*u,f=i*o,s=3*u*i,h=3*c*o,M=c*u;return t[0]=n[0]*f+r[0]*s+a[0]*h+e[0]*M,t[1]=n[1]*f+r[1]*s+a[1]*h+e[1]*M,t[2]=n[2]*f+r[2]*s+a[2]*h+e[2]*M,t},e.random=function(t,n){n=n||1;var r=2*a.RANDOM()*Math.PI,e=2*a.RANDOM()-1,u=Math.sqrt(1-e*e)*n;return t[0]=Math.cos(r)*u,t[1]=Math.sin(r)*u,t[2]=e*n,t},e.transformMat4=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[3]*a+r[7]*e+r[11]*u+r[15];return o=o||1,t[0]=(r[0]*a+r[4]*e+r[8]*u+r[12])/o,t[1]=(r[1]*a+r[5]*e+r[9]*u+r[13])/o,t[2]=(r[2]*a+r[6]*e+r[10]*u+r[14])/o,t},e.transformMat3=function(t,n,r){var a=n[0],e=n[1],u=n[2];return t[0]=a*r[0]+e*r[3]+u*r[6],t[1]=a*r[1]+e*r[4]+u*r[7],t[2]=a*r[2]+e*r[5]+u*r[8],t},e.transformQuat=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],c=r[2],f=r[3],s=f*a+i*u-c*e,h=f*e+c*a-o*u,M=f*u+o*e-i*a,l=-o*a-i*e-c*u;return t[0]=s*f+l*-o+h*-c-M*-i,t[1]=h*f+l*-i+M*-o-s*-c,t[2]=M*f+l*-c+s*-i-h*-o,t},e.rotateX=function(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[0],u[1]=e[1]*Math.cos(a)-e[2]*Math.sin(a),u[2]=e[1]*Math.sin(a)+e[2]*Math.cos(a),t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t},e.rotateY=function(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[2]*Math.sin(a)+e[0]*Math.cos(a),u[1]=e[1],u[2]=e[2]*Math.cos(a)-e[0]*Math.sin(a),t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t},e.rotateZ=function(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[0]*Math.cos(a)-e[1]*Math.sin(a),u[1]=e[0]*Math.sin(a)+e[1]*Math.cos(a),u[2]=e[2],t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t},e.forEach=function(){var t=e.create();return function(n,r,a,e,u,o){var i,c;for(r||(r=3),a||(a=0),c=e?Math.min(e*r+a,n.length):n.length,i=a;c>i;i+=r)t[0]=n[i],t[1]=n[i+1],t[2]=n[i+2],u(t,t,o),n[i]=t[0],n[i+1]=t[1],n[i+2]=t[2];return n}}(),e.angle=function(t,n){var r=e.fromValues(t[0],t[1],t[2]),a=e.fromValues(n[0],n[1],n[2]);e.normalize(r,r),e.normalize(a,a);var u=e.dot(r,a);return u>1?0:Math.acos(u)},e.str=function(t){return"vec3("+t[0]+", "+t[1]+", "+t[2]+")"},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(4);return t[0]=0,t[1]=0,t[2]=0,t[3]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(4);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n},e.fromValues=function(t,n,r,e){var u=new a.ARRAY_TYPE(4);return u[0]=t,u[1]=n,u[2]=r,u[3]=e,u},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t},e.set=function(t,n,r,a,e){return t[0]=n,t[1]=r,t[2]=a,t[3]=e,t},e.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t[2]=n[2]+r[2],t[3]=n[3]+r[3],t},e.subtract=function(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t[2]=n[2]-r[2],t[3]=n[3]-r[3],t},e.sub=e.subtract,e.multiply=function(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t[2]=n[2]*r[2],t[3]=n[3]*r[3],t},e.mul=e.multiply,e.divide=function(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t[2]=n[2]/r[2],t[3]=n[3]/r[3],t},e.div=e.divide,e.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t[2]=Math.min(n[2],r[2]),t[3]=Math.min(n[3],r[3]),t},e.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t[2]=Math.max(n[2],r[2]),t[3]=Math.max(n[3],r[3]),t},e.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t[3]=n[3]*r,t},e.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t[2]=n[2]+r[2]*a,t[3]=n[3]+r[3]*a,t},e.distance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2],u=n[3]-t[3];return Math.sqrt(r*r+a*a+e*e+u*u)},e.dist=e.distance,e.squaredDistance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2],u=n[3]-t[3];return r*r+a*a+e*e+u*u},e.sqrDist=e.squaredDistance,e.length=function(t){var n=t[0],r=t[1],a=t[2],e=t[3];return Math.sqrt(n*n+r*r+a*a+e*e)},e.len=e.length,e.squaredLength=function(t){var n=t[0],r=t[1],a=t[2],e=t[3];return n*n+r*r+a*a+e*e},e.sqrLen=e.squaredLength,e.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t[3]=-n[3],t},e.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t[2]=1/n[2],t[3]=1/n[3],t},e.normalize=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*r+a*a+e*e+u*u;return o>0&&(o=1/Math.sqrt(o),t[0]=r*o,t[1]=a*o,t[2]=e*o,t[3]=u*o),t},e.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]+t[3]*n[3]},e.lerp=function(t,n,r,a){var e=n[0],u=n[1],o=n[2],i=n[3];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t[2]=o+a*(r[2]-o),t[3]=i+a*(r[3]-i),t},e.random=function(t,n){return n=n||1,t[0]=a.RANDOM(),t[1]=a.RANDOM(),t[2]=a.RANDOM(),t[3]=a.RANDOM(),e.normalize(t,t),e.scale(t,t,n),t},e.transformMat4=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3];return t[0]=r[0]*a+r[4]*e+r[8]*u+r[12]*o,t[1]=r[1]*a+r[5]*e+r[9]*u+r[13]*o,t[2]=r[2]*a+r[6]*e+r[10]*u+r[14]*o,t[3]=r[3]*a+r[7]*e+r[11]*u+r[15]*o,t},e.transformQuat=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],c=r[2],f=r[3],s=f*a+i*u-c*e,h=f*e+c*a-o*u,M=f*u+o*e-i*a,l=-o*a-i*e-c*u;return t[0]=s*f+l*-o+h*-c-M*-i,t[1]=h*f+l*-i+M*-o-s*-c,t[2]=M*f+l*-c+s*-i-h*-o,t[3]=n[3],t},e.forEach=function(){var t=e.create();return function(n,r,a,e,u,o){var i,c;for(r||(r=4),a||(a=0),c=e?Math.min(e*r+a,n.length):n.length,i=a;c>i;i+=r)t[0]=n[i],t[1]=n[i+1],t[2]=n[i+2],t[3]=n[i+3],u(t,t,o),n[i]=t[0],n[i+1]=t[1],n[i+2]=t[2],n[i+3]=t[3];return n}}(),e.str=function(t){return"vec4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(2);return t[0]=0,t[1]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(2);return n[0]=t[0],n[1]=t[1],n},e.fromValues=function(t,n){var r=new a.ARRAY_TYPE(2);return r[0]=t,r[1]=n,r},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t},e.set=function(t,n,r){return t[0]=n,t[1]=r,t},e.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t},e.subtract=function(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t},e.sub=e.subtract,e.multiply=function(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t},e.mul=e.multiply,e.divide=function(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t},e.div=e.divide,e.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t},e.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t},e.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t},e.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t},e.distance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1];return Math.sqrt(r*r+a*a)},e.dist=e.distance,e.squaredDistance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1];return r*r+a*a},e.sqrDist=e.squaredDistance,e.length=function(t){var n=t[0],r=t[1];return Math.sqrt(n*n+r*r)},e.len=e.length,e.squaredLength=function(t){var n=t[0],r=t[1];return n*n+r*r},e.sqrLen=e.squaredLength,e.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t},e.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t},e.normalize=function(t,n){var r=n[0],a=n[1],e=r*r+a*a;return e>0&&(e=1/Math.sqrt(e),t[0]=n[0]*e,t[1]=n[1]*e),t},e.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]},e.cross=function(t,n,r){var a=n[0]*r[1]-n[1]*r[0];return t[0]=t[1]=0,t[2]=a,t},e.lerp=function(t,n,r,a){var e=n[0],u=n[1];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t},e.random=function(t,n){n=n||1;var r=2*a.RANDOM()*Math.PI;return t[0]=Math.cos(r)*n,t[1]=Math.sin(r)*n,t},e.transformMat2=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[2]*e,t[1]=r[1]*a+r[3]*e,t},e.transformMat2d=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[2]*e+r[4],t[1]=r[1]*a+r[3]*e+r[5],t},e.transformMat3=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[3]*e+r[6],t[1]=r[1]*a+r[4]*e+r[7],t},e.transformMat4=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[4]*e+r[12],t[1]=r[1]*a+r[5]*e+r[13],t},e.forEach=function(){var t=e.create();return function(n,r,a,e,u,o){var i,c;for(r||(r=2),a||(a=0),c=e?Math.min(e*r+a,n.length):n.length,i=a;c>i;i+=r)t[0]=n[i],t[1]=n[i+1],u(t,t,o),n[i]=t[0],n[i+1]=t[1];return n}}(),e.str=function(t){return"vec2("+t[0]+", "+t[1]+")"},t.exports=e}])});'use strict';tr.exportTo('tr.b',function(){function clamp(x,lo,hi){return Math.min(Math.max(x,lo),hi);}
+function lerp(percentage,lo,hi){var range=hi-lo;return lo+percentage*range;}
+function normalize(value,lo,hi){return(value-lo)/(hi-lo);}
+function deg2rad(deg){return(Math.PI*deg)/180.0;}
+var tmp_vec2=vec2.create();var tmp_vec2b=vec2.create();var tmp_vec4=vec4.create();var tmp_mat2d=mat2d.create();vec2.createFromArray=function(arr){if(arr.length!=2)
+throw new Error('Should be length 2');var v=vec2.create();vec2.set(v,arr[0],arr[1]);return v;};vec2.createXY=function(x,y){var v=vec2.create();vec2.set(v,x,y);return v;};vec2.toString=function(a){return'['+a[0]+', '+a[1]+']';};vec2.addTwoScaledUnitVectors=function(out,u1,scale1,u2,scale2){vec2.scale(tmp_vec2,u1,scale1);vec2.scale(tmp_vec2b,u2,scale2);vec2.add(out,tmp_vec2,tmp_vec2b);};vec2.interpolatePiecewiseFunction=function(points,x){if(x<points[0][0])
+return points[0][1];for(var i=1;i<points.length;++i){if(x<points[i][0]){var percent=normalize(x,points[i-1][0],points[i][0]);return lerp(percent,points[i-1][1],points[i][1]);}}
+return points[points.length-1][1];};vec3.createXYZ=function(x,y,z){var v=vec3.create();vec3.set(v,x,y,z);return v;};vec3.toString=function(a){return'vec3('+a[0]+', '+a[1]+', '+a[2]+')';}
+mat2d.translateXY=function(out,x,y){vec2.set(tmp_vec2,x,y);mat2d.translate(out,out,tmp_vec2);}
+mat2d.scaleXY=function(out,x,y){vec2.set(tmp_vec2,x,y);mat2d.scale(out,out,tmp_vec2);}
+vec4.unitize=function(out,a){out[0]=a[0]/a[3];out[1]=a[1]/a[3];out[2]=a[2]/a[3];out[3]=1;return out;}
+vec2.copyFromVec4=function(out,a){vec4.unitize(tmp_vec4,a);vec2.copy(out,tmp_vec4);}
+return{clamp:clamp,lerp:lerp,normalize:normalize,deg2rad:deg2rad};});'use strict';tr.exportTo('tr.b',function(){function Rect(){this.x=0;this.y=0;this.width=0;this.height=0;};Rect.fromXYWH=function(x,y,w,h){var rect=new Rect();rect.x=x;rect.y=y;rect.width=w;rect.height=h;return rect;}
+Rect.fromArray=function(ary){if(ary.length!=4)
+throw new Error('ary.length must be 4');var rect=new Rect();rect.x=ary[0];rect.y=ary[1];rect.width=ary[2];rect.height=ary[3];return rect;}
+Rect.prototype={__proto__:Object.prototype,get left(){return this.x;},get top(){return this.y;},get right(){return this.x+this.width;},get bottom(){return this.y+this.height;},toString:function(){return'Rect('+this.x+', '+this.y+', '+
+this.width+', '+this.height+')';},toArray:function(){return[this.x,this.y,this.width,this.height];},clone:function(){var rect=new Rect();rect.x=this.x;rect.y=this.y;rect.width=this.width;rect.height=this.height;return rect;},enlarge:function(pad){var rect=new Rect();this.enlargeFast(rect,pad);return rect;},enlargeFast:function(out,pad){out.x=this.x-pad;out.y=this.y-pad;out.width=this.width+2*pad;out.height=this.height+2*pad;return out;},size:function(){return{width:this.width,height:this.height};},scale:function(s){var rect=new Rect();this.scaleFast(rect,s);return rect;},scaleSize:function(s){return Rect.fromXYWH(this.x,this.y,this.width*s,this.height*s);},scaleFast:function(out,s){out.x=this.x*s;out.y=this.y*s;out.width=this.width*s;out.height=this.height*s;return out;},translate:function(v){var rect=new Rect();this.translateFast(rect,v);return rect;},translateFast:function(out,v){out.x=this.x+v[0];out.y=this.x+v[1];out.width=this.width;out.height=this.height;return out;},asUVRectInside:function(containingRect){var rect=new Rect();rect.x=(this.x-containingRect.x)/containingRect.width;rect.y=(this.y-containingRect.y)/containingRect.height;rect.width=this.width/containingRect.width;rect.height=this.height/containingRect.height;return rect;},intersects:function(that){var ok=true;ok&=this.x<that.right;ok&=this.right>that.x;ok&=this.y<that.bottom;ok&=this.bottom>that.y;return ok;},equalTo:function(rect){return rect&&(this.x===rect.x)&&(this.y===rect.y)&&(this.width===rect.width)&&(this.height===rect.height);}};return{Rect:Rect};});'use strict';tr.exportTo('tr.ui.b',function(){function instantiateTemplate(selector,doc){doc=doc||document;var el=doc.querySelector(selector);if(!el)
+throw new Error('Element not found');return el.createInstance();}
+function windowRectForElement(element){var position=[element.offsetLeft,element.offsetTop];var size=[element.offsetWidth,element.offsetHeight];var node=element.offsetParent;while(node){position[0]+=node.offsetLeft;position[1]+=node.offsetTop;node=node.offsetParent;}
+return tr.b.Rect.fromXYWH(position[0],position[1],size[0],size[1]);}
+function scrollIntoViewIfNeeded(el){var pr=el.parentElement.getBoundingClientRect();var cr=el.getBoundingClientRect();if(cr.top<pr.top){el.scrollIntoView(true);}else if(cr.bottom>pr.bottom){el.scrollIntoView(false);}}
+return{instantiateTemplate:instantiateTemplate,windowRectForElement:windowRectForElement,scrollIntoViewIfNeeded:scrollIntoViewIfNeeded};});'use strict';tr.exportTo('tr.ui.b',function(){if(tr.isHeadless)
+return{};var THIS_DOC=document.currentScript.ownerDocument;var Overlay=tr.ui.b.define('overlay');Overlay.prototype={__proto__:HTMLDivElement.prototype,decorate:function(){this.classList.add('overlay');this.parentEl_=this.ownerDocument.body;this.visible_=false;this.userCanClose_=true;this.onKeyDown_=this.onKeyDown_.bind(this);this.onClick_=this.onClick_.bind(this);this.onFocusIn_=this.onFocusIn_.bind(this);this.onDocumentClick_=this.onDocumentClick_.bind(this);this.onClose_=this.onClose_.bind(this);this.addEventListener('visible-change',tr.ui.b.Overlay.prototype.onVisibleChange_.bind(this),true);var createShadowRoot=this.createShadowRoot||this.webkitCreateShadowRoot;this.shadow_=createShadowRoot.call(this);this.shadow_.appendChild(tr.ui.b.instantiateTemplate('#overlay-template',THIS_DOC));this.closeBtn_=this.shadow_.querySelector('close-button');this.closeBtn_.addEventListener('click',this.onClose_);this.shadow_.querySelector('overlay-frame').addEventListener('click',this.onClick_);this.observer_=new WebKitMutationObserver(this.didButtonBarMutate_.bind(this));this.observer_.observe(this.shadow_.querySelector('button-bar'),{childList:true});Object.defineProperty(this,'title',{get:function(){return this.shadow_.querySelector('title').textContent;},set:function(title){this.shadow_.querySelector('title').textContent=title;}});},set userCanClose(userCanClose){this.userCanClose_=userCanClose;this.closeBtn_.style.display=userCanClose?'block':'none';},get buttons(){return this.shadow_.querySelector('button-bar');},get visible(){return this.visible_;},set visible(newValue){if(this.visible_===newValue)
+return;this.visible_=newValue;var e=new tr.b.Event('visible-change');this.dispatchEvent(e);},onVisibleChange_:function(){this.visible_?this.show_():this.hide_();},show_:function(){this.parentEl_.appendChild(this);if(this.userCanClose_){this.addEventListener('keydown',this.onKeyDown_.bind(this));this.addEventListener('click',this.onDocumentClick_.bind(this));}
+this.parentEl_.addEventListener('focusin',this.onFocusIn_);this.tabIndex=0;var focusEl=undefined;var elList=this.querySelectorAll('button, input, list, select, a');if(elList.length>0){if(elList[0]===this.closeBtn_){if(elList.length>1)
+focusEl=elList[1];}else{focusEl=elList[0];}}
+if(focusEl===undefined)
+focusEl=this;focusEl.focus();},hide_:function(){this.parentEl_.removeChild(this);this.parentEl_.removeEventListener('focusin',this.onFocusIn_);if(this.closeBtn_)
+this.closeBtn_.removeEventListener(this.onClose_);document.removeEventListener('keydown',this.onKeyDown_);document.removeEventListener('click',this.onDocumentClick_);},onClose_:function(e){this.visible=false;if((e.type!='keydown')||(e.type==='keydown'&&e.keyCode===27))
+e.stopPropagation();e.preventDefault();tr.b.dispatchSimpleEvent(this,'closeclick');},onFocusIn_:function(e){if(e.target===this)
+return;window.setTimeout(function(){this.focus();},0);e.preventDefault();e.stopPropagation();},didButtonBarMutate_:function(e){var hasButtons=this.buttons.children.length>0;if(hasButtons)
+this.shadow_.querySelector('button-bar').style.display=undefined;else
+this.shadow_.querySelector('button-bar').style.display='none';},onKeyDown_:function(e){if(e.keyCode===9&&e.shiftKey&&e.target===this){e.preventDefault();return;}
+if(e.keyCode!==27)
+return;this.onClose_(e);},onClick_:function(e){e.stopPropagation();},onDocumentClick_:function(e){if(!this.userCanClose_)
+return;this.onClose_(e);}};Overlay.showError=function(msg,opt_err){var o=new Overlay();o.title='Error';o.textContent=msg;if(opt_err){var e=tr.b.normalizeException(opt_err);var stackDiv=document.createElement('pre');stackDiv.textContent=e.stack;stackDiv.style.paddingLeft='8px';stackDiv.style.margin=0;o.appendChild(stackDiv);}
+var b=document.createElement('button');b.textContent='OK';b.addEventListener('click',function(){o.visible=false;});o.buttons.appendChild(b);o.visible=true;return o;}
+return{Overlay:Overlay};});'use strict';tr.exportTo('tr',function(){var Process=tr.model.Process;var Device=tr.model.Device;var Kernel=tr.model.Kernel;var GlobalMemoryDump=tr.model.GlobalMemoryDump;var GlobalInstantEvent=tr.model.GlobalInstantEvent;var FlowEvent=tr.model.FlowEvent;var Alert=tr.model.Alert;var InteractionRecord=tr.model.InteractionRecord;var Sample=tr.model.Sample;function ClockSyncRecord(name,ts,args){this.name=name;this.ts=ts;this.args=args;}
+function Model(){tr.model.EventContainer.call(this);tr.b.EventTarget.decorate(this);this.timestampShiftToZeroAmount_=0;this.faviconHue='blue';this.device=new Device(this);this.kernel=new Kernel(this);this.processes={};this.metadata=[];this.categories=[];this.instantEvents=[];this.flowEvents=[];this.clockSyncRecords=[];this.intrinsicTimeUnit_=undefined;this.stackFrames={};this.samples=[];this.alerts=[];this.interactionRecords=[];this.flowIntervalTree=new tr.b.IntervalTree(function(f){return f.start;},function(f){return f.end;});this.globalMemoryDumps=[];this.annotationsByGuid_={};this.modelIndices=undefined;this.importWarnings_=[];this.reportedImportWarnings_={};}
+Model.prototype={__proto__:tr.model.EventContainer.prototype,iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,GlobalMemoryDump))
+this.globalMemoryDumps.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,GlobalInstantEvent))
+this.instantEvents.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,FlowEvent))
+this.flowEvents.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,Alert))
+this.alerts.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,InteractionRecord))
+this.interactionRecords.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,Sample))
+this.samples.forEach(callback,opt_this);},iterateAllChildEventContainers:function(callback,opt_this){callback.call(opt_this,this.device);callback.call(opt_this,this.kernel);for(var pid in this.processes)
+callback.call(opt_this,this.processes[pid]);},iterateAllPersistableObjects:function(callback){this.kernel.iterateAllPersistableObjects(callback);for(var pid in this.processes)
+this.processes[pid].iterateAllPersistableObjects(callback);},updateBounds:function(){this.bounds.reset();var bounds=this.bounds;this.iterateAllChildEventContainers(function(ec){ec.updateBounds();bounds.addRange(ec.bounds);});this.iterateAllEventsInThisContainer(function(eventConstructor){return true;},function(event){event.addBoundsToRange(bounds);});},shiftWorldToZero:function(){var shiftAmount=-this.bounds.min;this.timestampShiftToZeroAmount_=shiftAmount;this.iterateAllChildEventContainers(function(ec){ec.shiftTimestampsForward(shiftAmount);});this.iterateAllEventsInThisContainer(function(eventConstructor){return true;},function(event){event.start+=shiftAmount;});this.updateBounds();},convertTimestampToModelTime:function(sourceClockDomainName,ts){if(sourceClockDomainName!=='traceEventClock')
+throw new Error('Only traceEventClock is supported.');return tr.b.u.Units.timestampFromUs(ts)+
+this.timestampShiftToZeroAmount_;},get numProcesses(){var n=0;for(var p in this.processes)
+n++;return n;},getProcess:function(pid){return this.processes[pid];},getOrCreateProcess:function(pid){if(!this.processes[pid])
+this.processes[pid]=new Process(this,pid);return this.processes[pid];},pushInstantEvent:function(instantEvent){this.instantEvents.push(instantEvent);},addStackFrame:function(stackFrame){if(this.stackFrames[stackFrame.id])
+throw new Error('Stack frame already exists');this.stackFrames[stackFrame.id]=stackFrame;return stackFrame;},addInteractionRecord:function(ir){this.interactionRecords.push(ir);return ir;},getClockSyncRecordsNamed:function(name){return this.clockSyncRecords.filter(function(x){return x.name===name;});},updateCategories_:function(){var categoriesDict={};this.device.addCategoriesToDict(categoriesDict);this.kernel.addCategoriesToDict(categoriesDict);for(var pid in this.processes)
+this.processes[pid].addCategoriesToDict(categoriesDict);this.categories=[];for(var category in categoriesDict)
+if(category!='')
+this.categories.push(category);},getAllThreads:function(){var threads=[];for(var tid in this.kernel.threads){threads.push(process.threads[tid]);}
+for(var pid in this.processes){var process=this.processes[pid];for(var tid in process.threads){threads.push(process.threads[tid]);}}
+return threads;},getAllProcesses:function(){var processes=[];for(var pid in this.processes)
+processes.push(this.processes[pid]);return processes;},getAllCounters:function(){var counters=[];counters.push.apply(counters,tr.b.dictionaryValues(this.device.counters));counters.push.apply(counters,tr.b.dictionaryValues(this.kernel.counters));for(var pid in this.processes){var process=this.processes[pid];for(var tid in process.counters){counters.push(process.counters[tid]);}}
+return counters;},getAnnotationByGUID:function(guid){return this.annotationsByGuid_[guid];},addAnnotation:function(annotation){if(!annotation.guid)
+throw new Error('Annotation with undefined guid given');this.annotationsByGuid_[annotation.guid]=annotation;tr.b.dispatchSimpleEvent(this,'annotationChange');},removeAnnotation:function(annotation){this.annotationsByGuid_[annotation.guid].onRemove();delete this.annotationsByGuid_[annotation.guid];tr.b.dispatchSimpleEvent(this,'annotationChange');},getAllAnnotations:function(){return tr.b.dictionaryValues(this.annotationsByGuid_);},findAllThreadsNamed:function(name){var namedThreads=[];namedThreads.push.apply(namedThreads,this.kernel.findAllThreadsNamed(name));for(var pid in this.processes){namedThreads.push.apply(namedThreads,this.processes[pid].findAllThreadsNamed(name));}
+return namedThreads;},set importOptions(options){this.importOptions_=options;},get intrinsicTimeUnit(){if(this.intrinsicTimeUnit_===undefined)
+return tr.b.u.TimeDisplayModes.ms;return this.intrinsicTimeUnit_;},set intrinsicTimeUnit(value){if(this.intrinsicTimeUnit_===value)
+return;if(this.intrinsicTimeUnit_!==undefined)
+throw new Error('Intrinsic time unit already set');this.intrinsicTimeUnit_=value;},importWarning:function(data){data.showToUser=!!data.showToUser;this.importWarnings_.push(data);if(this.reportedImportWarnings_[data.type]===true)
+return;if(this.importOptions_.showImportWarnings)
+console.warn(data.message);this.reportedImportWarnings_[data.type]=true;},get hasImportWarnings(){return(this.importWarnings_.length>0);},get importWarnings(){return this.importWarnings_;},get importWarningsThatShouldBeShownToUser(){return this.importWarnings_.filter(function(warning){return warning.showToUser;});},autoCloseOpenSlices:function(){this.samples.sort(function(x,y){return x.start-y.start;});this.updateBounds();this.kernel.autoCloseOpenSlices(this.bounds.max);for(var pid in this.processes)
+this.processes[pid].autoCloseOpenSlices(this.bounds.max);},createSubSlices:function(){this.kernel.createSubSlices();for(var pid in this.processes)
+this.processes[pid].createSubSlices();},preInitializeObjects:function(){for(var pid in this.processes)
+this.processes[pid].preInitializeObjects();},initializeObjects:function(){for(var pid in this.processes)
+this.processes[pid].initializeObjects();},pruneEmptyContainers:function(){this.kernel.pruneEmptyContainers();for(var pid in this.processes)
+this.processes[pid].pruneEmptyContainers();},mergeKernelWithUserland:function(){for(var pid in this.processes)
+this.processes[pid].mergeKernelWithUserland();},computeWorldBounds:function(shiftWorldToZero){this.updateBounds();this.updateCategories_();if(shiftWorldToZero)
+this.shiftWorldToZero();},buildFlowEventIntervalTree:function(){for(var i=0;i<this.flowEvents.length;++i){var flowEvent=this.flowEvents[i];this.flowIntervalTree.insert(flowEvent);}
+this.flowIntervalTree.updateHighValues();},cleanupUndeletedObjects:function(){for(var pid in this.processes)
+this.processes[pid].autoDeleteObjects(this.bounds.max);},sortMemoryDumps:function(){this.globalMemoryDumps.sort(function(x,y){return x.start-y.start;});for(var pid in this.processes)
+this.processes[pid].sortMemoryDumps();},calculateMemoryGraphAttributes:function(){this.globalMemoryDumps.forEach(function(dump){dump.calculateGraphAttributes();});},buildEventIndices:function(){this.modelIndices=new tr.model.ModelIndices(this);},sortInteractionRecords:function(){this.interactionRecords.sort(function(x,y){return x.start-y.start;});},sortAlerts:function(){this.alerts.sort(function(x,y){return x.start-y.start;});}};return{ClockSyncRecord:ClockSyncRecord,Model:Model};});'use strict';tr.exportTo('tr.importer',function(){function EmptyImporter(events){this.importPriority=0;};EmptyImporter.canImport=function(eventData){if(eventData instanceof Array&&eventData.length==0)
+return true;if(typeof(eventData)==='string'||eventData instanceof String){return eventData.length==0;}
+return false;};EmptyImporter.prototype={__proto__:tr.importer.Importer.prototype};tr.importer.Importer.register(EmptyImporter);return{EmptyImporter:EmptyImporter};});'use strict';tr.exportTo('tr.importer',function(){function ImportOptions(){this.shiftWorldToZero=true;this.pruneEmptyContainers=true;this.showImportWarnings=true;this.customizeModelCallback=undefined;var auditorTypes=tr.c.Auditor.getAllRegisteredTypeInfos();this.auditorConstructors=auditorTypes.map(function(typeInfo){return typeInfo.constructor;});}
+function Import(model,opt_options){if(model===undefined)
+throw new Error('Must provide model to import into.');this.importing_=false;this.importOptions_=opt_options||new ImportOptions();this.model_=model;this.model_.importOptions=this.importOptions_;}
+Import.prototype={__proto__:Object.prototype,importTraces:function(traces){var progressMeter={update:function(msg){}};tr.b.Task.RunSynchronously(this.createImportTracesTask(progressMeter,traces));},importTracesWithProgressDialog:function(traces){if(tr.isHeadless)
+throw new Error('Cannot use this method in headless mode.');var overlay=tr.ui.b.Overlay();overlay.title='Importing...';overlay.userCanClose=false;overlay.msgEl=document.createElement('div');overlay.appendChild(overlay.msgEl);overlay.msgEl.style.margin='20px';overlay.update=function(msg){this.msgEl.textContent=msg;}
+overlay.visible=true;var promise=tr.b.Task.RunWhenIdle(this.createImportTracesTask(overlay,traces));promise.then(function(){overlay.visible=false;},function(err){overlay.visible=false;});return promise;},createImportTracesTask:function(progressMeter,traces){if(this.importing_)
+throw new Error('Already importing.');this.importing_=true;var importTask=new tr.b.Task(function(){progressMeter.update('I will now import your traces for you...');},this);var lastTask=importTask;var importers=[];lastTask=lastTask.after(function(){traces=traces.slice(0);progressMeter.update('Creating importers...');for(var i=0;i<traces.length;++i)
+importers.push(this.createImporter_(traces[i]));for(var i=0;i<importers.length;i++){var subtraces=importers[i].extractSubtraces();for(var j=0;j<subtraces.length;j++){try{traces.push(subtraces[j]);importers.push(this.createImporter_(subtraces[j]));}catch(error){console.warn(error.name+': '+error.message);continue;}}}
+if(traces.length&&!this.hasEventDataDecoder_(importers)){throw new Error('Could not find an importer for the provided eventData.');}
+importers.sort(function(x,y){return x.importPriority-y.importPriority;});},this);lastTask=lastTask.after(function(task){importers.forEach(function(importer,index){task.subTask(function(){progressMeter.update('Importing '+(index+1)+' of '+importers.length);importer.importEvents();},this);},this);},this);if(this.importOptions_.customizeModelCallback){lastTask=lastTask.after(function(task){this.importOptions_.customizeModelCallback(this.model_);},this);}
+lastTask=lastTask.after(function(task){importers.forEach(function(importer,index){progressMeter.update('Importing sample data '+(index+1)+'/'+importers.length);importer.importSampleData();},this);},this);lastTask=lastTask.after(function(){progressMeter.update('Autoclosing open slices...');this.model_.autoCloseOpenSlices();this.model_.createSubSlices();},this);lastTask=lastTask.after(function(task){importers.forEach(function(importer,index){progressMeter.update('Finalizing import '+(index+1)+'/'+importers.length);importer.finalizeImport();},this);},this);lastTask=lastTask.after(function(){progressMeter.update('Initializing objects (step 1/2)...');this.model_.preInitializeObjects();},this);if(this.importOptions_.pruneEmptyContainers){lastTask=lastTask.after(function(){progressMeter.update('Pruning empty containers...');this.model_.pruneEmptyContainers();},this);}
+lastTask=lastTask.after(function(){progressMeter.update('Merging kernel with userland...');this.model_.mergeKernelWithUserland();},this);var auditors=[];lastTask=lastTask.after(function(){progressMeter.update('Adding arbitrary data to model...');auditors=this.importOptions_.auditorConstructors.map(function(auditorConstructor){return new auditorConstructor(this.model_);},this);auditors.forEach(function(auditor){auditor.runAnnotate();});},this);lastTask=lastTask.after(function(){progressMeter.update('Computing final world bounds...');this.model_.computeWorldBounds(this.importOptions_.shiftWorldToZero);},this);lastTask=lastTask.after(function(){progressMeter.update('Building flow event map...');this.model_.buildFlowEventIntervalTree();},this);lastTask=lastTask.after(function(){progressMeter.update('Joining object refs...');for(var i=0;i<importers.length;i++)
+importers[i].joinRefs();},this);lastTask=lastTask.after(function(){progressMeter.update('Cleaning up undeleted objects...');this.model_.cleanupUndeletedObjects();},this);lastTask=lastTask.after(function(){progressMeter.update('Sorting memory dumps...');this.model_.sortMemoryDumps();},this);lastTask=lastTask.after(function(){progressMeter.update('Calculating memory dump graph attributes...');this.model_.calculateMemoryGraphAttributes();},this);lastTask=lastTask.after(function(){progressMeter.update('Initializing objects (step 2/2)...');this.model_.initializeObjects();},this);lastTask=lastTask.after(function(){progressMeter.update('Building flow event indices...');this.model_.buildEventIndices();},this);lastTask=lastTask.after(function(){progressMeter.update('Running auditors...');auditors.forEach(function(auditor){auditor.runAudit();});},this);lastTask=lastTask.after(function(){progressMeter.update('Updating interaction records...');this.model_.sortInteractionRecords();},this);lastTask=lastTask.after(function(){progressMeter.update('Updating alerts...');this.model_.sortAlerts();},this);lastTask=lastTask.after(function(){progressMeter.update('Update bounds...');this.model_.updateBounds();},this);lastTask.after(function(){this.importing_=false;},this);return importTask;},createImporter_:function(eventData){var importerConstructor=tr.importer.Importer.findImporterFor(eventData);if(!importerConstructor){throw new Error('Couldn\'t create an importer for the provided '+'eventData.');}
+return new importerConstructor(this.model_,eventData);},hasEventDataDecoder_:function(importers){if(importers.length===0)
+return false;for(var i=0;i<importers.length;++i){if(!importers[i].isTraceDataContainer())
+return true;}
+return false;}};return{ImportOptions:ImportOptions,Import:Import};});'use strict';tr.exportTo('tr.importer',function(){function SimpleLineReader(text){this.lines_=text.split('\n');this.curLine_=0;this.savedLines_=undefined;}
+SimpleLineReader.prototype={advanceToLineMatching:function(regex){for(;this.curLine_<this.lines_.length;this.curLine_++){var line=this.lines_[this.curLine_];if(this.savedLines_!==undefined)
+this.savedLines_.push(line);if(regex.test(line))
+return true;}
+return false;},get curLineNumber(){return this.curLine_;},beginSavingLines:function(){this.savedLines_=[];},endSavingLinesAndGetResult:function(){var tmp=this.savedLines_;this.savedLines_=undefined;return tmp;}};return{SimpleLineReader:SimpleLineReader};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;function Activity(name,category,range,args){tr.model.TimedEvent.call(this,range.min);this.title=name;this.category=category;this.colorId=ColorScheme.getColorIdForGeneralPurposeString(name);this.duration=range.duration;this.args=args;this.name=name;};Activity.prototype={__proto__:tr.model.TimedEvent.prototype,shiftTimestampsForward:function(amount){this.start+=amount;},addBoundsToRange:function(range){range.addValue(this.start);range.addValue(this.end);}};return{Activity:Activity};});'use strict';tr.exportTo('tr.e.importer.android',function(){var Importer=tr.importer.Importer;var ACTIVITY_STATE={NONE:'none',CREATED:'created',STARTED:'started',RESUMED:'resumed',PAUSED:'paused',STOPPED:'stopped',DESTROYED:'destroyed'};var activityMap={};function EventLogImporter(model,events){this.model_=model;this.events_=events;this.importPriority=3;}
+var eventLogActivityRE=new RegExp('(\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}.\\d+)'+'\\s+(\\d+)\\s+(\\d+)\\s+([A-Z])\\s*'+'(am_\\w+)\\s*:(.*)');var amCreateRE=new RegExp('\s*\\[.*,.*,.*,(.*),.*,.*,.*,.*\\]');var amFocusedRE=new RegExp('\s*\\[\\d+,(.*)\\]');var amProcStartRE=new RegExp('\s*\\[\\d+,\\d+,\\d+,.*,activity,(.*)\\]');var amOnResumeRE=new RegExp('\s*\\[\\d+,(.*)\\]');var amOnPauseRE=new RegExp('\s*\\[\\d+,(.*)\\]');var amLaunchTimeRE=new RegExp('\s*\\[\\d+,\\d+,(.*),(\\d+),(\\d+)');var amDestroyRE=new RegExp('\s*\\[\\d+,\\d+,\\d+,(.*)\\]');EventLogImporter.canImport=function(events){if(!(typeof(events)==='string'||events instanceof String))
+return false;return eventLogActivityRE.test(events);};EventLogImporter.prototype={__proto__:Importer.prototype,get model(){return this.model_;},getFullActivityName:function(component){var componentSplit=component.split('/');if(componentSplit[1].startsWith('.'))
+return componentSplit[0]+componentSplit[1];return componentSplit[1];},getProcName:function(component){var componentSplit=component.split('/');return componentSplit[0];},findOrCreateActivity:function(activityName){if(activityName in activityMap)
+return activityMap[activityName];var activity={state:ACTIVITY_STATE.NONE,name:activityName};activityMap[activityName]=activity;return activity;},deleteActivity:function(activityName){delete activityMap[activityName];},handleCreateActivity:function(ts,activityName){var activity=this.findOrCreateActivity(activityName);activity.state=ACTIVITY_STATE.CREATED;activity.createdTs=ts;},handleFocusActivity:function(ts,procName,activityName){var activity=this.findOrCreateActivity(activityName);activity.lastFocusedTs=ts;},handleProcStartForActivity:function(ts,activityName){var activity=this.findOrCreateActivity(activityName);activity.procStartTs=ts;},handleOnResumeCalled:function(ts,pid,activityName){var activity=this.findOrCreateActivity(activityName);activity.state=ACTIVITY_STATE.RESUMED;activity.lastResumeTs=ts;activity.pid=pid;},handleOnPauseCalled:function(ts,activityName){var activity=this.findOrCreateActivity(activityName);activity.state=ACTIVITY_STATE.PAUSED;activity.lastPauseTs=ts;if(ts>this.model_.bounds.min&&ts<this.model_.bounds.max)
+this.addActivityToProcess(activity);},handleLaunchTime:function(ts,activityName,launchTime){var activity=this.findOrCreateActivity(activityName);activity.launchTime=launchTime;},handleDestroyActivity:function(ts,activityName){this.deleteActivity(activityName);},addActivityToProcess:function(activity){if(activity.pid===undefined)
+return;var process=this.model_.getOrCreateProcess(activity.pid);var range=tr.b.Range.fromExplicitRange(Math.max(this.model_.bounds.min,activity.lastResumeTs),activity.lastPauseTs);var newActivity=new tr.model.Activity(activity.name,'Android Activity',range,{created:activity.createdTs,procstart:activity.procStartTs,lastfocus:activity.lastFocusedTs});process.activities.push(newActivity);},parseAmLine_:function(line){var match=eventLogActivityRE.exec(line);if(!match)
+return;var first_realtime_ts=this.model_.bounds.min-
+this.model_.realtime_to_monotonic_offset_ms;var year=new Date(first_realtime_ts).getFullYear();var ts=match[1].substring(0,5)+'-'+year+' '+
+match[1].substring(5,match[1].length);var monotonic_ts=Date.parse(ts)+
+this.model_.realtime_to_monotonic_offset_ms;var pid=match[2];var action=match[5];var data=match[6];if(action==='am_create_activity'){match=amCreateRE.exec(data);if(match&&match.length>=2){this.handleCreateActivity(monotonic_ts,this.getFullActivityName(match[1]));}}else if(action==='am_focused_activity'){match=amFocusedRE.exec(data);if(match&&match.length>=2){this.handleFocusActivity(monotonic_ts,this.getProcName(match[1]),this.getFullActivityName(match[1]));}}else if(action==='am_proc_start'){match=amProcStartRE.exec(data);if(match&&match.length>=2){this.handleProcStartForActivity(monotonic_ts,this.getFullActivityName(match[1]));}}else if(action==='am_on_resume_called'){match=amOnResumeRE.exec(data);if(match&&match.length>=2)
+this.handleOnResumeCalled(monotonic_ts,pid,match[1]);}else if(action==='am_on_paused_called'){match=amOnPauseRE.exec(data);if(match&&match.length>=2)
+this.handleOnPauseCalled(monotonic_ts,match[1]);}else if(action==='am_activity_launch_time'){match=amLaunchTimeRE.exec(data);this.handleLaunchTime(monotonic_ts,this.getFullActivityName(match[1]),match[2]);}else if(action==='am_destroy_activity'){match=amDestroyRE.exec(data);if(match&&match.length==2){this.handleDestroyActivity(monotonic_ts,this.getFullActivityName(match[1]));}}},importEvents:function(isSecondaryImport){if(isNaN(this.model_.realtime_to_monotonic_offset_ms)){this.model_.importWarning({type:'eveng_log_clock_sync',message:'Need a trace_event_clock_sync to map realtime to import.'});return;}
+this.model_.updateBounds();var lines=this.events_.split('\n');lines.forEach(this.parseAmLine_,this);for(var activityName in activityMap){var activity=activityMap[activityName];if(activity.state==ACTIVITY_STATE.RESUMED){activity.lastPauseTs=this.model_.bounds.max;this.addActivityToProcess(activity);}}}};Importer.register(EventLogImporter);return{EventLogImporter:EventLogImporter};});'use strict';tr.exportTo('tr.e.importer.battor',function(){function BattorImporter(model,events){this.importPriority=3;this.sampleRate_=undefined;this.model_=model;this.events_=events;}
+var TestExports={};var battorDataLineRE=/^(\d+\.\d+)\s+(\d+\.\d+)\s+(\d+\.\d+)$/;var battorHeaderLineRE=/^# BattOr/;var sampleRateLineRE=/^# sample_rate=(\d+)Hz/;BattorImporter.canImport=function(events){if(!(typeof(events)==='string'||events instanceof String))
+return false;return battorHeaderLineRE.test(events);};BattorImporter.prototype={__proto__:tr.importer.Importer.prototype,get model(){return this.model_;},importEvents:function(isSecondaryImport){if(this.model_.device.powerSeries){this.model_.importWarning({type:'import_error',message:'Power counter exists, can not import BattOr power trace.'});return;}
+var name='power';var series=new tr.model.PowerSeries(this.model_.device);this.importPowerSamples(series);var syncMarks=this.model_.getClockSyncRecordsNamed('battor');if(syncMarks.length<1){this.model_.importWarning({type:'clock_sync',message:'Cannot import BattOr power trace without a sync signal.'});return;}
+var shiftTs=this.correlationClockSync(syncMarks,series);if(shiftTs===undefined){this.model_.importWarning({type:'clock_sync',message:'All of the BattOr power trace clock sync techinques failed.'});return;}
+series.shiftTimestampsForward(shiftTs);this.model_.device.powerSeries=series;},importPowerSamples:function(series){var lines=this.events_.split('\n');this.model_.updateBounds();var minTs=0;if(this.model_.bounds.min!==undefined)
+minTs=this.model_.bounds.min;lines.forEach(function(line){line=line.trim();if(line.length===0)
+return;if(/^#/.test(line)){groups=sampleRateLineRE.exec(line);if(!groups)
+return;this.sampleRate_=parseInt(groups[1]);}else{var groups=battorDataLineRE.exec(line);if(!groups){this.model_.importWarning({type:'parse_error',message:'Unrecognized line: '+line});return;}
+var time=parseFloat(groups[1])+minTs;var voltage_mV=parseFloat(groups[2]);var current_mA=parseFloat(groups[3]);series.addPowerSample(time,(voltage_mV*current_mA)/1000);}},this);},correlationClockSync:function(syncMarks,series){var syncCtr=this.model_.kernel.counters['null.vreg '+syncMarks[0].args['regulator']+' enabled'];if(syncCtr===undefined){this.model_.importWarning({type:'clock_sync',message:'Cannot correlate BattOr power trace without sync vreg.'});return undefined;}
+var syncEvents=[];var firstSyncEventTs=undefined;syncCtr.series[0].iterateAllEvents(function(event){if(event.timestamp>=syncMarks[0].ts&&event.timestamp<=syncMarks[1].ts){if(firstSyncEventTs===undefined)
+firstSyncEventTs=event.timestamp;var newEvent={'ts':(event.timestamp-firstSyncEventTs)/1000,'val':event.value};syncEvents.push(newEvent);}});var syncSamples=[];var syncNumSamples=Math.ceil(syncEvents[syncEvents.length-1].ts*this.sampleRate_);for(var i=1;i<syncEvents.length;i++){var sampleStartIdx=Math.ceil(syncEvents[i-1].ts*this.sampleRate_);var sampleEndIdx=Math.ceil(syncEvents[i].ts*this.sampleRate_);for(var j=sampleStartIdx;j<sampleEndIdx;j++){syncSamples[j]=syncEvents[i-1].val;}}
+var powerSamples=series.samples;if(powerSamples.length<syncSamples.length){this.model_.importWarning({type:'not_enough_samples',message:'Not enough power samples to correlate with sync signal.'});return undefined;}
+var maxShift=powerSamples.length-syncSamples.length;var minShift=0;var corrNumSamples=this.sampleRate_*5.0;if(powerSamples.length>corrNumSamples)
+minShift=powerSamples.length-corrNumSamples;var corr=[];for(var shift=minShift;shift<=maxShift;shift++){var corrSum=0;var powerAvg=0;for(var i=0;i<syncSamples.length;i++){corrSum+=(powerSamples[i+shift].power*syncSamples[i]);powerAvg+=powerSamples[i+shift].power;}
+powerAvg=powerAvg/syncSamples.length;corr.push(corrSum/powerAvg);}
+var corrPeakIdx=0;var corrPeak=0;for(var i=0;i<powerSamples.length;i++){if(corr[i]>corrPeak){corrPeak=corr[i];corrPeakIdx=i;}}
+var corrPeakTs=((minShift+corrPeakIdx)/this.sampleRate_);corrPeakTs*=1000;var syncStartTs=firstSyncEventTs-this.model_.bounds.min;var shiftTs=syncStartTs-corrPeakTs;return shiftTs;}};tr.importer.Importer.register(BattorImporter);return{BattorImporter:BattorImporter,_BattorImporterTestExports:TestExports};});!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;"undefined"!=typeof window?b=window:"undefined"!=typeof global?b=global:"undefined"!=typeof self&&(b=self),b.JSZip=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}({1:[function(a,b,c){"use strict";var d="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";c.encode=function(a){for(var b,c,e,f,g,h,i,j="",k=0;k<a.length;)b=a.charCodeAt(k++),c=a.charCodeAt(k++),e=a.charCodeAt(k++),f=b>>2,g=(3&b)<<4|c>>4,h=(15&c)<<2|e>>6,i=63&e,isNaN(c)?h=i=64:isNaN(e)&&(i=64),j=j+d.charAt(f)+d.charAt(g)+d.charAt(h)+d.charAt(i);return j},c.decode=function(a){var b,c,e,f,g,h,i,j="",k=0;for(a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");k<a.length;)f=d.indexOf(a.charAt(k++)),g=d.indexOf(a.charAt(k++)),h=d.indexOf(a.charAt(k++)),i=d.indexOf(a.charAt(k++)),b=f<<2|g>>4,c=(15&g)<<4|h>>2,e=(3&h)<<6|i,j+=String.fromCharCode(b),64!=h&&(j+=String.fromCharCode(c)),64!=i&&(j+=String.fromCharCode(e));return j}},{}],2:[function(a,b){"use strict";function c(){this.compressedSize=0,this.uncompressedSize=0,this.crc32=0,this.compressionMethod=null,this.compressedContent=null}c.prototype={getContent:function(){return null},getCompressedContent:function(){return null}},b.exports=c},{}],3:[function(a,b,c){"use strict";c.STORE={magic:"\x00\x00",compress:function(a){return a},uncompress:function(a){return a},compressInputType:null,uncompressInputType:null},c.DEFLATE=a("./flate")},{"./flate":8}],4:[function(a,b){"use strict";var c=a("./utils"),d=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117];b.exports=function(a,b){if("undefined"==typeof a||!a.length)return 0;var e="string"!==c.getTypeOf(a);"undefined"==typeof b&&(b=0);var f=0,g=0,h=0;b=-1^b;for(var i=0,j=a.length;j>i;i++)h=e?a[i]:a.charCodeAt(i),g=255&(b^h),f=d[g],b=b>>>8^f;return-1^b}},{"./utils":21}],5:[function(a,b){"use strict";function c(){this.data=null,this.length=0,this.index=0}var d=a("./utils");c.prototype={checkOffset:function(a){this.checkIndex(this.index+a)},checkIndex:function(a){if(this.length<a||0>a)throw new Error("End of data reached (data length = "+this.length+", asked index = "+a+"). Corrupted zip ?")},setIndex:function(a){this.checkIndex(a),this.index=a},skip:function(a){this.setIndex(this.index+a)},byteAt:function(){},readInt:function(a){var b,c=0;for(this.checkOffset(a),b=this.index+a-1;b>=this.index;b--)c=(c<<8)+this.byteAt(b);return this.index+=a,c},readString:function(a){return d.transformTo("string",this.readData(a))},readData:function(){},lastIndexOfSignature:function(){},readDate:function(){var a=this.readInt(4);return new Date((a>>25&127)+1980,(a>>21&15)-1,a>>16&31,a>>11&31,a>>5&63,(31&a)<<1)}},b.exports=c},{"./utils":21}],6:[function(a,b,c){"use strict";c.base64=!1,c.binary=!1,c.dir=!1,c.createFolders=!1,c.date=null,c.compression=null,c.comment=null},{}],7:[function(a,b,c){"use strict";var d=a("./utils");c.string2binary=function(a){return d.string2binary(a)},c.string2Uint8Array=function(a){return d.transformTo("uint8array",a)},c.uint8Array2String=function(a){return d.transformTo("string",a)},c.string2Blob=function(a){var b=d.transformTo("arraybuffer",a);return d.arrayBuffer2Blob(b)},c.arrayBuffer2Blob=function(a){return d.arrayBuffer2Blob(a)},c.transformTo=function(a,b){return d.transformTo(a,b)},c.getTypeOf=function(a){return d.getTypeOf(a)},c.checkSupport=function(a){return d.checkSupport(a)},c.MAX_VALUE_16BITS=d.MAX_VALUE_16BITS,c.MAX_VALUE_32BITS=d.MAX_VALUE_32BITS,c.pretty=function(a){return d.pretty(a)},c.findCompression=function(a){return d.findCompression(a)},c.isRegExp=function(a){return d.isRegExp(a)}},{"./utils":21}],8:[function(a,b,c){"use strict";var d="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Uint32Array,e=a("pako");c.uncompressInputType=d?"uint8array":"array",c.compressInputType=d?"uint8array":"array",c.magic="\b\x00",c.compress=function(a){return e.deflateRaw(a)},c.uncompress=function(a){return e.inflateRaw(a)}},{pako:24}],9:[function(a,b){"use strict";function c(a,b){return this instanceof c?(this.files={},this.comment=null,this.root="",a&&this.load(a,b),void(this.clone=function(){var a=new c;for(var b in this)"function"!=typeof this[b]&&(a[b]=this[b]);return a})):new c(a,b)}var d=a("./base64");c.prototype=a("./object"),c.prototype.load=a("./load"),c.support=a("./support"),c.defaults=a("./defaults"),c.utils=a("./deprecatedPublicUtils"),c.base64={encode:function(a){return d.encode(a)},decode:function(a){return d.decode(a)}},c.compressions=a("./compressions"),b.exports=c},{"./base64":1,"./compressions":3,"./defaults":6,"./deprecatedPublicUtils":7,"./load":10,"./object":13,"./support":17}],10:[function(a,b){"use strict";var c=a("./base64"),d=a("./zipEntries");b.exports=function(a,b){var e,f,g,h;for(b=b||{},b.base64&&(a=c.decode(a)),f=new d(a,b),e=f.files,g=0;g<e.length;g++)h=e[g],this.file(h.fileName,h.decompressed,{binary:!0,optimizedBinaryString:!0,date:h.date,dir:h.dir,comment:h.fileComment.length?h.fileComment:null,createFolders:b.createFolders});return f.zipComment.length&&(this.comment=f.zipComment),this}},{"./base64":1,"./zipEntries":22}],11:[function(a,b){(function(a){"use strict";b.exports=function(b,c){return new a(b,c)},b.exports.test=function(b){return a.isBuffer(b)}}).call(this,"undefined"!=typeof Buffer?Buffer:void 0)},{}],12:[function(a,b){"use strict";function c(a){this.data=a,this.length=this.data.length,this.index=0}var d=a("./uint8ArrayReader");c.prototype=new d,c.prototype.readData=function(a){this.checkOffset(a);var b=this.data.slice(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./uint8ArrayReader":18}],13:[function(a,b){"use strict";var c=a("./support"),d=a("./utils"),e=a("./crc32"),f=a("./signature"),g=a("./defaults"),h=a("./base64"),i=a("./compressions"),j=a("./compressedObject"),k=a("./nodeBuffer"),l=a("./utf8"),m=a("./stringWriter"),n=a("./uint8ArrayWriter"),o=function(a){if(a._data instanceof j&&(a._data=a._data.getContent(),a.options.binary=!0,a.options.base64=!1,"uint8array"===d.getTypeOf(a._data))){var b=a._data;a._data=new Uint8Array(b.length),0!==b.length&&a._data.set(b,0)}return a._data},p=function(a){var b=o(a),e=d.getTypeOf(b);return"string"===e?!a.options.binary&&c.nodebuffer?k(b,"utf-8"):a.asBinary():b},q=function(a){var b=o(this);return null===b||"undefined"==typeof b?"":(this.options.base64&&(b=h.decode(b)),b=a&&this.options.binary?A.utf8decode(b):d.transformTo("string",b),a||this.options.binary||(b=d.transformTo("string",A.utf8encode(b))),b)},r=function(a,b,c){this.name=a,this.dir=c.dir,this.date=c.date,this.comment=c.comment,this._data=b,this.options=c,this._initialMetadata={dir:c.dir,date:c.date}};r.prototype={asText:function(){return q.call(this,!0)},asBinary:function(){return q.call(this,!1)},asNodeBuffer:function(){var a=p(this);return d.transformTo("nodebuffer",a)},asUint8Array:function(){var a=p(this);return d.transformTo("uint8array",a)},asArrayBuffer:function(){return this.asUint8Array().buffer}};var s=function(a,b){var c,d="";for(c=0;b>c;c++)d+=String.fromCharCode(255&a),a>>>=8;return d},t=function(){var a,b,c={};for(a=0;a<arguments.length;a++)for(b in arguments[a])arguments[a].hasOwnProperty(b)&&"undefined"==typeof c[b]&&(c[b]=arguments[a][b]);return c},u=function(a){return a=a||{},a.base64!==!0||null!==a.binary&&void 0!==a.binary||(a.binary=!0),a=t(a,g),a.date=a.date||new Date,null!==a.compression&&(a.compression=a.compression.toUpperCase()),a},v=function(a,b,c){var e,f=d.getTypeOf(b);if(c=u(c),c.createFolders&&(e=w(a))&&x.call(this,e,!0),c.dir||null===b||"undefined"==typeof b)c.base64=!1,c.binary=!1,b=null;else if("string"===f)c.binary&&!c.base64&&c.optimizedBinaryString!==!0&&(b=d.string2binary(b));else{if(c.base64=!1,c.binary=!0,!(f||b instanceof j))throw new Error("The data of '"+a+"' is in an unsupported format !");"arraybuffer"===f&&(b=d.transformTo("uint8array",b))}var g=new r(a,b,c);return this.files[a]=g,g},w=function(a){"/"==a.slice(-1)&&(a=a.substring(0,a.length-1));var b=a.lastIndexOf("/");return b>0?a.substring(0,b):""},x=function(a,b){return"/"!=a.slice(-1)&&(a+="/"),b="undefined"!=typeof b?b:!1,this.files[a]||v.call(this,a,null,{dir:!0,createFolders:b}),this.files[a]},y=function(a,b){var c,f=new j;return a._data instanceof j?(f.uncompressedSize=a._data.uncompressedSize,f.crc32=a._data.crc32,0===f.uncompressedSize||a.dir?(b=i.STORE,f.compressedContent="",f.crc32=0):a._data.compressionMethod===b.magic?f.compressedContent=a._data.getCompressedContent():(c=a._data.getContent(),f.compressedContent=b.compress(d.transformTo(b.compressInputType,c)))):(c=p(a),(!c||0===c.length||a.dir)&&(b=i.STORE,c=""),f.uncompressedSize=c.length,f.crc32=e(c),f.compressedContent=b.compress(d.transformTo(b.compressInputType,c))),f.compressedSize=f.compressedContent.length,f.compressionMethod=b.magic,f},z=function(a,b,c,g){var h,i,j,k,m=(c.compressedContent,d.transformTo("string",l.utf8encode(b.name))),n=b.comment||"",o=d.transformTo("string",l.utf8encode(n)),p=m.length!==b.name.length,q=o.length!==n.length,r=b.options,t="",u="",v="";j=b._initialMetadata.dir!==b.dir?b.dir:r.dir,k=b._initialMetadata.date!==b.date?b.date:r.date,h=k.getHours(),h<<=6,h|=k.getMinutes(),h<<=5,h|=k.getSeconds()/2,i=k.getFullYear()-1980,i<<=4,i|=k.getMonth()+1,i<<=5,i|=k.getDate(),p&&(u=s(1,1)+s(e(m),4)+m,t+="up"+s(u.length,2)+u),q&&(v=s(1,1)+s(this.crc32(o),4)+o,t+="uc"+s(v.length,2)+v);var w="";w+="\n\x00",w+=p||q?"\x00\b":"\x00\x00",w+=c.compressionMethod,w+=s(h,2),w+=s(i,2),w+=s(c.crc32,4),w+=s(c.compressedSize,4),w+=s(c.uncompressedSize,4),w+=s(m.length,2),w+=s(t.length,2);var x=f.LOCAL_FILE_HEADER+w+m+t,y=f.CENTRAL_FILE_HEADER+"\x00"+w+s(o.length,2)+"\x00\x00\x00\x00"+(j===!0?"\x00\x00\x00":"\x00\x00\x00\x00")+s(g,4)+m+t+o;return{fileRecord:x,dirRecord:y,compressedObject:c}},A={load:function(){throw new Error("Load method is not defined. Is the file jszip-load.js included ?")},filter:function(a){var b,c,d,e,f=[];for(b in this.files)this.files.hasOwnProperty(b)&&(d=this.files[b],e=new r(d.name,d._data,t(d.options)),c=b.slice(this.root.length,b.length),b.slice(0,this.root.length)===this.root&&a(c,e)&&f.push(e));return f},file:function(a,b,c){if(1===arguments.length){if(d.isRegExp(a)){var e=a;return this.filter(function(a,b){return!b.dir&&e.test(a)})}return this.filter(function(b,c){return!c.dir&&b===a})[0]||null}return a=this.root+a,v.call(this,a,b,c),this},folder:function(a){if(!a)return this;if(d.isRegExp(a))return this.filter(function(b,c){return c.dir&&a.test(b)});var b=this.root+a,c=x.call(this,b),e=this.clone();return e.root=c.name,e},remove:function(a){a=this.root+a;var b=this.files[a];if(b||("/"!=a.slice(-1)&&(a+="/"),b=this.files[a]),b&&!b.dir)delete this.files[a];else for(var c=this.filter(function(b,c){return c.name.slice(0,a.length)===a}),d=0;d<c.length;d++)delete this.files[c[d].name];return this},generate:function(a){a=t(a||{},{base64:!0,compression:"STORE",type:"base64",comment:null}),d.checkSupport(a.type);var b,c,e=[],g=0,j=0,k=d.transformTo("string",this.utf8encode(a.comment||this.comment||""));for(var l in this.files)if(this.files.hasOwnProperty(l)){var o=this.files[l],p=o.options.compression||a.compression.toUpperCase(),q=i[p];if(!q)throw new Error(p+" is not a valid compression method !");var r=y.call(this,o,q),u=z.call(this,l,o,r,g);g+=u.fileRecord.length+r.compressedSize,j+=u.dirRecord.length,e.push(u)}var v="";v=f.CENTRAL_DIRECTORY_END+"\x00\x00\x00\x00"+s(e.length,2)+s(e.length,2)+s(j,4)+s(g,4)+s(k.length,2)+k;var w=a.type.toLowerCase();for(b="uint8array"===w||"arraybuffer"===w||"blob"===w||"nodebuffer"===w?new n(g+j+v.length):new m(g+j+v.length),c=0;c<e.length;c++)b.append(e[c].fileRecord),b.append(e[c].compressedObject.compressedContent);for(c=0;c<e.length;c++)b.append(e[c].dirRecord);b.append(v);var x=b.finalize();switch(a.type.toLowerCase()){case"uint8array":case"arraybuffer":case"nodebuffer":return d.transformTo(a.type.toLowerCase(),x);case"blob":return d.arrayBuffer2Blob(d.transformTo("arraybuffer",x));case"base64":return a.base64?h.encode(x):x;default:return x}},crc32:function(a,b){return e(a,b)},utf8encode:function(a){return d.transformTo("string",l.utf8encode(a))},utf8decode:function(a){return l.utf8decode(a)}};b.exports=A},{"./base64":1,"./compressedObject":2,"./compressions":3,"./crc32":4,"./defaults":6,"./nodeBuffer":11,"./signature":14,"./stringWriter":16,"./support":17,"./uint8ArrayWriter":19,"./utf8":20,"./utils":21}],14:[function(a,b,c){"use strict";c.LOCAL_FILE_HEADER="PK",c.CENTRAL_FILE_HEADER="PK",c.CENTRAL_DIRECTORY_END="PK",c.ZIP64_CENTRAL_DIRECTORY_LOCATOR="PK",c.ZIP64_CENTRAL_DIRECTORY_END="PK",c.DATA_DESCRIPTOR="PK\b"},{}],15:[function(a,b){"use strict";function c(a,b){this.data=a,b||(this.data=e.string2binary(this.data)),this.length=this.data.length,this.index=0}var d=a("./dataReader"),e=a("./utils");c.prototype=new d,c.prototype.byteAt=function(a){return this.data.charCodeAt(a)},c.prototype.lastIndexOfSignature=function(a){return this.data.lastIndexOf(a)},c.prototype.readData=function(a){this.checkOffset(a);var b=this.data.slice(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./dataReader":5,"./utils":21}],16:[function(a,b){"use strict";var c=a("./utils"),d=function(){this.data=[]};d.prototype={append:function(a){a=c.transformTo("string",a),this.data.push(a)},finalize:function(){return this.data.join("")}},b.exports=d},{"./utils":21}],17:[function(a,b,c){(function(a){"use strict";if(c.base64=!0,c.array=!0,c.string=!0,c.arraybuffer="undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array,c.nodebuffer="undefined"!=typeof a,c.uint8array="undefined"!=typeof Uint8Array,"undefined"==typeof ArrayBuffer)c.blob=!1;else{var b=new ArrayBuffer(0);try{c.blob=0===new Blob([b],{type:"application/zip"}).size}catch(d){try{var e=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,f=new e;f.append(b),c.blob=0===f.getBlob("application/zip").size}catch(d){c.blob=!1}}}}).call(this,"undefined"!=typeof Buffer?Buffer:void 0)},{}],18:[function(a,b){"use strict";function c(a){a&&(this.data=a,this.length=this.data.length,this.index=0)}var d=a("./dataReader");c.prototype=new d,c.prototype.byteAt=function(a){return this.data[a]},c.prototype.lastIndexOfSignature=function(a){for(var b=a.charCodeAt(0),c=a.charCodeAt(1),d=a.charCodeAt(2),e=a.charCodeAt(3),f=this.length-4;f>=0;--f)if(this.data[f]===b&&this.data[f+1]===c&&this.data[f+2]===d&&this.data[f+3]===e)return f;return-1},c.prototype.readData=function(a){if(this.checkOffset(a),0===a)return new Uint8Array(0);var b=this.data.subarray(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./dataReader":5}],19:[function(a,b){"use strict";var c=a("./utils"),d=function(a){this.data=new Uint8Array(a),this.index=0};d.prototype={append:function(a){0!==a.length&&(a=c.transformTo("uint8array",a),this.data.set(a,this.index),this.index+=a.length)},finalize:function(){return this.data}},b.exports=d},{"./utils":21}],20:[function(a,b,c){"use strict";for(var d=a("./utils"),e=a("./support"),f=a("./nodeBuffer"),g=new Array(256),h=0;256>h;h++)g[h]=h>=252?6:h>=248?5:h>=240?4:h>=224?3:h>=192?2:1;g[254]=g[254]=1;var i=function(a){var b,c,d,f,g,h=a.length,i=0;for(f=0;h>f;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),i+=128>c?1:2048>c?2:65536>c?3:4;for(b=e.uint8array?new Uint8Array(i):new Array(i),g=0,f=0;i>g;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),128>c?b[g++]=c:2048>c?(b[g++]=192|c>>>6,b[g++]=128|63&c):65536>c?(b[g++]=224|c>>>12,b[g++]=128|c>>>6&63,b[g++]=128|63&c):(b[g++]=240|c>>>18,b[g++]=128|c>>>12&63,b[g++]=128|c>>>6&63,b[g++]=128|63&c);return b},j=function(a,b){var c;for(b=b||a.length,b>a.length&&(b=a.length),c=b-1;c>=0&&128===(192&a[c]);)c--;return 0>c?b:0===c?b:c+g[a[c]]>b?c:b},k=function(a){var b,c,e,f,h=a.length,i=new Array(2*h);for(c=0,b=0;h>b;)if(e=a[b++],128>e)i[c++]=e;else if(f=g[e],f>4)i[c++]=65533,b+=f-1;else{for(e&=2===f?31:3===f?15:7;f>1&&h>b;)e=e<<6|63&a[b++],f--;f>1?i[c++]=65533:65536>e?i[c++]=e:(e-=65536,i[c++]=55296|e>>10&1023,i[c++]=56320|1023&e)}return i.length!==c&&(i.subarray?i=i.subarray(0,c):i.length=c),d.applyFromCharCode(i)};c.utf8encode=function(a){return e.nodebuffer?f(a,"utf-8"):i(a)},c.utf8decode=function(a){if(e.nodebuffer)return d.transformTo("nodebuffer",a).toString("utf-8");a=d.transformTo(e.uint8array?"uint8array":"array",a);for(var b=[],c=0,f=a.length,g=65536;f>c;){var h=j(a,Math.min(c+g,f));b.push(e.uint8array?k(a.subarray(c,h)):k(a.slice(c,h))),c=h}return b.join("")}},{"./nodeBuffer":11,"./support":17,"./utils":21}],21:[function(a,b,c){"use strict";function d(a){return a}function e(a,b){for(var c=0;c<a.length;++c)b[c]=255&a.charCodeAt(c);return b}function f(a){var b=65536,d=[],e=a.length,f=c.getTypeOf(a),g=0,h=!0;try{switch(f){case"uint8array":String.fromCharCode.apply(null,new Uint8Array(0));break;case"nodebuffer":String.fromCharCode.apply(null,j(0))}}catch(i){h=!1}if(!h){for(var k="",l=0;l<a.length;l++)k+=String.fromCharCode(a[l]);return k}for(;e>g&&b>1;)try{d.push("array"===f||"nodebuffer"===f?String.fromCharCode.apply(null,a.slice(g,Math.min(g+b,e))):String.fromCharCode.apply(null,a.subarray(g,Math.min(g+b,e)))),g+=b}catch(i){b=Math.floor(b/2)}return d.join("")}function g(a,b){for(var c=0;c<a.length;c++)b[c]=a[c];return b}var h=a("./support"),i=a("./compressions"),j=a("./nodeBuffer");c.string2binary=function(a){for(var b="",c=0;c<a.length;c++)b+=String.fromCharCode(255&a.charCodeAt(c));return b},c.arrayBuffer2Blob=function(a){c.checkSupport("blob");try{return new Blob([a],{type:"application/zip"})}catch(b){try{var d=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,e=new d;return e.append(a),e.getBlob("application/zip")}catch(b){throw new Error("Bug : can't construct the Blob.")}}},c.applyFromCharCode=f;var k={};k.string={string:d,array:function(a){return e(a,new Array(a.length))},arraybuffer:function(a){return k.string.uint8array(a).buffer},uint8array:function(a){return e(a,new Uint8Array(a.length))},nodebuffer:function(a){return e(a,j(a.length))}},k.array={string:f,array:d,arraybuffer:function(a){return new Uint8Array(a).buffer},uint8array:function(a){return new Uint8Array(a)},nodebuffer:function(a){return j(a)}},k.arraybuffer={string:function(a){return f(new Uint8Array(a))},array:function(a){return g(new Uint8Array(a),new Array(a.byteLength))},arraybuffer:d,uint8array:function(a){return new Uint8Array(a)},nodebuffer:function(a){return j(new Uint8Array(a))}},k.uint8array={string:f,array:function(a){return g(a,new Array(a.length))},arraybuffer:function(a){return a.buffer},uint8array:d,nodebuffer:function(a){return j(a)}},k.nodebuffer={string:f,array:function(a){return g(a,new Array(a.length))},arraybuffer:function(a){return k.nodebuffer.uint8array(a).buffer},uint8array:function(a){return g(a,new Uint8Array(a.length))},nodebuffer:d},c.transformTo=function(a,b){if(b||(b=""),!a)return b;c.checkSupport(a);var d=c.getTypeOf(b),e=k[d][a](b);return e},c.getTypeOf=function(a){return"string"==typeof a?"string":"[object Array]"===Object.prototype.toString.call(a)?"array":h.nodebuffer&&j.test(a)?"nodebuffer":h.uint8array&&a instanceof Uint8Array?"uint8array":h.arraybuffer&&a instanceof ArrayBuffer?"arraybuffer":void 0},c.checkSupport=function(a){var b=h[a.toLowerCase()];if(!b)throw new Error(a+" is not supported by this browser")},c.MAX_VALUE_16BITS=65535,c.MAX_VALUE_32BITS=-1,c.pretty=function(a){var b,c,d="";for(c=0;c<(a||"").length;c++)b=a.charCodeAt(c),d+="\\x"+(16>b?"0":"")+b.toString(16).toUpperCase();return d},c.findCompression=function(a){for(var b in i)if(i.hasOwnProperty(b)&&i[b].magic===a)return i[b];return null},c.isRegExp=function(a){return"[object RegExp]"===Object.prototype.toString.call(a)}},{"./compressions":3,"./nodeBuffer":11,"./support":17}],22:[function(a,b){"use strict";function c(a,b){this.files=[],this.loadOptions=b,a&&this.load(a)}var d=a("./stringReader"),e=a("./nodeBufferReader"),f=a("./uint8ArrayReader"),g=a("./utils"),h=a("./signature"),i=a("./zipEntry"),j=a("./support"),k=a("./object");c.prototype={checkSignature:function(a){var b=this.reader.readString(4);if(b!==a)throw new Error("Corrupted zip or bug : unexpected signature ("+g.pretty(b)+", expected "+g.pretty(a)+")")},readBlockEndOfCentral:function(){this.diskNumber=this.reader.readInt(2),this.diskWithCentralDirStart=this.reader.readInt(2),this.centralDirRecordsOnThisDisk=this.reader.readInt(2),this.centralDirRecords=this.reader.readInt(2),this.centralDirSize=this.reader.readInt(4),this.centralDirOffset=this.reader.readInt(4),this.zipCommentLength=this.reader.readInt(2),this.zipComment=this.reader.readString(this.zipCommentLength),this.zipComment=k.utf8decode(this.zipComment)},readBlockZip64EndOfCentral:function(){this.zip64EndOfCentralSize=this.reader.readInt(8),this.versionMadeBy=this.reader.readString(2),this.versionNeeded=this.reader.readInt(2),this.diskNumber=this.reader.readInt(4),this.diskWithCentralDirStart=this.reader.readInt(4),this.centralDirRecordsOnThisDisk=this.reader.readInt(8),this.centralDirRecords=this.reader.readInt(8),this.centralDirSize=this.reader.readInt(8),this.centralDirOffset=this.reader.readInt(8),this.zip64ExtensibleData={};for(var a,b,c,d=this.zip64EndOfCentralSize-44,e=0;d>e;)a=this.reader.readInt(2),b=this.reader.readInt(4),c=this.reader.readString(b),this.zip64ExtensibleData[a]={id:a,length:b,value:c}},readBlockZip64EndOfCentralLocator:function(){if(this.diskWithZip64CentralDirStart=this.reader.readInt(4),this.relativeOffsetEndOfZip64CentralDir=this.reader.readInt(8),this.disksCount=this.reader.readInt(4),this.disksCount>1)throw new Error("Multi-volumes zip are not supported")},readLocalFiles:function(){var a,b;for(a=0;a<this.files.length;a++)b=this.files[a],this.reader.setIndex(b.localHeaderOffset),this.checkSignature(h.LOCAL_FILE_HEADER),b.readLocalPart(this.reader),b.handleUTF8()},readCentralDir:function(){var a;for(this.reader.setIndex(this.centralDirOffset);this.reader.readString(4)===h.CENTRAL_FILE_HEADER;)a=new i({zip64:this.zip64},this.loadOptions),a.readCentralPart(this.reader),this.files.push(a)},readEndOfCentral:function(){var a=this.reader.lastIndexOfSignature(h.CENTRAL_DIRECTORY_END);if(-1===a)throw new Error("Corrupted zip : can't find end of central directory");if(this.reader.setIndex(a),this.checkSignature(h.CENTRAL_DIRECTORY_END),this.readBlockEndOfCentral(),this.diskNumber===g.MAX_VALUE_16BITS||this.diskWithCentralDirStart===g.MAX_VALUE_16BITS||this.centralDirRecordsOnThisDisk===g.MAX_VALUE_16BITS||this.centralDirRecords===g.MAX_VALUE_16BITS||this.centralDirSize===g.MAX_VALUE_32BITS||this.centralDirOffset===g.MAX_VALUE_32BITS){if(this.zip64=!0,a=this.reader.lastIndexOfSignature(h.ZIP64_CENTRAL_DIRECTORY_LOCATOR),-1===a)throw new Error("Corrupted zip : can't find the ZIP64 end of central directory locator");this.reader.setIndex(a),this.checkSignature(h.ZIP64_CENTRAL_DIRECTORY_LOCATOR),this.readBlockZip64EndOfCentralLocator(),this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir),this.checkSignature(h.ZIP64_CENTRAL_DIRECTORY_END),this.readBlockZip64EndOfCentral()}},prepareReader:function(a){var b=g.getTypeOf(a);this.reader="string"!==b||j.uint8array?"nodebuffer"===b?new e(a):new f(g.transformTo("uint8array",a)):new d(a,this.loadOptions.optimizedBinaryString)},load:function(a){this.prepareReader(a),this.readEndOfCentral(),this.readCentralDir(),this.readLocalFiles()}},b.exports=c},{"./nodeBufferReader":12,"./object":13,"./signature":14,"./stringReader":15,"./support":17,"./uint8ArrayReader":18,"./utils":21,"./zipEntry":23}],23:[function(a,b){"use strict";function c(a,b){this.options=a,this.loadOptions=b}var d=a("./stringReader"),e=a("./utils"),f=a("./compressedObject"),g=a("./object");c.prototype={isEncrypted:function(){return 1===(1&this.bitFlag)},useUTF8:function(){return 2048===(2048&this.bitFlag)},prepareCompressedContent:function(a,b,c){return function(){var d=a.index;a.setIndex(b);var e=a.readData(c);return a.setIndex(d),e}},prepareContent:function(a,b,c,d,f){return function(){var a=e.transformTo(d.uncompressInputType,this.getCompressedContent()),b=d.uncompress(a);if(b.length!==f)throw new Error("Bug : uncompressed data size mismatch");return b}},readLocalPart:function(a){var b,c;if(a.skip(22),this.fileNameLength=a.readInt(2),c=a.readInt(2),this.fileName=a.readString(this.fileNameLength),a.skip(c),-1==this.compressedSize||-1==this.uncompressedSize)throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory (compressedSize == -1 || uncompressedSize == -1)");if(b=e.findCompression(this.compressionMethod),null===b)throw new Error("Corrupted zip : compression "+e.pretty(this.compressionMethod)+" unknown (inner file : "+this.fileName+")");if(this.decompressed=new f,this.decompressed.compressedSize=this.compressedSize,this.decompressed.uncompressedSize=this.uncompressedSize,this.decompressed.crc32=this.crc32,this.decompressed.compressionMethod=this.compressionMethod,this.decompressed.getCompressedContent=this.prepareCompressedContent(a,a.index,this.compressedSize,b),this.decompressed.getContent=this.prepareContent(a,a.index,this.compressedSize,b,this.uncompressedSize),this.loadOptions.checkCRC32&&(this.decompressed=e.transformTo("string",this.decompressed.getContent()),g.crc32(this.decompressed)!==this.crc32))throw new Error("Corrupted zip : CRC32 mismatch")},readCentralPart:function(a){if(this.versionMadeBy=a.readString(2),this.versionNeeded=a.readInt(2),this.bitFlag=a.readInt(2),this.compressionMethod=a.readString(2),this.date=a.readDate(),this.crc32=a.readInt(4),this.compressedSize=a.readInt(4),this.uncompressedSize=a.readInt(4),this.fileNameLength=a.readInt(2),this.extraFieldsLength=a.readInt(2),this.fileCommentLength=a.readInt(2),this.diskNumberStart=a.readInt(2),this.internalFileAttributes=a.readInt(2),this.externalFileAttributes=a.readInt(4),this.localHeaderOffset=a.readInt(4),this.isEncrypted())throw new Error("Encrypted zip are not supported");this.fileName=a.readString(this.fileNameLength),this.readExtraFields(a),this.parseZIP64ExtraField(a),this.fileComment=a.readString(this.fileCommentLength),this.dir=16&this.externalFileAttributes?!0:!1},parseZIP64ExtraField:function(){if(this.extraFields[1]){var a=new d(this.extraFields[1].value);this.uncompressedSize===e.MAX_VALUE_32BITS&&(this.uncompressedSize=a.readInt(8)),this.compressedSize===e.MAX_VALUE_32BITS&&(this.compressedSize=a.readInt(8)),this.localHeaderOffset===e.MAX_VALUE_32BITS&&(this.localHeaderOffset=a.readInt(8)),this.diskNumberStart===e.MAX_VALUE_32BITS&&(this.diskNumberStart=a.readInt(4))}},readExtraFields:function(a){var b,c,d,e=a.index;for(this.extraFields=this.extraFields||{};a.index<e+this.extraFieldsLength;)b=a.readInt(2),c=a.readInt(2),d=a.readString(c),this.extraFields[b]={id:b,length:c,value:d}},handleUTF8:function(){if(this.useUTF8())this.fileName=g.utf8decode(this.fileName),this.fileComment=g.utf8decode(this.fileComment);else{var a=this.findExtraFieldUnicodePath();null!==a&&(this.fileName=a);var b=this.findExtraFieldUnicodeComment();null!==b&&(this.fileComment=b)}},findExtraFieldUnicodePath:function(){var a=this.extraFields[28789];if(a){var b=new d(a.value);return 1!==b.readInt(1)?null:g.crc32(this.fileName)!==b.readInt(4)?null:g.utf8decode(b.readString(a.length-5))}return null},findExtraFieldUnicodeComment:function(){var a=this.extraFields[25461];if(a){var b=new d(a.value);return 1!==b.readInt(1)?null:g.crc32(this.fileComment)!==b.readInt(4)?null:g.utf8decode(b.readString(a.length-5))}return null}},b.exports=c},{"./compressedObject":2,"./object":13,"./stringReader":15,"./utils":21}],24:[function(a,b){"use strict";var c=a("./lib/utils/common").assign,d=a("./lib/deflate"),e=a("./lib/inflate"),f=a("./lib/zlib/constants"),g={};c(g,d,e,f),b.exports=g},{"./lib/deflate":25,"./lib/inflate":26,"./lib/utils/common":27,"./lib/zlib/constants":30}],25:[function(a,b,c){"use strict";function d(a,b){var c=new s(b);if(c.push(a,!0),c.err)throw c.msg;return c.result}function e(a,b){return b=b||{},b.raw=!0,d(a,b)}function f(a,b){return b=b||{},b.gzip=!0,d(a,b)}var g=a("./zlib/deflate.js"),h=a("./utils/common"),i=a("./utils/strings"),j=a("./zlib/messages"),k=a("./zlib/zstream"),l=0,m=4,n=0,o=1,p=-1,q=0,r=8,s=function(a){this.options=h.assign({level:p,method:r,chunkSize:16384,windowBits:15,memLevel:8,strategy:q,to:""},a||{});var b=this.options;b.raw&&b.windowBits>0?b.windowBits=-b.windowBits:b.gzip&&b.windowBits>0&&b.windowBits<16&&(b.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new k,this.strm.avail_out=0;var c=g.deflateInit2(this.strm,b.level,b.method,b.windowBits,b.memLevel,b.strategy);if(c!==n)throw new Error(j[c]);b.header&&g.deflateSetHeader(this.strm,b.header)};s.prototype.push=function(a,b){var c,d,e=this.strm,f=this.options.chunkSize;if(this.ended)return!1;d=b===~~b?b:b===!0?m:l,e.input="string"==typeof a?i.string2buf(a):a,e.next_in=0,e.avail_in=e.input.length;do{if(0===e.avail_out&&(e.output=new h.Buf8(f),e.next_out=0,e.avail_out=f),c=g.deflate(e,d),c!==o&&c!==n)return this.onEnd(c),this.ended=!0,!1;(0===e.avail_out||0===e.avail_in&&d===m)&&this.onData("string"===this.options.to?i.buf2binstring(h.shrinkBuf(e.output,e.next_out)):h.shrinkBuf(e.output,e.next_out))}while((e.avail_in>0||0===e.avail_out)&&c!==o);return d===m?(c=g.deflateEnd(this.strm),this.onEnd(c),this.ended=!0,c===n):!0},s.prototype.onData=function(a){this.chunks.push(a)},s.prototype.onEnd=function(a){a===n&&(this.result="string"===this.options.to?this.chunks.join(""):h.flattenChunks(this.chunks)),this.chunks=[],this.err=a,this.msg=this.strm.msg},c.Deflate=s,c.deflate=d,c.deflateRaw=e,c.gzip=f},{"./utils/common":27,"./utils/strings":28,"./zlib/deflate.js":32,"./zlib/messages":37,"./zlib/zstream":39}],26:[function(a,b,c){"use strict";function d(a,b){var c=new m(b);if(c.push(a,!0),c.err)throw c.msg;return c.result}function e(a,b){return b=b||{},b.raw=!0,d(a,b)}var f=a("./zlib/inflate.js"),g=a("./utils/common"),h=a("./utils/strings"),i=a("./zlib/constants"),j=a("./zlib/messages"),k=a("./zlib/zstream"),l=a("./zlib/gzheader"),m=function(a){this.options=g.assign({chunkSize:16384,windowBits:0,to:""},a||{});var b=this.options;b.raw&&b.windowBits>=0&&b.windowBits<16&&(b.windowBits=-b.windowBits,0===b.windowBits&&(b.windowBits=-15)),!(b.windowBits>=0&&b.windowBits<16)||a&&a.windowBits||(b.windowBits+=32),b.windowBits>15&&b.windowBits<48&&0===(15&b.windowBits)&&(b.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new k,this.strm.avail_out=0;var c=f.inflateInit2(this.strm,b.windowBits);if(c!==i.Z_OK)throw new Error(j[c]);this.header=new l,f.inflateGetHeader(this.strm,this.header)};m.prototype.push=function(a,b){var c,d,e,j,k,l=this.strm,m=this.options.chunkSize;if(this.ended)return!1;d=b===~~b?b:b===!0?i.Z_FINISH:i.Z_NO_FLUSH,l.input="string"==typeof a?h.binstring2buf(a):a,l.next_in=0,l.avail_in=l.input.length;do{if(0===l.avail_out&&(l.output=new g.Buf8(m),l.next_out=0,l.avail_out=m),c=f.inflate(l,i.Z_NO_FLUSH),c!==i.Z_STREAM_END&&c!==i.Z_OK)return this.onEnd(c),this.ended=!0,!1;l.next_out&&(0===l.avail_out||c===i.Z_STREAM_END||0===l.avail_in&&d===i.Z_FINISH)&&("string"===this.options.to?(e=h.utf8border(l.output,l.next_out),j=l.next_out-e,k=h.buf2string(l.output,e),l.next_out=j,l.avail_out=m-j,j&&g.arraySet(l.output,l.output,e,j,0),this.onData(k)):this.onData(g.shrinkBuf(l.output,l.next_out)))}while(l.avail_in>0&&c!==i.Z_STREAM_END);return c===i.Z_STREAM_END&&(d=i.Z_FINISH),d===i.Z_FINISH?(c=f.inflateEnd(this.strm),this.onEnd(c),this.ended=!0,c===i.Z_OK):!0},m.prototype.onData=function(a){this.chunks.push(a)},m.prototype.onEnd=function(a){a===i.Z_OK&&(this.result="string"===this.options.to?this.chunks.join(""):g.flattenChunks(this.chunks)),this.chunks=[],this.err=a,this.msg=this.strm.msg},c.Inflate=m,c.inflate=d,c.inflateRaw=e,c.ungzip=d},{"./utils/common":27,"./utils/strings":28,"./zlib/constants":30,"./zlib/gzheader":33,"./zlib/inflate.js":35,"./zlib/messages":37,"./zlib/zstream":39}],27:[function(a,b,c){"use strict";var d="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;c.assign=function(a){for(var b=Array.prototype.slice.call(arguments,1);b.length;){var c=b.shift();if(c){if("object"!=typeof c)throw new TypeError(c+"must be non-object");for(var d in c)c.hasOwnProperty(d)&&(a[d]=c[d])}}return a},c.shrinkBuf=function(a,b){return a.length===b?a:a.subarray?a.subarray(0,b):(a.length=b,a)};var e={arraySet:function(a,b,c,d,e){if(b.subarray&&a.subarray)return void a.set(b.subarray(c,c+d),e);for(var f=0;d>f;f++)a[e+f]=b[c+f]},flattenChunks:function(a){var b,c,d,e,f,g;for(d=0,b=0,c=a.length;c>b;b++)d+=a[b].length;for(g=new Uint8Array(d),e=0,b=0,c=a.length;c>b;b++)f=a[b],g.set(f,e),e+=f.length;return g}},f={arraySet:function(a,b,c,d,e){for(var f=0;d>f;f++)a[e+f]=b[c+f]},flattenChunks:function(a){return[].concat.apply([],a)}};c.setTyped=function(a){a?(c.Buf8=Uint8Array,c.Buf16=Uint16Array,c.Buf32=Int32Array,c.assign(c,e)):(c.Buf8=Array,c.Buf16=Array,c.Buf32=Array,c.assign(c,f))},c.setTyped(d)},{}],28:[function(a,b,c){"use strict";function d(a,b){if(65537>b&&(a.subarray&&g||!a.subarray&&f))return String.fromCharCode.apply(null,e.shrinkBuf(a,b));for(var c="",d=0;b>d;d++)c+=String.fromCharCode(a[d]);return c}var e=a("./common"),f=!0,g=!0;try{String.fromCharCode.apply(null,[0])}catch(h){f=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(h){g=!1}for(var i=new e.Buf8(256),j=0;256>j;j++)i[j]=j>=252?6:j>=248?5:j>=240?4:j>=224?3:j>=192?2:1;i[254]=i[254]=1,c.string2buf=function(a){var b,c,d,f,g,h=a.length,i=0;for(f=0;h>f;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),i+=128>c?1:2048>c?2:65536>c?3:4;for(b=new e.Buf8(i),g=0,f=0;i>g;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),128>c?b[g++]=c:2048>c?(b[g++]=192|c>>>6,b[g++]=128|63&c):65536>c?(b[g++]=224|c>>>12,b[g++]=128|c>>>6&63,b[g++]=128|63&c):(b[g++]=240|c>>>18,b[g++]=128|c>>>12&63,b[g++]=128|c>>>6&63,b[g++]=128|63&c);return b},c.buf2binstring=function(a){return d(a,a.length)},c.binstring2buf=function(a){for(var b=new e.Buf8(a.length),c=0,d=b.length;d>c;c++)b[c]=a.charCodeAt(c);return b},c.buf2string=function(a,b){var c,e,f,g,h=b||a.length,j=new Array(2*h);for(e=0,c=0;h>c;)if(f=a[c++],128>f)j[e++]=f;else if(g=i[f],g>4)j[e++]=65533,c+=g-1;else{for(f&=2===g?31:3===g?15:7;g>1&&h>c;)f=f<<6|63&a[c++],g--;g>1?j[e++]=65533:65536>f?j[e++]=f:(f-=65536,j[e++]=55296|f>>10&1023,j[e++]=56320|1023&f)}return d(j,e)},c.utf8border=function(a,b){var c;for(b=b||a.length,b>a.length&&(b=a.length),c=b-1;c>=0&&128===(192&a[c]);)c--;return 0>c?b:0===c?b:c+i[a[c]]>b?c:b}},{"./common":27}],29:[function(a,b){"use strict";function c(a,b,c,d){for(var e=65535&a|0,f=a>>>16&65535|0,g=0;0!==c;){g=c>2e3?2e3:c,c-=g;do e=e+b[d++]|0,f=f+e|0;while(--g);e%=65521,f%=65521}return e|f<<16|0}b.exports=c},{}],30:[function(a,b){b.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},{}],31:[function(a,b){"use strict";function c(){for(var a,b=[],c=0;256>c;c++){a=c;for(var d=0;8>d;d++)a=1&a?3988292384^a>>>1:a>>>1;b[c]=a}return b}function d(a,b,c,d){var f=e,g=d+c;a=-1^a;for(var h=d;g>h;h++)a=a>>>8^f[255&(a^b[h])];return-1^a}var e=c();b.exports=d},{}],32:[function(a,b,c){"use strict";function d(a,b){return a.msg=G[b],b}function e(a){return(a<<1)-(a>4?9:0)}function f(a){for(var b=a.length;--b>=0;)a[b]=0}function g(a){var b=a.state,c=b.pending;c>a.avail_out&&(c=a.avail_out),0!==c&&(C.arraySet(a.output,b.pending_buf,b.pending_out,c,a.next_out),a.next_out+=c,b.pending_out+=c,a.total_out+=c,a.avail_out-=c,b.pending-=c,0===b.pending&&(b.pending_out=0))}function h(a,b){D._tr_flush_block(a,a.block_start>=0?a.block_start:-1,a.strstart-a.block_start,b),a.block_start=a.strstart,g(a.strm)}function i(a,b){a.pending_buf[a.pending++]=b}function j(a,b){a.pending_buf[a.pending++]=b>>>8&255,a.pending_buf[a.pending++]=255&b}function k(a,b,c,d){var e=a.avail_in;return e>d&&(e=d),0===e?0:(a.avail_in-=e,C.arraySet(b,a.input,a.next_in,e,c),1===a.state.wrap?a.adler=E(a.adler,b,e,c):2===a.state.wrap&&(a.adler=F(a.adler,b,e,c)),a.next_in+=e,a.total_in+=e,e)}function l(a,b){var c,d,e=a.max_chain_length,f=a.strstart,g=a.prev_length,h=a.nice_match,i=a.strstart>a.w_size-jb?a.strstart-(a.w_size-jb):0,j=a.window,k=a.w_mask,l=a.prev,m=a.strstart+ib,n=j[f+g-1],o=j[f+g];a.prev_length>=a.good_match&&(e>>=2),h>a.lookahead&&(h=a.lookahead);do if(c=b,j[c+g]===o&&j[c+g-1]===n&&j[c]===j[f]&&j[++c]===j[f+1]){f+=2,c++;do;while(j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&m>f);if(d=ib-(m-f),f=m-ib,d>g){if(a.match_start=b,g=d,d>=h)break;n=j[f+g-1],o=j[f+g]}}while((b=l[b&k])>i&&0!==--e);return g<=a.lookahead?g:a.lookahead}function m(a){var b,c,d,e,f,g=a.w_size;do{if(e=a.window_size-a.lookahead-a.strstart,a.strstart>=g+(g-jb)){C.arraySet(a.window,a.window,g,g,0),a.match_start-=g,a.strstart-=g,a.block_start-=g,c=a.hash_size,b=c;do d=a.head[--b],a.head[b]=d>=g?d-g:0;while(--c);c=g,b=c;do d=a.prev[--b],a.prev[b]=d>=g?d-g:0;while(--c);e+=g}if(0===a.strm.avail_in)break;if(c=k(a.strm,a.window,a.strstart+a.lookahead,e),a.lookahead+=c,a.lookahead+a.insert>=hb)for(f=a.strstart-a.insert,a.ins_h=a.window[f],a.ins_h=(a.ins_h<<a.hash_shift^a.window[f+1])&a.hash_mask;a.insert&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[f+hb-1])&a.hash_mask,a.prev[f&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=f,f++,a.insert--,!(a.lookahead+a.insert<hb)););}while(a.lookahead<jb&&0!==a.strm.avail_in)}function n(a,b){var c=65535;for(c>a.pending_buf_size-5&&(c=a.pending_buf_size-5);;){if(a.lookahead<=1){if(m(a),0===a.lookahead&&b===H)return sb;if(0===a.lookahead)break}a.strstart+=a.lookahead,a.lookahead=0;var d=a.block_start+c;if((0===a.strstart||a.strstart>=d)&&(a.lookahead=a.strstart-d,a.strstart=d,h(a,!1),0===a.strm.avail_out))return sb;if(a.strstart-a.block_start>=a.w_size-jb&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.strstart>a.block_start&&(h(a,!1),0===a.strm.avail_out)?sb:sb}function o(a,b){for(var c,d;;){if(a.lookahead<jb){if(m(a),a.lookahead<jb&&b===H)return sb;if(0===a.lookahead)break}if(c=0,a.lookahead>=hb&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart),0!==c&&a.strstart-c<=a.w_size-jb&&(a.match_length=l(a,c)),a.match_length>=hb)if(d=D._tr_tally(a,a.strstart-a.match_start,a.match_length-hb),a.lookahead-=a.match_length,a.match_length<=a.max_lazy_match&&a.lookahead>=hb){a.match_length--;do a.strstart++,a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart;while(0!==--a.match_length);a.strstart++}else a.strstart+=a.match_length,a.match_length=0,a.ins_h=a.window[a.strstart],a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+1])&a.hash_mask;else d=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++;if(d&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=a.strstart<hb-1?a.strstart:hb-1,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function p(a,b){for(var c,d,e;;){if(a.lookahead<jb){if(m(a),a.lookahead<jb&&b===H)return sb;if(0===a.lookahead)break}if(c=0,a.lookahead>=hb&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart),a.prev_length=a.match_length,a.prev_match=a.match_start,a.match_length=hb-1,0!==c&&a.prev_length<a.max_lazy_match&&a.strstart-c<=a.w_size-jb&&(a.match_length=l(a,c),a.match_length<=5&&(a.strategy===S||a.match_length===hb&&a.strstart-a.match_start>4096)&&(a.match_length=hb-1)),a.prev_length>=hb&&a.match_length<=a.prev_length){e=a.strstart+a.lookahead-hb,d=D._tr_tally(a,a.strstart-1-a.prev_match,a.prev_length-hb),a.lookahead-=a.prev_length-1,a.prev_length-=2;do++a.strstart<=e&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart);while(0!==--a.prev_length);if(a.match_available=0,a.match_length=hb-1,a.strstart++,d&&(h(a,!1),0===a.strm.avail_out))return sb}else if(a.match_available){if(d=D._tr_tally(a,0,a.window[a.strstart-1]),d&&h(a,!1),a.strstart++,a.lookahead--,0===a.strm.avail_out)return sb}else a.match_available=1,a.strstart++,a.lookahead--}return a.match_available&&(d=D._tr_tally(a,0,a.window[a.strstart-1]),a.match_available=0),a.insert=a.strstart<hb-1?a.strstart:hb-1,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function q(a,b){for(var c,d,e,f,g=a.window;;){if(a.lookahead<=ib){if(m(a),a.lookahead<=ib&&b===H)return sb;if(0===a.lookahead)break}if(a.match_length=0,a.lookahead>=hb&&a.strstart>0&&(e=a.strstart-1,d=g[e],d===g[++e]&&d===g[++e]&&d===g[++e])){f=a.strstart+ib;do;while(d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&f>e);a.match_length=ib-(f-e),a.match_length>a.lookahead&&(a.match_length=a.lookahead)}if(a.match_length>=hb?(c=D._tr_tally(a,1,a.match_length-hb),a.lookahead-=a.match_length,a.strstart+=a.match_length,a.match_length=0):(c=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++),c&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function r(a,b){for(var c;;){if(0===a.lookahead&&(m(a),0===a.lookahead)){if(b===H)return sb;break}if(a.match_length=0,c=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++,c&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function s(a){a.window_size=2*a.w_size,f(a.head),a.max_lazy_match=B[a.level].max_lazy,a.good_match=B[a.level].good_length,a.nice_match=B[a.level].nice_length,a.max_chain_length=B[a.level].max_chain,a.strstart=0,a.block_start=0,a.lookahead=0,a.insert=0,a.match_length=a.prev_length=hb-1,a.match_available=0,a.ins_h=0}function t(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=Y,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new C.Buf16(2*fb),this.dyn_dtree=new C.Buf16(2*(2*db+1)),this.bl_tree=new C.Buf16(2*(2*eb+1)),f(this.dyn_ltree),f(this.dyn_dtree),f(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new C.Buf16(gb+1),this.heap=new C.Buf16(2*cb+1),f(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new C.Buf16(2*cb+1),f(this.depth),this.l_buf=0,this.lit_bufsize=0,this.last_lit=0,this.d_buf=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}function u(a){var b;return a&&a.state?(a.total_in=a.total_out=0,a.data_type=X,b=a.state,b.pending=0,b.pending_out=0,b.wrap<0&&(b.wrap=-b.wrap),b.status=b.wrap?lb:qb,a.adler=2===b.wrap?0:1,b.last_flush=H,D._tr_init(b),M):d(a,O)}function v(a){var b=u(a);return b===M&&s(a.state),b}function w(a,b){return a&&a.state?2!==a.state.wrap?O:(a.state.gzhead=b,M):O}function x(a,b,c,e,f,g){if(!a)return O;var h=1;if(b===R&&(b=6),0>e?(h=0,e=-e):e>15&&(h=2,e-=16),1>f||f>Z||c!==Y||8>e||e>15||0>b||b>9||0>g||g>V)return d(a,O);8===e&&(e=9);var i=new t;return a.state=i,i.strm=a,i.wrap=h,i.gzhead=null,i.w_bits=e,i.w_size=1<<i.w_bits,i.w_mask=i.w_size-1,i.hash_bits=f+7,i.hash_size=1<<i.hash_bits,i.hash_mask=i.hash_size-1,i.hash_shift=~~((i.hash_bits+hb-1)/hb),i.window=new C.Buf8(2*i.w_size),i.head=new C.Buf16(i.hash_size),i.prev=new C.Buf16(i.w_size),i.lit_bufsize=1<<f+6,i.pending_buf_size=4*i.lit_bufsize,i.pending_buf=new C.Buf8(i.pending_buf_size),i.d_buf=i.lit_bufsize>>1,i.l_buf=3*i.lit_bufsize,i.level=b,i.strategy=g,i.method=c,v(a)}function y(a,b){return x(a,b,Y,$,_,W)}function z(a,b){var c,h,k,l;if(!a||!a.state||b>L||0>b)return a?d(a,O):O;if(h=a.state,!a.output||!a.input&&0!==a.avail_in||h.status===rb&&b!==K)return d(a,0===a.avail_out?Q:O);if(h.strm=a,c=h.last_flush,h.last_flush=b,h.status===lb)if(2===h.wrap)a.adler=0,i(h,31),i(h,139),i(h,8),h.gzhead?(i(h,(h.gzhead.text?1:0)+(h.gzhead.hcrc?2:0)+(h.gzhead.extra?4:0)+(h.gzhead.name?8:0)+(h.gzhead.comment?16:0)),i(h,255&h.gzhead.time),i(h,h.gzhead.time>>8&255),i(h,h.gzhead.time>>16&255),i(h,h.gzhead.time>>24&255),i(h,9===h.level?2:h.strategy>=T||h.level<2?4:0),i(h,255&h.gzhead.os),h.gzhead.extra&&h.gzhead.extra.length&&(i(h,255&h.gzhead.extra.length),i(h,h.gzhead.extra.length>>8&255)),h.gzhead.hcrc&&(a.adler=F(a.adler,h.pending_buf,h.pending,0)),h.gzindex=0,h.status=mb):(i(h,0),i(h,0),i(h,0),i(h,0),i(h,0),i(h,9===h.level?2:h.strategy>=T||h.level<2?4:0),i(h,wb),h.status=qb);else{var m=Y+(h.w_bits-8<<4)<<8,n=-1;n=h.strategy>=T||h.level<2?0:h.level<6?1:6===h.level?2:3,m|=n<<6,0!==h.strstart&&(m|=kb),m+=31-m%31,h.status=qb,j(h,m),0!==h.strstart&&(j(h,a.adler>>>16),j(h,65535&a.adler)),a.adler=1}if(h.status===mb)if(h.gzhead.extra){for(k=h.pending;h.gzindex<(65535&h.gzhead.extra.length)&&(h.pending!==h.pending_buf_size||(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending!==h.pending_buf_size));)i(h,255&h.gzhead.extra[h.gzindex]),h.gzindex++;h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),h.gzindex===h.gzhead.extra.length&&(h.gzindex=0,h.status=nb)}else h.status=nb;if(h.status===nb)if(h.gzhead.name){k=h.pending;do{if(h.pending===h.pending_buf_size&&(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending===h.pending_buf_size)){l=1;break}l=h.gzindex<h.gzhead.name.length?255&h.gzhead.name.charCodeAt(h.gzindex++):0,i(h,l)}while(0!==l);h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),0===l&&(h.gzindex=0,h.status=ob)}else h.status=ob;if(h.status===ob)if(h.gzhead.comment){k=h.pending;do{if(h.pending===h.pending_buf_size&&(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending===h.pending_buf_size)){l=1;break}l=h.gzindex<h.gzhead.comment.length?255&h.gzhead.comment.charCodeAt(h.gzindex++):0,i(h,l)}while(0!==l);h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),0===l&&(h.status=pb)}else h.status=pb;if(h.status===pb&&(h.gzhead.hcrc?(h.pending+2>h.pending_buf_size&&g(a),h.pending+2<=h.pending_buf_size&&(i(h,255&a.adler),i(h,a.adler>>8&255),a.adler=0,h.status=qb)):h.status=qb),0!==h.pending){if(g(a),0===a.avail_out)return h.last_flush=-1,M}else if(0===a.avail_in&&e(b)<=e(c)&&b!==K)return d(a,Q);if(h.status===rb&&0!==a.avail_in)return d(a,Q);if(0!==a.avail_in||0!==h.lookahead||b!==H&&h.status!==rb){var o=h.strategy===T?r(h,b):h.strategy===U?q(h,b):B[h.level].func(h,b);if((o===ub||o===vb)&&(h.status=rb),o===sb||o===ub)return 0===a.avail_out&&(h.last_flush=-1),M;if(o===tb&&(b===I?D._tr_align(h):b!==L&&(D._tr_stored_block(h,0,0,!1),b===J&&(f(h.head),0===h.lookahead&&(h.strstart=0,h.block_start=0,h.insert=0))),g(a),0===a.avail_out))return h.last_flush=-1,M}return b!==K?M:h.wrap<=0?N:(2===h.wrap?(i(h,255&a.adler),i(h,a.adler>>8&255),i(h,a.adler>>16&255),i(h,a.adler>>24&255),i(h,255&a.total_in),i(h,a.total_in>>8&255),i(h,a.total_in>>16&255),i(h,a.total_in>>24&255)):(j(h,a.adler>>>16),j(h,65535&a.adler)),g(a),h.wrap>0&&(h.wrap=-h.wrap),0!==h.pending?M:N)}function A(a){var b;return a&&a.state?(b=a.state.status,b!==lb&&b!==mb&&b!==nb&&b!==ob&&b!==pb&&b!==qb&&b!==rb?d(a,O):(a.state=null,b===qb?d(a,P):M)):O}var B,C=a("../utils/common"),D=a("./trees"),E=a("./adler32"),F=a("./crc32"),G=a("./messages"),H=0,I=1,J=3,K=4,L=5,M=0,N=1,O=-2,P=-3,Q=-5,R=-1,S=1,T=2,U=3,V=4,W=0,X=2,Y=8,Z=9,$=15,_=8,ab=29,bb=256,cb=bb+1+ab,db=30,eb=19,fb=2*cb+1,gb=15,hb=3,ib=258,jb=ib+hb+1,kb=32,lb=42,mb=69,nb=73,ob=91,pb=103,qb=113,rb=666,sb=1,tb=2,ub=3,vb=4,wb=3,xb=function(a,b,c,d,e){this.good_length=a,this.max_lazy=b,this.nice_length=c,this.max_chain=d,this.func=e};B=[new xb(0,0,0,0,n),new xb(4,4,8,4,o),new xb(4,5,16,8,o),new xb(4,6,32,32,o),new xb(4,4,16,16,p),new xb(8,16,32,32,p),new xb(8,16,128,128,p),new xb(8,32,128,256,p),new xb(32,128,258,1024,p),new xb(32,258,258,4096,p)],c.deflateInit=y,c.deflateInit2=x,c.deflateReset=v,c.deflateResetKeep=u,c.deflateSetHeader=w,c.deflate=z,c.deflateEnd=A,c.deflateInfo="pako deflate (from Nodeca project)"},{"../utils/common":27,"./adler32":29,"./crc32":31,"./messages":37,"./trees":38}],33:[function(a,b){"use strict";function c(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}b.exports=c},{}],34:[function(a,b){"use strict";var c=30,d=12;b.exports=function(a,b){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C;e=a.state,f=a.next_in,B=a.input,g=f+(a.avail_in-5),h=a.next_out,C=a.output,i=h-(b-a.avail_out),j=h+(a.avail_out-257),k=e.dmax,l=e.wsize,m=e.whave,n=e.wnext,o=e.window,p=e.hold,q=e.bits,r=e.lencode,s=e.distcode,t=(1<<e.lenbits)-1,u=(1<<e.distbits)-1;a:do{15>q&&(p+=B[f++]<<q,q+=8,p+=B[f++]<<q,q+=8),v=r[p&t];b:for(;;){if(w=v>>>24,p>>>=w,q-=w,w=v>>>16&255,0===w)C[h++]=65535&v;else{if(!(16&w)){if(0===(64&w)){v=r[(65535&v)+(p&(1<<w)-1)];continue b}if(32&w){e.mode=d;break a}a.msg="invalid literal/length code",e.mode=c;break a}x=65535&v,w&=15,w&&(w>q&&(p+=B[f++]<<q,q+=8),x+=p&(1<<w)-1,p>>>=w,q-=w),15>q&&(p+=B[f++]<<q,q+=8,p+=B[f++]<<q,q+=8),v=s[p&u];c:for(;;){if(w=v>>>24,p>>>=w,q-=w,w=v>>>16&255,!(16&w)){if(0===(64&w)){v=s[(65535&v)+(p&(1<<w)-1)];continue c}a.msg="invalid distance code",e.mode=c;break a}if(y=65535&v,w&=15,w>q&&(p+=B[f++]<<q,q+=8,w>q&&(p+=B[f++]<<q,q+=8)),y+=p&(1<<w)-1,y>k){a.msg="invalid distance too far back",e.mode=c;break a}if(p>>>=w,q-=w,w=h-i,y>w){if(w=y-w,w>m&&e.sane){a.msg="invalid distance too far back",e.mode=c;break a}if(z=0,A=o,0===n){if(z+=l-w,x>w){x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}}else if(w>n){if(z+=l+n-w,w-=n,x>w){x-=w;do C[h++]=o[z++];while(--w);if(z=0,x>n){w=n,x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}}}else if(z+=n-w,x>w){x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}for(;x>2;)C[h++]=A[z++],C[h++]=A[z++],C[h++]=A[z++],x-=3;x&&(C[h++]=A[z++],x>1&&(C[h++]=A[z++]))}else{z=h-y;do C[h++]=C[z++],C[h++]=C[z++],C[h++]=C[z++],x-=3;while(x>2);x&&(C[h++]=C[z++],x>1&&(C[h++]=C[z++]))}break}}break}}while(g>f&&j>h);x=q>>3,f-=x,q-=x<<3,p&=(1<<q)-1,a.next_in=f,a.next_out=h,a.avail_in=g>f?5+(g-f):5-(f-g),a.avail_out=j>h?257+(j-h):257-(h-j),e.hold=p,e.bits=q}},{}],35:[function(a,b,c){"use strict";function d(a){return(a>>>24&255)+(a>>>8&65280)+((65280&a)<<8)+((255&a)<<24)}function e(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new r.Buf16(320),this.work=new r.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function f(a){var b;return a&&a.state?(b=a.state,a.total_in=a.total_out=b.total=0,a.msg="",b.wrap&&(a.adler=1&b.wrap),b.mode=K,b.last=0,b.havedict=0,b.dmax=32768,b.head=null,b.hold=0,b.bits=0,b.lencode=b.lendyn=new r.Buf32(ob),b.distcode=b.distdyn=new r.Buf32(pb),b.sane=1,b.back=-1,C):F}function g(a){var b;return a&&a.state?(b=a.state,b.wsize=0,b.whave=0,b.wnext=0,f(a)):F}function h(a,b){var c,d;return a&&a.state?(d=a.state,0>b?(c=0,b=-b):(c=(b>>4)+1,48>b&&(b&=15)),b&&(8>b||b>15)?F:(null!==d.window&&d.wbits!==b&&(d.window=null),d.wrap=c,d.wbits=b,g(a))):F}function i(a,b){var c,d;return a?(d=new e,a.state=d,d.window=null,c=h(a,b),c!==C&&(a.state=null),c):F}function j(a){return i(a,rb)}function k(a){if(sb){var b;for(p=new r.Buf32(512),q=new r.Buf32(32),b=0;144>b;)a.lens[b++]=8;for(;256>b;)a.lens[b++]=9;for(;280>b;)a.lens[b++]=7;for(;288>b;)a.lens[b++]=8;for(v(x,a.lens,0,288,p,0,a.work,{bits:9}),b=0;32>b;)a.lens[b++]=5;v(y,a.lens,0,32,q,0,a.work,{bits:5}),sb=!1}a.lencode=p,a.lenbits=9,a.distcode=q,a.distbits=5}function l(a,b,c,d){var e,f=a.state;return null===f.window&&(f.wsize=1<<f.wbits,f.wnext=0,f.whave=0,f.window=new r.Buf8(f.wsize)),d>=f.wsize?(r.arraySet(f.window,b,c-f.wsize,f.wsize,0),f.wnext=0,f.whave=f.wsize):(e=f.wsize-f.wnext,e>d&&(e=d),r.arraySet(f.window,b,c-d,e,f.wnext),d-=e,d?(r.arraySet(f.window,b,c-d,d,0),f.wnext=d,f.whave=f.wsize):(f.wnext+=e,f.wnext===f.wsize&&(f.wnext=0),f.whave<f.wsize&&(f.whave+=e))),0}function m(a,b){var c,e,f,g,h,i,j,m,n,o,p,q,ob,pb,qb,rb,sb,tb,ub,vb,wb,xb,yb,zb,Ab=0,Bb=new r.Buf8(4),Cb=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];if(!a||!a.state||!a.output||!a.input&&0!==a.avail_in)return F;c=a.state,c.mode===V&&(c.mode=W),h=a.next_out,f=a.output,j=a.avail_out,g=a.next_in,e=a.input,i=a.avail_in,m=c.hold,n=c.bits,o=i,p=j,xb=C;a:for(;;)switch(c.mode){case K:if(0===c.wrap){c.mode=W;break}for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(2&c.wrap&&35615===m){c.check=0,Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0),m=0,n=0,c.mode=L;break}if(c.flags=0,c.head&&(c.head.done=!1),!(1&c.wrap)||(((255&m)<<8)+(m>>8))%31){a.msg="incorrect header check",c.mode=lb;break}if((15&m)!==J){a.msg="unknown compression method",c.mode=lb;break}if(m>>>=4,n-=4,wb=(15&m)+8,0===c.wbits)c.wbits=wb;else if(wb>c.wbits){a.msg="invalid window size",c.mode=lb;break}c.dmax=1<<wb,a.adler=c.check=1,c.mode=512&m?T:V,m=0,n=0;break;case L:for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(c.flags=m,(255&c.flags)!==J){a.msg="unknown compression method",c.mode=lb;break}if(57344&c.flags){a.msg="unknown header flags set",c.mode=lb;break}c.head&&(c.head.text=m>>8&1),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0,c.mode=M;case M:for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.head&&(c.head.time=m),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,Bb[2]=m>>>16&255,Bb[3]=m>>>24&255,c.check=t(c.check,Bb,4,0)),m=0,n=0,c.mode=N;case N:for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.head&&(c.head.xflags=255&m,c.head.os=m>>8),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0,c.mode=O;case O:if(1024&c.flags){for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.length=m,c.head&&(c.head.extra_len=m),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0}else c.head&&(c.head.extra=null);c.mode=P;case P:if(1024&c.flags&&(q=c.length,q>i&&(q=i),q&&(c.head&&(wb=c.head.extra_len-c.length,c.head.extra||(c.head.extra=new Array(c.head.extra_len)),r.arraySet(c.head.extra,e,g,q,wb)),512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,c.length-=q),c.length))break a;c.length=0,c.mode=Q;case Q:if(2048&c.flags){if(0===i)break a;q=0;do wb=e[g+q++],c.head&&wb&&c.length<65536&&(c.head.name+=String.fromCharCode(wb));while(wb&&i>q);if(512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,wb)break a}else c.head&&(c.head.name=null);c.length=0,c.mode=R;case R:if(4096&c.flags){if(0===i)break a;q=0;do wb=e[g+q++],c.head&&wb&&c.length<65536&&(c.head.comment+=String.fromCharCode(wb));while(wb&&i>q);if(512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,wb)break a}else c.head&&(c.head.comment=null);c.mode=S;case S:if(512&c.flags){for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m!==(65535&c.check)){a.msg="header crc mismatch",c.mode=lb;break}m=0,n=0}c.head&&(c.head.hcrc=c.flags>>9&1,c.head.done=!0),a.adler=c.check=0,c.mode=V;break;case T:for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}a.adler=c.check=d(m),m=0,n=0,c.mode=U;case U:if(0===c.havedict)return a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,E;a.adler=c.check=1,c.mode=V;case V:if(b===A||b===B)break a;case W:if(c.last){m>>>=7&n,n-=7&n,c.mode=ib;break}for(;3>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}switch(c.last=1&m,m>>>=1,n-=1,3&m){case 0:c.mode=X;break;case 1:if(k(c),c.mode=bb,b===B){m>>>=2,n-=2;break a}break;case 2:c.mode=$;break;case 3:a.msg="invalid block type",c.mode=lb}m>>>=2,n-=2;break;case X:for(m>>>=7&n,n-=7&n;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if((65535&m)!==(m>>>16^65535)){a.msg="invalid stored block lengths",c.mode=lb;break}if(c.length=65535&m,m=0,n=0,c.mode=Y,b===B)break a;case Y:c.mode=Z;case Z:if(q=c.length){if(q>i&&(q=i),q>j&&(q=j),0===q)break a;r.arraySet(f,e,g,q,h),i-=q,g+=q,j-=q,h+=q,c.length-=q;break}c.mode=V;break;case $:for(;14>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(c.nlen=(31&m)+257,m>>>=5,n-=5,c.ndist=(31&m)+1,m>>>=5,n-=5,c.ncode=(15&m)+4,m>>>=4,n-=4,c.nlen>286||c.ndist>30){a.msg="too many length or distance symbols",c.mode=lb;break}c.have=0,c.mode=_;case _:for(;c.have<c.ncode;){for(;3>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.lens[Cb[c.have++]]=7&m,m>>>=3,n-=3}for(;c.have<19;)c.lens[Cb[c.have++]]=0;if(c.lencode=c.lendyn,c.lenbits=7,yb={bits:c.lenbits},xb=v(w,c.lens,0,19,c.lencode,0,c.work,yb),c.lenbits=yb.bits,xb){a.msg="invalid code lengths set",c.mode=lb;break}c.have=0,c.mode=ab;case ab:for(;c.have<c.nlen+c.ndist;){for(;Ab=c.lencode[m&(1<<c.lenbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(16>sb)m>>>=qb,n-=qb,c.lens[c.have++]=sb;else{if(16===sb){for(zb=qb+2;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m>>>=qb,n-=qb,0===c.have){a.msg="invalid bit length repeat",c.mode=lb;break}wb=c.lens[c.have-1],q=3+(3&m),m>>>=2,n-=2}else if(17===sb){for(zb=qb+3;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=qb,n-=qb,wb=0,q=3+(7&m),m>>>=3,n-=3}else{for(zb=qb+7;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=qb,n-=qb,wb=0,q=11+(127&m),m>>>=7,n-=7}if(c.have+q>c.nlen+c.ndist){a.msg="invalid bit length repeat",c.mode=lb;break}for(;q--;)c.lens[c.have++]=wb}}if(c.mode===lb)break;if(0===c.lens[256]){a.msg="invalid code -- missing end-of-block",c.mode=lb;break}if(c.lenbits=9,yb={bits:c.lenbits},xb=v(x,c.lens,0,c.nlen,c.lencode,0,c.work,yb),c.lenbits=yb.bits,xb){a.msg="invalid literal/lengths set",c.mode=lb;break}if(c.distbits=6,c.distcode=c.distdyn,yb={bits:c.distbits},xb=v(y,c.lens,c.nlen,c.ndist,c.distcode,0,c.work,yb),c.distbits=yb.bits,xb){a.msg="invalid distances set",c.mode=lb;break}if(c.mode=bb,b===B)break a;case bb:c.mode=cb;case cb:if(i>=6&&j>=258){a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,u(a,p),h=a.next_out,f=a.output,j=a.avail_out,g=a.next_in,e=a.input,i=a.avail_in,m=c.hold,n=c.bits,c.mode===V&&(c.back=-1);break}for(c.back=0;Ab=c.lencode[m&(1<<c.lenbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(rb&&0===(240&rb)){for(tb=qb,ub=rb,vb=sb;Ab=c.lencode[vb+((m&(1<<tb+ub)-1)>>tb)],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=tb+qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=tb,n-=tb,c.back+=tb}if(m>>>=qb,n-=qb,c.back+=qb,c.length=sb,0===rb){c.mode=hb;break}if(32&rb){c.back=-1,c.mode=V;break}if(64&rb){a.msg="invalid literal/length code",c.mode=lb;break}c.extra=15&rb,c.mode=db;case db:if(c.extra){for(zb=c.extra;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.length+=m&(1<<c.extra)-1,m>>>=c.extra,n-=c.extra,c.back+=c.extra}c.was=c.length,c.mode=eb;case eb:for(;Ab=c.distcode[m&(1<<c.distbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(0===(240&rb)){for(tb=qb,ub=rb,vb=sb;Ab=c.distcode[vb+((m&(1<<tb+ub)-1)>>tb)],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=tb+qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=tb,n-=tb,c.back+=tb}if(m>>>=qb,n-=qb,c.back+=qb,64&rb){a.msg="invalid distance code",c.mode=lb;break}c.offset=sb,c.extra=15&rb,c.mode=fb;case fb:if(c.extra){for(zb=c.extra;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.offset+=m&(1<<c.extra)-1,m>>>=c.extra,n-=c.extra,c.back+=c.extra}if(c.offset>c.dmax){a.msg="invalid distance too far back",c.mode=lb;break}c.mode=gb;case gb:if(0===j)break a;if(q=p-j,c.offset>q){if(q=c.offset-q,q>c.whave&&c.sane){a.msg="invalid distance too far back",c.mode=lb;break}q>c.wnext?(q-=c.wnext,ob=c.wsize-q):ob=c.wnext-q,q>c.length&&(q=c.length),pb=c.window}else pb=f,ob=h-c.offset,q=c.length;q>j&&(q=j),j-=q,c.length-=q;do f[h++]=pb[ob++];while(--q);0===c.length&&(c.mode=cb);break;case hb:if(0===j)break a;f[h++]=c.length,j--,c.mode=cb;break;case ib:if(c.wrap){for(;32>n;){if(0===i)break a;i--,m|=e[g++]<<n,n+=8}if(p-=j,a.total_out+=p,c.total+=p,p&&(a.adler=c.check=c.flags?t(c.check,f,p,h-p):s(c.check,f,p,h-p)),p=j,(c.flags?m:d(m))!==c.check){a.msg="incorrect data check",c.mode=lb;break}m=0,n=0}c.mode=jb;case jb:if(c.wrap&&c.flags){for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m!==(4294967295&c.total)){a.msg="incorrect length check",c.mode=lb;break}m=0,n=0}c.mode=kb;case kb:xb=D;break a;case lb:xb=G;break a;case mb:return H;case nb:default:return F}return a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,(c.wsize||p!==a.avail_out&&c.mode<lb&&(c.mode<ib||b!==z))&&l(a,a.output,a.next_out,p-a.avail_out)?(c.mode=mb,H):(o-=a.avail_in,p-=a.avail_out,a.total_in+=o,a.total_out+=p,c.total+=p,c.wrap&&p&&(a.adler=c.check=c.flags?t(c.check,f,p,a.next_out-p):s(c.check,f,p,a.next_out-p)),a.data_type=c.bits+(c.last?64:0)+(c.mode===V?128:0)+(c.mode===bb||c.mode===Y?256:0),(0===o&&0===p||b===z)&&xb===C&&(xb=I),xb)}function n(a){if(!a||!a.state)return F;var b=a.state;return b.window&&(b.window=null),a.state=null,C}function o(a,b){var c;return a&&a.state?(c=a.state,0===(2&c.wrap)?F:(c.head=b,b.done=!1,C)):F}var p,q,r=a("../utils/common"),s=a("./adler32"),t=a("./crc32"),u=a("./inffast"),v=a("./inftrees"),w=0,x=1,y=2,z=4,A=5,B=6,C=0,D=1,E=2,F=-2,G=-3,H=-4,I=-5,J=8,K=1,L=2,M=3,N=4,O=5,P=6,Q=7,R=8,S=9,T=10,U=11,V=12,W=13,X=14,Y=15,Z=16,$=17,_=18,ab=19,bb=20,cb=21,db=22,eb=23,fb=24,gb=25,hb=26,ib=27,jb=28,kb=29,lb=30,mb=31,nb=32,ob=852,pb=592,qb=15,rb=qb,sb=!0;c.inflateReset=g,c.inflateReset2=h,c.inflateResetKeep=f,c.inflateInit=j,c.inflateInit2=i,c.inflate=m,c.inflateEnd=n,c.inflateGetHeader=o,c.inflateInfo="pako inflate (from Nodeca project)"},{"../utils/common":27,"./adler32":29,"./crc32":31,"./inffast":34,"./inftrees":36}],36:[function(a,b){"use strict";var c=a("../utils/common"),d=15,e=852,f=592,g=0,h=1,i=2,j=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],k=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],l=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],m=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];b.exports=function(a,b,n,o,p,q,r,s){var t,u,v,w,x,y,z,A,B,C=s.bits,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=null,O=0,P=new c.Buf16(d+1),Q=new c.Buf16(d+1),R=null,S=0;for(D=0;d>=D;D++)P[D]=0;for(E=0;o>E;E++)P[b[n+E]]++;for(H=C,G=d;G>=1&&0===P[G];G--);if(H>G&&(H=G),0===G)return p[q++]=20971520,p[q++]=20971520,s.bits=1,0;for(F=1;G>F&&0===P[F];F++);for(F>H&&(H=F),K=1,D=1;d>=D;D++)if(K<<=1,K-=P[D],0>K)return-1;if(K>0&&(a===g||1!==G))return-1;for(Q[1]=0,D=1;d>D;D++)Q[D+1]=Q[D]+P[D];for(E=0;o>E;E++)0!==b[n+E]&&(r[Q[b[n+E]]++]=E);if(a===g?(N=R=r,y=19):a===h?(N=j,O-=257,R=k,S-=257,y=256):(N=l,R=m,y=-1),M=0,E=0,D=F,x=q,I=H,J=0,v=-1,L=1<<H,w=L-1,a===h&&L>e||a===i&&L>f)return 1;for(var T=0;;){T++,z=D-J,r[E]<y?(A=0,B=r[E]):r[E]>y?(A=R[S+r[E]],B=N[O+r[E]]):(A=96,B=0),t=1<<D-J,u=1<<I,F=u;do u-=t,p[x+(M>>J)+u]=z<<24|A<<16|B|0;while(0!==u);for(t=1<<D-1;M&t;)t>>=1;if(0!==t?(M&=t-1,M+=t):M=0,E++,0===--P[D]){if(D===G)break;D=b[n+r[E]]}if(D>H&&(M&w)!==v){for(0===J&&(J=H),x+=F,I=D-J,K=1<<I;G>I+J&&(K-=P[I+J],!(0>=K));)I++,K<<=1;if(L+=1<<I,a===h&&L>e||a===i&&L>f)return 1;v=M&w,p[v]=H<<24|I<<16|x-q|0}}return 0!==M&&(p[x+M]=D-J<<24|64<<16|0),s.bits=H,0}},{"../utils/common":27}],37:[function(a,b){"use strict";b.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],38:[function(a,b,c){"use strict";function d(a){for(var b=a.length;--b>=0;)a[b]=0}function e(a){return 256>a?gb[a]:gb[256+(a>>>7)]}function f(a,b){a.pending_buf[a.pending++]=255&b,a.pending_buf[a.pending++]=b>>>8&255}function g(a,b,c){a.bi_valid>V-c?(a.bi_buf|=b<<a.bi_valid&65535,f(a,a.bi_buf),a.bi_buf=b>>V-a.bi_valid,a.bi_valid+=c-V):(a.bi_buf|=b<<a.bi_valid&65535,a.bi_valid+=c)}function h(a,b,c){g(a,c[2*b],c[2*b+1])}function i(a,b){var c=0;do c|=1&a,a>>>=1,c<<=1;while(--b>0);return c>>>1}function j(a){16===a.bi_valid?(f(a,a.bi_buf),a.bi_buf=0,a.bi_valid=0):a.bi_valid>=8&&(a.pending_buf[a.pending++]=255&a.bi_buf,a.bi_buf>>=8,a.bi_valid-=8)}function k(a,b){var c,d,e,f,g,h,i=b.dyn_tree,j=b.max_code,k=b.stat_desc.static_tree,l=b.stat_desc.has_stree,m=b.stat_desc.extra_bits,n=b.stat_desc.extra_base,o=b.stat_desc.max_length,p=0;for(f=0;U>=f;f++)a.bl_count[f]=0;for(i[2*a.heap[a.heap_max]+1]=0,c=a.heap_max+1;T>c;c++)d=a.heap[c],f=i[2*i[2*d+1]+1]+1,f>o&&(f=o,p++),i[2*d+1]=f,d>j||(a.bl_count[f]++,g=0,d>=n&&(g=m[d-n]),h=i[2*d],a.opt_len+=h*(f+g),l&&(a.static_len+=h*(k[2*d+1]+g)));if(0!==p){do{for(f=o-1;0===a.bl_count[f];)f--;a.bl_count[f]--,a.bl_count[f+1]+=2,a.bl_count[o]--,p-=2}while(p>0);for(f=o;0!==f;f--)for(d=a.bl_count[f];0!==d;)e=a.heap[--c],e>j||(i[2*e+1]!==f&&(a.opt_len+=(f-i[2*e+1])*i[2*e],i[2*e+1]=f),d--)}}function l(a,b,c){var d,e,f=new Array(U+1),g=0;for(d=1;U>=d;d++)f[d]=g=g+c[d-1]<<1;for(e=0;b>=e;e++){var h=a[2*e+1];0!==h&&(a[2*e]=i(f[h]++,h))}}function m(){var a,b,c,d,e,f=new Array(U+1);for(c=0,d=0;O-1>d;d++)for(ib[d]=c,a=0;a<1<<_[d];a++)hb[c++]=d;for(hb[c-1]=d,e=0,d=0;16>d;d++)for(jb[d]=e,a=0;a<1<<ab[d];a++)gb[e++]=d;for(e>>=7;R>d;d++)for(jb[d]=e<<7,a=0;a<1<<ab[d]-7;a++)gb[256+e++]=d;for(b=0;U>=b;b++)f[b]=0;for(a=0;143>=a;)eb[2*a+1]=8,a++,f[8]++;for(;255>=a;)eb[2*a+1]=9,a++,f[9]++;for(;279>=a;)eb[2*a+1]=7,a++,f[7]++;for(;287>=a;)eb[2*a+1]=8,a++,f[8]++;for(l(eb,Q+1,f),a=0;R>a;a++)fb[2*a+1]=5,fb[2*a]=i(a,5);kb=new nb(eb,_,P+1,Q,U),lb=new nb(fb,ab,0,R,U),mb=new nb(new Array(0),bb,0,S,W)}function n(a){var b;for(b=0;Q>b;b++)a.dyn_ltree[2*b]=0;for(b=0;R>b;b++)a.dyn_dtree[2*b]=0;for(b=0;S>b;b++)a.bl_tree[2*b]=0;a.dyn_ltree[2*X]=1,a.opt_len=a.static_len=0,a.last_lit=a.matches=0}function o(a){a.bi_valid>8?f(a,a.bi_buf):a.bi_valid>0&&(a.pending_buf[a.pending++]=a.bi_buf),a.bi_buf=0,a.bi_valid=0}function p(a,b,c,d){o(a),d&&(f(a,c),f(a,~c)),E.arraySet(a.pending_buf,a.window,b,c,a.pending),a.pending+=c}function q(a,b,c,d){var e=2*b,f=2*c;return a[e]<a[f]||a[e]===a[f]&&d[b]<=d[c]}function r(a,b,c){for(var d=a.heap[c],e=c<<1;e<=a.heap_len&&(e<a.heap_len&&q(b,a.heap[e+1],a.heap[e],a.depth)&&e++,!q(b,d,a.heap[e],a.depth));)a.heap[c]=a.heap[e],c=e,e<<=1;a.heap[c]=d}function s(a,b,c){var d,f,i,j,k=0;if(0!==a.last_lit)do d=a.pending_buf[a.d_buf+2*k]<<8|a.pending_buf[a.d_buf+2*k+1],f=a.pending_buf[a.l_buf+k],k++,0===d?h(a,f,b):(i=hb[f],h(a,i+P+1,b),j=_[i],0!==j&&(f-=ib[i],g(a,f,j)),d--,i=e(d),h(a,i,c),j=ab[i],0!==j&&(d-=jb[i],g(a,d,j)));while(k<a.last_lit);h(a,X,b)}function t(a,b){var c,d,e,f=b.dyn_tree,g=b.stat_desc.static_tree,h=b.stat_desc.has_stree,i=b.stat_desc.elems,j=-1;for(a.heap_len=0,a.heap_max=T,c=0;i>c;c++)0!==f[2*c]?(a.heap[++a.heap_len]=j=c,a.depth[c]=0):f[2*c+1]=0;for(;a.heap_len<2;)e=a.heap[++a.heap_len]=2>j?++j:0,f[2*e]=1,a.depth[e]=0,a.opt_len--,h&&(a.static_len-=g[2*e+1]);for(b.max_code=j,c=a.heap_len>>1;c>=1;c--)r(a,f,c);e=i;do c=a.heap[1],a.heap[1]=a.heap[a.heap_len--],r(a,f,1),d=a.heap[1],a.heap[--a.heap_max]=c,a.heap[--a.heap_max]=d,f[2*e]=f[2*c]+f[2*d],a.depth[e]=(a.depth[c]>=a.depth[d]?a.depth[c]:a.depth[d])+1,f[2*c+1]=f[2*d+1]=e,a.heap[1]=e++,r(a,f,1);while(a.heap_len>=2);a.heap[--a.heap_max]=a.heap[1],k(a,b),l(f,j,a.bl_count)}function u(a,b,c){var d,e,f=-1,g=b[1],h=0,i=7,j=4;for(0===g&&(i=138,j=3),b[2*(c+1)+1]=65535,d=0;c>=d;d++)e=g,g=b[2*(d+1)+1],++h<i&&e===g||(j>h?a.bl_tree[2*e]+=h:0!==e?(e!==f&&a.bl_tree[2*e]++,a.bl_tree[2*Y]++):10>=h?a.bl_tree[2*Z]++:a.bl_tree[2*$]++,h=0,f=e,0===g?(i=138,j=3):e===g?(i=6,j=3):(i=7,j=4))}function v(a,b,c){var d,e,f=-1,i=b[1],j=0,k=7,l=4;for(0===i&&(k=138,l=3),d=0;c>=d;d++)if(e=i,i=b[2*(d+1)+1],!(++j<k&&e===i)){if(l>j){do h(a,e,a.bl_tree);while(0!==--j)}else 0!==e?(e!==f&&(h(a,e,a.bl_tree),j--),h(a,Y,a.bl_tree),g(a,j-3,2)):10>=j?(h(a,Z,a.bl_tree),g(a,j-3,3)):(h(a,$,a.bl_tree),g(a,j-11,7));j=0,f=e,0===i?(k=138,l=3):e===i?(k=6,l=3):(k=7,l=4)}}function w(a){var b;for(u(a,a.dyn_ltree,a.l_desc.max_code),u(a,a.dyn_dtree,a.d_desc.max_code),t(a,a.bl_desc),b=S-1;b>=3&&0===a.bl_tree[2*cb[b]+1];b--);return a.opt_len+=3*(b+1)+5+5+4,b}function x(a,b,c,d){var e;for(g(a,b-257,5),g(a,c-1,5),g(a,d-4,4),e=0;d>e;e++)g(a,a.bl_tree[2*cb[e]+1],3);v(a,a.dyn_ltree,b-1),v(a,a.dyn_dtree,c-1)}function y(a){var b,c=4093624447;for(b=0;31>=b;b++,c>>>=1)if(1&c&&0!==a.dyn_ltree[2*b])return G;if(0!==a.dyn_ltree[18]||0!==a.dyn_ltree[20]||0!==a.dyn_ltree[26])return H;for(b=32;P>b;b++)if(0!==a.dyn_ltree[2*b])return H;return G}function z(a){pb||(m(),pb=!0),a.l_desc=new ob(a.dyn_ltree,kb),a.d_desc=new ob(a.dyn_dtree,lb),a.bl_desc=new ob(a.bl_tree,mb),a.bi_buf=0,a.bi_valid=0,n(a)}function A(a,b,c,d){g(a,(J<<1)+(d?1:0),3),p(a,b,c,!0)}function B(a){g(a,K<<1,3),h(a,X,eb),j(a)}function C(a,b,c,d){var e,f,h=0;a.level>0?(a.strm.data_type===I&&(a.strm.data_type=y(a)),t(a,a.l_desc),t(a,a.d_desc),h=w(a),e=a.opt_len+3+7>>>3,f=a.static_len+3+7>>>3,e>=f&&(e=f)):e=f=c+5,e>=c+4&&-1!==b?A(a,b,c,d):a.strategy===F||f===e?(g(a,(K<<1)+(d?1:0),3),s(a,eb,fb)):(g(a,(L<<1)+(d?1:0),3),x(a,a.l_desc.max_code+1,a.d_desc.max_code+1,h+1),s(a,a.dyn_ltree,a.dyn_dtree)),n(a),d&&o(a)}function D(a,b,c){return a.pending_buf[a.d_buf+2*a.last_lit]=b>>>8&255,a.pending_buf[a.d_buf+2*a.last_lit+1]=255&b,a.pending_buf[a.l_buf+a.last_lit]=255&c,a.last_lit++,0===b?a.dyn_ltree[2*c]++:(a.matches++,b--,a.dyn_ltree[2*(hb[c]+P+1)]++,a.dyn_dtree[2*e(b)]++),a.last_lit===a.lit_bufsize-1}var E=a("../utils/common"),F=4,G=0,H=1,I=2,J=0,K=1,L=2,M=3,N=258,O=29,P=256,Q=P+1+O,R=30,S=19,T=2*Q+1,U=15,V=16,W=7,X=256,Y=16,Z=17,$=18,_=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],ab=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],bb=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],cb=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],db=512,eb=new Array(2*(Q+2));d(eb);var fb=new Array(2*R);d(fb);var gb=new Array(db);d(gb);var hb=new Array(N-M+1);d(hb);var ib=new Array(O);d(ib);var jb=new Array(R);d(jb);var kb,lb,mb,nb=function(a,b,c,d,e){this.static_tree=a,this.extra_bits=b,this.extra_base=c,this.elems=d,this.max_length=e,this.has_stree=a&&a.length},ob=function(a,b){this.dyn_tree=a,this.max_code=0,this.stat_desc=b},pb=!1;c._tr_init=z,c._tr_stored_block=A,c._tr_flush_block=C,c._tr_tally=D,c._tr_align=B},{"../utils/common":27}],39:[function(a,b){"use strict";function c(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}b.exports=c},{}]},{},[9])(9)});'use strict';if(tr.isHeadless){global.window={};}'use strict';if(tr.isHeadless){global.JSZip=global.window.JSZip;global.window=undefined;}'use strict';tr.exportTo('tr.e.importer.ddms',function(){var kPid=0;var kCategory='java';var kMethodLutEndMarker='\n*end\n';var kThreadsStart='\n*threads\n';var kMethodsStart='\n*methods\n';var kTraceMethodEnter=0x00;var kTraceMethodExit=0x01;var kTraceUnroll=0x02;var kTraceMethodActionMask=0x03;var kTraceHeaderLength=32;var kTraceMagicValue=0x574f4c53;var kTraceVersionSingleClock=2;var kTraceVersionDualClock=3;var kTraceRecordSizeSingleClock=10;var kTraceRecordSizeDualClock=14;function Reader(string_payload){this.position_=0;this.data_=JSZip.utils.transformTo('uint8array',string_payload);}
+Reader.prototype={__proto__:Object.prototype,uint8:function(){var result=this.data_[this.position_];this.position_+=1;return result;},uint16:function(){var result=0;result+=this.uint8();result+=this.uint8()<<8;return result;},uint32:function(){var result=0;result+=this.uint8();result+=this.uint8()<<8;result+=this.uint8()<<16;result+=this.uint8()<<24;return result;},uint64:function(){var low=this.uint32();var high=this.uint32();var low_str=('0000000'+low.toString(16)).substr(-8);var high_str=('0000000'+high.toString(16)).substr(-8);var result=high_str+low_str;return result;},seekTo:function(position){this.position_=position;},hasMore:function(){return this.position_<this.data_.length;}};function DdmsImporter(model,data){this.importPriority=3;this.model_=model;this.data_=data;}
+DdmsImporter.canImport=function(data){if(typeof(data)==='string'||data instanceof String){var header=data.slice(0,1000);return header.startsWith('*version\n')&&header.indexOf('\nvm=')>=0&&header.indexOf(kThreadsStart)>=0;}
+return false;};DdmsImporter.prototype={__proto__:tr.importer.Importer.prototype,get model(){return this.model_;},importEvents:function(isSecondaryImport){var divider=this.data_.indexOf(kMethodLutEndMarker)+
+kMethodLutEndMarker.length;this.metadata_=this.data_.slice(0,divider);this.methods_={};this.parseThreads();this.parseMethods();var traceReader=new Reader(this.data_.slice(divider));var magic=traceReader.uint32();if(magic!=kTraceMagicValue){throw Error('Failed to match magic value');}
+this.version_=traceReader.uint16();if(this.version_!=kTraceVersionDualClock){throw Error('Unknown version');}
+var dataOffest=traceReader.uint16();var startDateTime=traceReader.uint64();var recordSize=traceReader.uint16();traceReader.seekTo(dataOffest);while(traceReader.hasMore()){this.parseTraceEntry(traceReader);}},parseTraceEntry:function(reader){var tid=reader.uint16();var methodPacked=reader.uint32();var cpuSinceStart=reader.uint32();var wallClockSinceStart=reader.uint32();var method=methodPacked&~kTraceMethodActionMask;var action=methodPacked&kTraceMethodActionMask;var thread=this.getTid(tid);method=this.getMethodName(method);if(action==kTraceMethodEnter){thread.sliceGroup.beginSlice(kCategory,method,wallClockSinceStart,undefined,cpuSinceStart);}else if(thread.sliceGroup.openSliceCount){thread.sliceGroup.endSlice(wallClockSinceStart,cpuSinceStart);}},parseThreads:function(){var threads=this.metadata_.slice(this.metadata_.indexOf(kThreadsStart)+
+kThreadsStart.length);threads=threads.slice(0,threads.indexOf('\n*'));threads=threads.split('\n');threads.forEach(this.parseThread.bind(this));},parseThread:function(thread_line){var tid=thread_line.slice(0,thread_line.indexOf('\t'));var thread=this.getTid(parseInt(tid));thread.name=thread_line.slice(thread_line.indexOf('\t')+1);},getTid:function(tid){return this.model_.getOrCreateProcess(kPid).getOrCreateThread(tid);},parseMethods:function(){var methods=this.metadata_.slice(this.metadata_.indexOf(kMethodsStart)+
+kMethodsStart.length);methods=methods.slice(0,methods.indexOf('\n*'));methods=methods.split('\n');methods.forEach(this.parseMethod.bind(this));},parseMethod:function(method_line){var data=method_line.split('\t');var methodId=parseInt(data[0]);var methodName=data[1]+'.'+data[2]+data[3];this.addMethod(methodId,methodName);},addMethod:function(methodId,methodName){this.methods_[methodId]=methodName;},getMethodName:function(methodId){return this.methods_[methodId];}};tr.importer.Importer.register(DdmsImporter);return{DdmsImporter:DdmsImporter};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){function Parser(importer){this.importer=importer;this.model=importer.model;}
+Parser.prototype={__proto__:Object.prototype};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.mandatoryBaseClass=Parser;tr.b.decorateExtensionRegistry(Parser,options);return{Parser:Parser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function AndroidParser(importer){Parser.call(this,importer);importer.registerEventHandler('tracing_mark_write:android',AndroidParser.prototype.traceMarkWriteAndroidEvent.bind(this));importer.registerEventHandler('0:android',AndroidParser.prototype.traceMarkWriteAndroidEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
+function parseArgs(argsString){var args={};if(argsString){var argsArray=argsString.split(';');for(var i=0;i<argsArray.length;++i){var parts=argsArray[i].split('=');if(parts[0])
+args[parts.shift()]=parts.join('=');}}
+return args;}
+AndroidParser.prototype={__proto__:Parser.prototype,openAsyncSlice:function(thread,category,name,cookie,ts,args){var asyncSliceConstructor=tr.model.AsyncSlice.getConstructor(category,name);var slice=new asyncSliceConstructor(category,name,ColorScheme.getColorIdForGeneralPurposeString(name),ts,args);var key=category+':'+name+':'+cookie;slice.id=cookie;slice.startThread=thread;if(!this.openAsyncSlices){this.openAsyncSlices={};}
+this.openAsyncSlices[key]=slice;},closeAsyncSlice:function(thread,category,name,cookie,ts,args){if(!this.openAsyncSlices){return;}
+var key=category+':'+name+':'+cookie;var slice=this.openAsyncSlices[key];if(!slice){return;}
+for(var arg in args){if(slice.args[arg]!==undefined){this.model_.importWarning({type:'parse_error',message:'Both the S and F events of '+slice.title+' provided values for argument '+arg+'.'+' The value of the F event will be used.'});}
+slice.args[arg]=args[arg];}
+slice.endThread=thread;slice.duration=ts-slice.start;slice.startThread.asyncSliceGroup.push(slice);slice.subSlices=[new tr.model.AsyncSlice(slice.category,slice.title,slice.colorId,slice.start,slice.args,slice.duration)];delete this.openAsyncSlices[key];},traceMarkWriteAndroidEvent:function(eventName,cpuNumber,pid,ts,eventBase){var eventData=eventBase.details.split('|');switch(eventData[0]){case'B':var ppid=parseInt(eventData[1]);var title=eventData[2];var args=parseArgs(eventData[3]);var category=eventData[4];if(category===undefined)
+category='android';var thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);thread.name=eventBase.threadName;if(!thread.sliceGroup.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
+this.ppids_[pid]=ppid;thread.sliceGroup.beginSlice(category,title,ts,args);break;case'E':var ppid=this.ppids_[pid];if(ppid===undefined){break;}
+var thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);if(!thread.sliceGroup.openSliceCount){break;}
+var slice=thread.sliceGroup.endSlice(ts);var args=parseArgs(eventData[3]);for(var arg in args){if(slice.args[arg]!==undefined){this.model_.importWarning({type:'parse_error',message:'Both the B and E events of '+slice.title+' provided values for argument '+arg+'.'+' The value of the E event will be used.'});}
+slice.args[arg]=args[arg];}
+break;case'C':var ppid=parseInt(eventData[1]);var name=eventData[2];var value=parseInt(eventData[3]);var category=eventData[4];if(category===undefined)
+category='android';var ctr=this.model_.getOrCreateProcess(ppid).getOrCreateCounter(category,name);if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries(value,ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
+ctr.series.forEach(function(series){series.addCounterSample(ts,value);});break;case'S':var ppid=parseInt(eventData[1]);var name=eventData[2];var cookie=parseInt(eventData[3]);var args=parseArgs(eventData[4]);var category=eventData[5];if(category===undefined)
+category='android';var thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);thread.name=eventBase.threadName;this.ppids_[pid]=ppid;this.openAsyncSlice(thread,category,name,cookie,ts,args);break;case'F':var ppid=parseInt(eventData[1]);var name=eventData[2];var cookie=parseInt(eventData[3]);var args=parseArgs(eventData[4]);var category=eventData[5];if(category===undefined)
+category='android';var thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);thread.name=eventBase.threadName;this.ppids_[pid]=ppid;this.closeAsyncSlice(thread,category,name,cookie,ts,args);break;default:return false;}
+return true;}};Parser.register(AndroidParser);return{AndroidParser:AndroidParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;var binderTransRE=new RegExp('transaction=(\\d+) dest_node=(\\d+) '+'dest_proc=(\\d+) dest_thread=(\\d+) '+'reply=(\\d+) flags=(0x[0-9a-fA-F]+) '+'code=(0x[0-9a-fA-F]+)');var binderTransReceivedRE=/transaction=(\d+)/;function isBinderThread(name){return(name.indexOf('Binder')>-1);}
+var TF_ONE_WAY=0x01;var TF_ROOT_OBJECT=0x04;var TF_STATUS_CODE=0x08;var TF_ACCEPT_FDS=0x10;var NO_FLAGS=0;function binderFlagsToHuman(num){var flag=parseInt(num,16);var str='';if(flag&TF_ONE_WAY)
+str+='this is a one-way call: async, no return; ';if(flag&TF_ROOT_OBJECT)
+str+='contents are the components root object; ';if(flag&TF_STATUS_CODE)
+str+='contents are a 32-bit status code; ';if(flag&TF_ACCEPT_FDS)
+str+='allow replies with file descriptors; ';if(flag===NO_FLAGS)
+str+='No Flags Set';return str;}
+function isReplyToOrigin(calling,called){return(called.dest_proc===calling.calling_pid||called.dest_thread===calling.calling_pid);}
+function binderCodeToHuman(code){return'Java Layer Dependent';}
+function doInternalSlice(trans,slice,ts){if(slice.subSlices.length!==0){slice.subSlices[0].start=ts;return slice.subSlices[0];}
+var kthread=trans.calling_kthread.thread;var internal_slice=kthread.sliceGroup.pushCompleteSlice('binder',slice.title,ts,.001,0,0,slice.args);internal_slice.title=slice.title;internal_slice.id=slice.id;internal_slice.colorId=slice.colorId;slice.subSlices.push(internal_slice);return internal_slice;}
+function generateBinderArgsForSlice(trans,c_threadName){return{'Transaction Id':trans.transaction_key,'Destination Node':trans.dest_node,'Destination Process':trans.dest_proc,'Destination Thread':trans.dest_thread,'Destination Name':c_threadName,'Reply transaction?':trans.is_reply_transaction,'Flags':trans.flags+' '+
+binderFlagsToHuman(trans.flags),'Code':trans.code+' '+
+binderCodeToHuman(trans.code),'Calling PID':trans.calling_pid,'Calling tgid':trans.calling_kthread.thread.parent.pid};}
+function BinderTransaction(events,calling_pid,calling_ts,calling_kthread){this.transaction_key=parseInt(events[1]);this.dest_node=parseInt(events[2]);this.dest_proc=parseInt(events[3]);this.dest_thread=parseInt(events[4]);this.is_reply_transaction=parseInt(events[5])===1?true:false;this.expect_reply=((this.is_reply_transaction===false)&&(parseInt(events[6],16)&TF_ONE_WAY)===0);this.flags=events[6];this.code=events[7];this.calling_pid=calling_pid;this.calling_ts=calling_ts;this.calling_kthread=calling_kthread;}
+function BinderParser(importer){Parser.call(this,importer);importer.registerEventHandler('binder_locked',BinderParser.prototype.binderLocked.bind(this));importer.registerEventHandler('binder_unlock',BinderParser.prototype.binderUnlock.bind(this));importer.registerEventHandler('binder_lock',BinderParser.prototype.binderLock.bind(this));importer.registerEventHandler('binder_transaction',BinderParser.prototype.binderTransaction.bind(this));importer.registerEventHandler('binder_transaction_received',BinderParser.prototype.binderTransactionReceived.bind(this));this.model_=importer.model;this.kthreadlookup={};this.importer_=importer;this.transWaitingRecv={};this.syncTransWaitingCompletion={};this.recursiveSyncTransWaitingCompletion_ByPID={};this.receivedTransWaitingConversion={};}
+BinderParser.prototype={__proto__:Parser.prototype,binderLock:function(eventName,cpuNumber,pid,ts,eventBase){var tgid=parseInt(eventBase.tgid);this.doNameMappings(pid,tgid,eventName.threadName);var kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);kthread.binderAttemptLockTS=ts;kthread.binderOpenTsA=ts;return true;},binderLocked:function(eventName,cpuNumber,pid,ts,eventBase){var binder_thread=isBinderThread(eventBase.threadName);var tgid,name;var as_slice;var need_push=false;var kthread,rthread;tgid=parseInt(eventBase.tgid);name=eventBase.threadName;kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);this.doNameMappings(pid,tgid,name);rthread=kthread.thread;kthread.binderLockAquiredTS=ts;if(kthread.binderAttemptLockTS===undefined)
+return false;var args=this.generateArgsForSlice(tgid,pid,name,kthread);rthread.sliceGroup.pushCompleteSlice('binder','binder lock waiting',kthread.binderAttemptLockTS,ts-kthread.binderAttemptLockTS,0,0,args);kthread.binderAttemptLockTS=undefined;return true;},binderUnlock:function(eventName,cpuNumber,pid,ts,eventBase){var tgid=parseInt(eventBase.tgid);var kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);if(kthread.binderLockAquiredTS===undefined)
+return false;args=this.generateArgsForSlice(tgid,pid,eventBase.threadName,kthread);kthread.thread.sliceGroup.pushCompleteSlice('binder','binder lock held',kthread.binderLockAquiredTS,ts-kthread.binderLockAquiredTS,0,0,args);kthread.binderLockAquiredTS=undefined;return true;},binderTransaction:function(eventName,cpuNumber,pid,ts,eventBase){var event=binderTransRE.exec(eventBase.details);if(event===undefined)
+return false;var tgid=parseInt(eventBase.tgid);this.doNameMappings(pid,tgid,eventBase.threadName);var kthread;kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);var trans=new BinderTransaction(event,pid,ts,kthread);var args=generateBinderArgsForSlice(trans,eventBase.threadName);var prior_receive=this.getPriorReceiveOnPID(pid);if(prior_receive!==false){return this.modelPriorReceive(prior_receive,ts,pid,tgid,kthread,trans,args,event);}
+var recursive_trans=this.getRecursiveTransactionNeedingCompletion(pid);if(recursive_trans!==false)
+return this.modelRecursiveTransactions(recursive_trans,ts,pid,kthread,trans,args);var slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','',ts,.03,0,0,args);slice.colorId=ColorScheme.getColorIdForGeneralPurposeString(ts.toString());trans.slice=slice;if(trans.expect_reply)
+slice.title='binder transaction';else
+slice.title='binder transaction async';this.addTransactionWaitingForRecv(trans.transaction_key,trans);return true;},binderTransactionReceived:function(eventName,cpuNumber,pid,ts,eventBase){var event=binderTransReceivedRE.exec(eventBase.details);if(event===undefined)
+return false;var transactionkey=parseInt(event[1]);var tgid=parseInt(eventBase.tgid);var kthread;kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);var syncComplete=this.getSyncTransNeedsCompletion(transactionkey);if(syncComplete!==false){var sync_trans=syncComplete[0];var sync_slice=sync_trans.slice;var response_trans=syncComplete[1];var response_slice=response_trans.slice;sync_slice.duration=ts-sync_slice.start;var sync_internal=doInternalSlice(sync_trans,sync_slice,ts);var response_ts=response_slice.start+response_slice.duration;var response_internal=doInternalSlice(response_trans,response_slice,response_ts);if(response_slice.outFlowEvents.length===0||sync_slice.inFlowEvents.length===0){var flow=this.generateFlow(response_internal,sync_internal,response_trans,sync_trans);sync_slice.inFlowEvents.push(flow);response_slice.outFlowEvents.push(flow);this.model_.flowEvents.push(flow);}
+for(var i=1;i<sync_slice.inFlowEvents.length;i++){sync_slice.inFlowEvents[i].duration=ts-sync_slice.inFlowEvents[i].start;}
+return true;}
+var tr_for_recv=this.getTransactionWaitingForRecv(transactionkey);if(tr_for_recv!==false){if(!tr_for_recv.expect_reply){var args=generateBinderArgsForSlice(tr_for_recv,eventBase.threadName);var slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','binder Async recv',ts,.03,0,0,args);var fake_event=[0,0,0,0,0,0,0];var fake_trans=new BinderTransaction(fake_event,pid,ts,kthread);var flow=this.generateFlow(tr_for_recv.slice,slice,tr_for_recv,fake_trans);this.model_.flowEvents.push(flow);tr_for_recv.slice.title='binder transaction async';tr_for_recv.slice.duration=.03;return true;}
+tr_for_recv.slice.title='binder transaction';this.setCurrentReceiveOnPID(pid,[ts,tr_for_recv]);return true;}
+return false;},modelRecursiveTransactions:function(recursive_trans,ts,pid,kthread,trans,args){var recursive_slice=recursive_trans[1].slice;var orig_slice=recursive_trans[0].slice;recursive_slice.duration=ts-recursive_slice.start;trans.slice=recursive_slice;if(trans.is_reply_transaction){orig_slice.duration=ts-orig_slice.start;this.addSyncTransNeedingCompletion(trans.transaction_key,recursive_trans);if(isReplyToOrigin(recursive_trans[0],trans))
+this.removeRecursiveTransaction(pid);}else{var slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','',ts,.03,0,0,args);trans.slice=slice;this.addTransactionWaitingForRecv(trans.transaction_key,trans);}
+return true;},modelPriorReceive:function(prior_receive,ts,pid,tgid,kthread,trans,args,event){var callee_slice=prior_receive[1].slice;var callee_trans=prior_receive[1];var recv_ts=prior_receive[0];var slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','',recv_ts,ts-recv_ts,0,0,args);var flow=this.generateFlow(callee_slice,slice,callee_trans,trans);this.model_.flowEvents.push(flow);trans.slice=slice;if(trans.is_reply_transaction){slice.title='binder reply';this.addSyncTransNeedingCompletion(trans.transaction_key,[callee_trans,trans]);}else{slice.title='binder reply';var trans1=new BinderTransaction(event,pid,ts,kthread);slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','binder transaction',recv_ts,(ts-recv_ts),0,0,args);if(!trans.expect_reply){slice.title='binder transaction async';slice.duration=.03;}else{}
+trans1.slice=slice;this.addRecursiveSyncTransNeedingCompletion(pid,[callee_trans,trans]);this.addTransactionWaitingForRecv(trans.transaction_key,trans1);}
+return true;},getRecursiveTransactionNeedingCompletion:function(pid){if(this.recursiveSyncTransWaitingCompletion_ByPID[pid]===undefined)
+return false;var len=this.recursiveSyncTransWaitingCompletion_ByPID[pid].length;if(len===0)
+return false;return this.recursiveSyncTransWaitingCompletion_ByPID[pid][len-1];},addRecursiveSyncTransNeedingCompletion:function(pid,tuple){if(this.recursiveSyncTransWaitingCompletion_ByPID[pid]===undefined)
+this.recursiveSyncTransWaitingCompletion_ByPID[pid]=[];this.recursiveSyncTransWaitingCompletion_ByPID[pid].push(tuple);},removeRecursiveTransaction:function(pid){var len=this.recursiveSyncTransWaitingCompletion_ByPID[pid].length;if(len===0){delete this.recursiveSyncTransWaitingCompletion_ByPID[pid];return;}
+this.recursiveSyncTransWaitingCompletion_ByPID[pid].splice(len-1,1);},setCurrentReceiveOnPID:function(pid,tuple){if(this.receivedTransWaitingConversion[pid]===undefined){this.receivedTransWaitingConversion[pid]=[];}
+this.receivedTransWaitingConversion[pid].push(tuple);},getPriorReceiveOnPID:function(pid){if(this.receivedTransWaitingConversion[pid]===undefined)
+return false;var len=this.receivedTransWaitingConversion[pid].length;if(len===0)
+return false;return this.receivedTransWaitingConversion[pid].splice(len-1,1)[0];},addSyncTransNeedingCompletion:function(transactionkey,tuple){var dict=this.syncTransWaitingCompletion;dict[transactionkey]=tuple;},getSyncTransNeedsCompletion:function(transactionkey){var ret=this.syncTransWaitingCompletion[transactionkey];if(ret===undefined)
+return false;delete this.syncTransWaitingCompletion[transactionkey];return ret;},getTransactionWaitingForRecv:function(transactionkey){var ret=this.transWaitingRecv[transactionkey];if(ret===undefined)
+return false;delete this.transWaitingRecv[transactionkey];return ret;},addTransactionWaitingForRecv:function(transactionkey,transaction){this.transWaitingRecv[transactionkey]=transaction;},generateFlow:function(from,to,from_trans,to_trans){var title='Transaction from : '+
+this.pid2name(from_trans.calling_pid)+' From PID: '+from_trans.calling_pid+' to pid: '+
+to_trans.calling_pid+' Thread Name: '+this.pid2name(to_trans.calling_pid);var ts=from.start;var flow=new tr.model.FlowEvent('binder','binder',title,1,ts,[]);flow.startSlice=from;flow.endSlice=to;flow.start=from.start;flow.duration=to.start-ts;from.outFlowEvents.push(flow);to.inFlowEvents.push(flow);return flow;},generateArgsForSlice:function(tgid,pid,name,kthread){return{'Thread Name':name,'pid':pid,'gid':tgid};},pid2name:function(pid){return this.kthreadlookup[pid];},doNameMappings:function(pid,tgid,name){this.registerPidName(pid,name);this.registerPidName(tgid,name);},registerPidName:function(pid,name){if(this.pid2name(pid)===undefined)
+this.kthreadlookup[pid]=name;}};Parser.register(BinderParser);return{BinderParser:BinderParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function BusParser(importer){Parser.call(this,importer);importer.registerEventHandler('memory_bus_usage',BusParser.prototype.traceMarkWriteBusEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
+BusParser.prototype={__proto__:Parser.prototype,traceMarkWriteBusEvent:function(eventName,cpuNumber,pid,ts,eventBase,threadName){var re=new RegExp('bus=(\\S+) rw_bytes=(\\d+) r_bytes=(\\d+) '+'w_bytes=(\\d+) cycles=(\\d+) ns=(\\d+)');var event=re.exec(eventBase.details);var name=event[1];var rw_bytes=parseInt(event[2]);var r_bytes=parseInt(event[3]);var w_bytes=parseInt(event[4]);var cycles=parseInt(event[5]);var ns=parseInt(event[6]);var r_bw=r_bytes*1000000000/ns;r_bw/=1024*1024;var w_bw=w_bytes*1000000000/ns;w_bw/=1024*1024;var ctr=this.model_.kernel.getOrCreateCounter(null,'bus '+name+' read');if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries('value',ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
+ctr.series.forEach(function(series){series.addCounterSample(ts,r_bw);});ctr=this.model_.kernel.getOrCreateCounter(null,'bus '+name+' write');if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries('value',ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
+ctr.series.forEach(function(series){series.addCounterSample(ts,r_bw);});return true;}};Parser.register(BusParser);return{BusParser:BusParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function ClockParser(importer){Parser.call(this,importer);importer.registerEventHandler('clock_set_rate',ClockParser.prototype.traceMarkWriteClockEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
+ClockParser.prototype={__proto__:Parser.prototype,traceMarkWriteClockEvent:function(eventName,cpuNumber,pid,ts,eventBase,threadName){var event=/(\S+) state=(\d+) cpu_id=(\d+)/.exec(eventBase.details);var name=event[1];var rate=parseInt(event[2]);var ctr=this.model_.kernel.getOrCreateCounter(null,name);if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries('value',ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
+ctr.series.forEach(function(series){series.addCounterSample(ts,rate);});return true;}};Parser.register(ClockParser);return{ClockParser:ClockParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function CpufreqParser(importer){Parser.call(this,importer);importer.registerEventHandler('cpufreq_interactive_up',CpufreqParser.prototype.cpufreqUpDownEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_down',CpufreqParser.prototype.cpufreqUpDownEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_already',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_notyet',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_setspeed',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_target',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_boost',CpufreqParser.prototype.cpufreqBoostUnboostEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_unboost',CpufreqParser.prototype.cpufreqBoostUnboostEvent.bind(this));}
+function splitData(input){var data={};var args=input.split(/\s+/);var len=args.length;for(var i=0;i<len;i++){var item=args[i].split('=');data[item[0]]=parseInt(item[1]);}
+return data;}
+CpufreqParser.prototype={__proto__:Parser.prototype,cpufreqSlice:function(ts,eventName,cpu,args){var kthread=this.importer.getOrCreatePseudoThread('cpufreq');kthread.openSlice=eventName;var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},cpufreqBoostSlice:function(ts,eventName,args){var kthread=this.importer.getOrCreatePseudoThread('cpufreq_boost');kthread.openSlice=eventName;var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},cpufreqUpDownEvent:function(eventName,cpuNumber,pid,ts,eventBase){var data=splitData(eventBase.details);this.cpufreqSlice(ts,eventName,data.cpu,data);return true;},cpufreqTargetEvent:function(eventName,cpuNumber,pid,ts,eventBase){var data=splitData(eventBase.details);this.cpufreqSlice(ts,eventName,data.cpu,data);return true;},cpufreqBoostUnboostEvent:function(eventName,cpuNumber,pid,ts,eventBase){this.cpufreqBoostSlice(ts,eventName,{type:eventBase.details});return true;}};Parser.register(CpufreqParser);return{CpufreqParser:CpufreqParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function DiskParser(importer){Parser.call(this,importer);importer.registerEventHandler('f2fs_write_begin',DiskParser.prototype.f2fsWriteBeginEvent.bind(this));importer.registerEventHandler('f2fs_write_end',DiskParser.prototype.f2fsWriteEndEvent.bind(this));importer.registerEventHandler('f2fs_sync_file_enter',DiskParser.prototype.f2fsSyncFileEnterEvent.bind(this));importer.registerEventHandler('f2fs_sync_file_exit',DiskParser.prototype.f2fsSyncFileExitEvent.bind(this));importer.registerEventHandler('ext4_sync_file_enter',DiskParser.prototype.ext4SyncFileEnterEvent.bind(this));importer.registerEventHandler('ext4_sync_file_exit',DiskParser.prototype.ext4SyncFileExitEvent.bind(this));importer.registerEventHandler('ext4_da_write_begin',DiskParser.prototype.ext4WriteBeginEvent.bind(this));importer.registerEventHandler('ext4_da_write_end',DiskParser.prototype.ext4WriteEndEvent.bind(this));importer.registerEventHandler('block_rq_issue',DiskParser.prototype.blockRqIssueEvent.bind(this));importer.registerEventHandler('block_rq_complete',DiskParser.prototype.blockRqCompleteEvent.bind(this));}
+DiskParser.prototype={__proto__:Parser.prototype,openAsyncSlice:function(ts,category,threadName,pid,key,name){var kthread=this.importer.getOrCreateKernelThread(category+':'+threadName,pid);var asyncSliceConstructor=tr.model.AsyncSlice.getConstructor(category,name);var slice=new asyncSliceConstructor(category,name,ColorScheme.getColorIdForGeneralPurposeString(name),ts);slice.startThread=kthread.thread;if(!kthread.openAsyncSlices){kthread.openAsyncSlices={};}
+kthread.openAsyncSlices[key]=slice;},closeAsyncSlice:function(ts,category,threadName,pid,key,args){var kthread=this.importer.getOrCreateKernelThread(category+':'+threadName,pid);if(kthread.openAsyncSlices){var slice=kthread.openAsyncSlices[key];if(slice){slice.duration=ts-slice.start;slice.args=args;slice.endThread=kthread.thread;slice.subSlices=[new tr.model.AsyncSlice(category,slice.title,slice.colorId,slice.start,slice.args,slice.duration)];kthread.thread.asyncSliceGroup.push(slice);delete kthread.openAsyncSlices[key];}}},f2fsWriteBeginEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev = \((\d+,\d+)\), ino = (\d+), pos = (\d+), len = (\d+), flags = (\d+)/.exec(eventBase.details);if(!event)
+return false;var device=event[1];var inode=parseInt(event[2]);var pos=parseInt(event[3]);var len=parseInt(event[4]);var key=device+'-'+inode+'-'+pos+'-'+len;this.openAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,'f2fs_write');return true;},f2fsWriteEndEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev = \((\d+,\d+)\), ino = (\d+), pos = (\d+), len = (\d+), copied = (\d+)/.exec(eventBase.details);if(!event)
+return false;var device=event[1];var inode=parseInt(event[2]);var pos=parseInt(event[3]);var len=parseInt(event[4]);var error=parseInt(event[5])!==len;var key=device+'-'+inode+'-'+pos+'-'+len;this.closeAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,{device:device,inode:inode,error:error});return true;},ext4WriteBeginEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev (\d+,\d+) ino (\d+) pos (\d+) len (\d+) flags (\d+)/.exec(eventBase.details);if(!event)
+return false;var device=event[1];var inode=parseInt(event[2]);var pos=parseInt(event[3]);var len=parseInt(event[4]);var key=device+'-'+inode+'-'+pos+'-'+len;this.openAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,'ext4_write');return true;},ext4WriteEndEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev (\d+,\d+) ino (\d+) pos (\d+) len (\d+) copied (\d+)/.exec(eventBase.details);if(!event)
+return false;var device=event[1];var inode=parseInt(event[2]);var pos=parseInt(event[3]);var len=parseInt(event[4]);var error=parseInt(event[5])!==len;var key=device+'-'+inode+'-'+pos+'-'+len;this.closeAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,{device:device,inode:inode,error:error});return true;},f2fsSyncFileEnterEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=new RegExp('dev = \\((\\d+,\\d+)\\), ino = (\\d+), pino = (\\d+), i_mode = (\\S+), '+'i_size = (\\d+), i_nlink = (\\d+), i_blocks = (\\d+), i_advise = (\\d+)').exec(eventBase.details);if(!event)
+return false;var device=event[1];var inode=parseInt(event[2]);var key=device+'-'+inode;this.openAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,'fsync');return true;},f2fsSyncFileExitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=new RegExp('dev = \\((\\d+,\\d+)\\), ino = (\\d+), checkpoint is (\\S+), '+'datasync = (\\d+), ret = (\\d+)').exec(eventBase.details.replace('not needed','not_needed'));if(!event)
+return false;var device=event[1];var inode=parseInt(event[2]);var error=parseInt(event[5]);var key=device+'-'+inode;this.closeAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,{device:device,inode:inode,error:error});return true;},ext4SyncFileEnterEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev (\d+,\d+) ino (\d+) parent (\d+) datasync (\d+)/.exec(eventBase.details);if(!event)
+return false;var device=event[1];var inode=parseInt(event[2]);var datasync=event[4]==1;var key=device+'-'+inode;var action=datasync?'fdatasync':'fsync';this.openAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,action);return true;},ext4SyncFileExitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev (\d+,\d+) ino (\d+) ret (\d+)/.exec(eventBase.details);if(!event)
+return false;var device=event[1];var inode=parseInt(event[2]);var error=parseInt(event[3]);var key=device+'-'+inode;this.closeAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,{device:device,inode:inode,error:error});return true;},blockRqIssueEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=new RegExp('(\\d+,\\d+) (F)?([DWRN])(F)?(A)?(S)?(M)? '+'\\d+ \\(.*\\) (\\d+) \\+ (\\d+) \\[.*\\]').exec(eventBase.details);if(!event)
+return false;var action;switch(event[3]){case'D':action='discard';break;case'W':action='write';break;case'R':action='read';break;case'N':action='none';break;default:action='unknown';break;}
+if(event[2]){action+=' flush';}
+if(event[4]=='F'){action+=' fua';}
+if(event[5]=='A'){action+=' ahead';}
+if(event[6]=='S'){action+=' sync';}
+if(event[7]=='M'){action+=' meta';}
+var device=event[1];var sector=parseInt(event[8]);var numSectors=parseInt(event[9]);var key=device+'-'+sector+'-'+numSectors;this.openAsyncSlice(ts,'block',eventBase.threadName,eventBase.pid,key,action);return true;},blockRqCompleteEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=new RegExp('(\\d+,\\d+) (F)?([DWRN])(F)?(A)?(S)?(M)? '+'\\(.*\\) (\\d+) \\+ (\\d+) \\[(.*)\\]').exec(eventBase.details);if(!event)
+return false;var device=event[1];var sector=parseInt(event[8]);var numSectors=parseInt(event[9]);var error=parseInt(event[10]);var key=device+'-'+sector+'-'+numSectors;this.closeAsyncSlice(ts,'block',eventBase.threadName,eventBase.pid,key,{device:device,sector:sector,numSectors:numSectors,error:error});return true;}};Parser.register(DiskParser);return{DiskParser:DiskParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function DrmParser(importer){Parser.call(this,importer);importer.registerEventHandler('drm_vblank_event',DrmParser.prototype.vblankEvent.bind(this));}
+DrmParser.prototype={__proto__:Parser.prototype,drmVblankSlice:function(ts,eventName,args){var kthread=this.importer.getOrCreatePseudoThread('drm_vblank');kthread.openSlice=eventName;var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},vblankEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/crtc=(\d+), seq=(\d+)/.exec(eventBase.details);if(!event)
+return false;var crtc=parseInt(event[1]);var seq=parseInt(event[2]);this.drmVblankSlice(ts,'vblank:'+crtc,{crtc:crtc,seq:seq});return true;}};Parser.register(DrmParser);return{DrmParser:DrmParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function ExynosParser(importer){Parser.call(this,importer);importer.registerEventHandler('exynos_busfreq_target_int',ExynosParser.prototype.busfreqTargetIntEvent.bind(this));importer.registerEventHandler('exynos_busfreq_target_mif',ExynosParser.prototype.busfreqTargetMifEvent.bind(this));importer.registerEventHandler('exynos_page_flip_state',ExynosParser.prototype.pageFlipStateEvent.bind(this));}
+ExynosParser.prototype={__proto__:Parser.prototype,exynosBusfreqSample:function(name,ts,frequency){var targetCpu=this.importer.getOrCreateCpu(0);var counter=targetCpu.getOrCreateCounter('',name);if(counter.numSeries===0){counter.addSeries(new tr.model.CounterSeries('frequency',ColorScheme.getColorIdForGeneralPurposeString(counter.name+'.'+'frequency')));}
+counter.series.forEach(function(series){series.addCounterSample(ts,frequency);});},busfreqTargetIntEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/frequency=(\d+)/.exec(eventBase.details);if(!event)
+return false;this.exynosBusfreqSample('INT Frequency',ts,parseInt(event[1]));return true;},busfreqTargetMifEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/frequency=(\d+)/.exec(eventBase.details);if(!event)
+return false;this.exynosBusfreqSample('MIF Frequency',ts,parseInt(event[1]));return true;},exynosPageFlipStateOpenSlice:function(ts,pipe,fb,state){var kthread=this.importer.getOrCreatePseudoThread('exynos_flip_state (pipe:'+pipe+', fb:'+fb+')');kthread.openSliceTS=ts;kthread.openSlice=state;},exynosPageFlipStateCloseSlice:function(ts,pipe,fb,args){var kthread=this.importer.getOrCreatePseudoThread('exynos_flip_state (pipe:'+pipe+', fb:'+fb+')');if(kthread.openSlice){var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),kthread.openSliceTS,args,ts-kthread.openSliceTS);kthread.thread.sliceGroup.pushSlice(slice);}
+kthread.openSlice=undefined;},pageFlipStateEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/pipe=(\d+), fb=(\d+), state=(.*)/.exec(eventBase.details);if(!event)
+return false;var pipe=parseInt(event[1]);var fb=parseInt(event[2]);var state=event[3];this.exynosPageFlipStateCloseSlice(ts,pipe,fb,{pipe:pipe,fb:fb});if(state!=='flipped')
+this.exynosPageFlipStateOpenSlice(ts,pipe,fb,state);return true;}};Parser.register(ExynosParser);return{ExynosParser:ExynosParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var Parser=tr.e.importer.linux_perf.Parser;function GestureParser(importer){Parser.call(this,importer);importer.registerEventHandler('tracing_mark_write:log',GestureParser.prototype.logEvent.bind(this));importer.registerEventHandler('tracing_mark_write:SyncInterpret',GestureParser.prototype.syncEvent.bind(this));importer.registerEventHandler('tracing_mark_write:HandleTimer',GestureParser.prototype.timerEvent.bind(this));}
+GestureParser.prototype={__proto__:Parser.prototype,gestureOpenSlice:function(title,ts,opt_args){var thread=this.importer.getOrCreatePseudoThread('gesture').thread;thread.sliceGroup.beginSlice('touchpad_gesture',title,ts,opt_args);},gestureCloseSlice:function(title,ts){var thread=this.importer.getOrCreatePseudoThread('gesture').thread;if(thread.sliceGroup.openSliceCount){var slice=thread.sliceGroup.mostRecentlyOpenedPartialSlice;if(slice.title!=title){this.importer.model.importWarning({type:'title_match_error',message:'Titles do not match. Title is '+
+slice.title+' in openSlice, and is '+
+title+' in endSlice'});}else{thread.sliceGroup.endSlice(ts);}}},logEvent:function(eventName,cpuNumber,pid,ts,eventBase){var innerEvent=/^\s*(\w+):\s*(\w+)$/.exec(eventBase.details);switch(innerEvent[1]){case'start':this.gestureOpenSlice('GestureLog',ts,{name:innerEvent[2]});break;case'end':this.gestureCloseSlice('GestureLog',ts);}
+return true;},syncEvent:function(eventName,cpuNumber,pid,ts,eventBase){var innerEvent=/^\s*(\w+):\s*(\w+)$/.exec(eventBase.details);switch(innerEvent[1]){case'start':this.gestureOpenSlice('SyncInterpret',ts,{interpreter:innerEvent[2]});break;case'end':this.gestureCloseSlice('SyncInterpret',ts);}
+return true;},timerEvent:function(eventName,cpuNumber,pid,ts,eventBase){var innerEvent=/^\s*(\w+):\s*(\w+)$/.exec(eventBase.details);switch(innerEvent[1]){case'start':this.gestureOpenSlice('HandleTimer',ts,{interpreter:innerEvent[2]});break;case'end':this.gestureCloseSlice('HandleTimer',ts);}
+return true;}};Parser.register(GestureParser);return{GestureParser:GestureParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function I915Parser(importer){Parser.call(this,importer);importer.registerEventHandler('i915_gem_object_create',I915Parser.prototype.gemObjectCreateEvent.bind(this));importer.registerEventHandler('i915_gem_object_bind',I915Parser.prototype.gemObjectBindEvent.bind(this));importer.registerEventHandler('i915_gem_object_unbind',I915Parser.prototype.gemObjectBindEvent.bind(this));importer.registerEventHandler('i915_gem_object_change_domain',I915Parser.prototype.gemObjectChangeDomainEvent.bind(this));importer.registerEventHandler('i915_gem_object_pread',I915Parser.prototype.gemObjectPreadWriteEvent.bind(this));importer.registerEventHandler('i915_gem_object_pwrite',I915Parser.prototype.gemObjectPreadWriteEvent.bind(this));importer.registerEventHandler('i915_gem_object_fault',I915Parser.prototype.gemObjectFaultEvent.bind(this));importer.registerEventHandler('i915_gem_object_clflush',I915Parser.prototype.gemObjectDestroyEvent.bind(this));importer.registerEventHandler('i915_gem_object_destroy',I915Parser.prototype.gemObjectDestroyEvent.bind(this));importer.registerEventHandler('i915_gem_ring_dispatch',I915Parser.prototype.gemRingDispatchEvent.bind(this));importer.registerEventHandler('i915_gem_ring_flush',I915Parser.prototype.gemRingFlushEvent.bind(this));importer.registerEventHandler('i915_gem_request',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_add',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_complete',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_retire',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_wait_begin',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_wait_end',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_ring_wait_begin',I915Parser.prototype.gemRingWaitEvent.bind(this));importer.registerEventHandler('i915_gem_ring_wait_end',I915Parser.prototype.gemRingWaitEvent.bind(this));importer.registerEventHandler('i915_reg_rw',I915Parser.prototype.regRWEvent.bind(this));importer.registerEventHandler('i915_flip_request',I915Parser.prototype.flipEvent.bind(this));importer.registerEventHandler('i915_flip_complete',I915Parser.prototype.flipEvent.bind(this));importer.registerEventHandler('intel_gpu_freq_change',I915Parser.prototype.gpuFrequency.bind(this));}
+I915Parser.prototype={__proto__:Parser.prototype,i915FlipOpenSlice:function(ts,obj,plane){var kthread=this.importer.getOrCreatePseudoThread('i915_flip');kthread.openSliceTS=ts;kthread.openSlice='flip:'+obj+'/'+plane;},i915FlipCloseSlice:function(ts,args){var kthread=this.importer.getOrCreatePseudoThread('i915_flip');if(kthread.openSlice){var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),kthread.openSliceTS,args,ts-kthread.openSliceTS);kthread.thread.sliceGroup.pushSlice(slice);}
+kthread.openSlice=undefined;},i915GemObjectSlice:function(ts,eventName,obj,args){var kthread=this.importer.getOrCreatePseudoThread('i915_gem');kthread.openSlice=eventName+':'+obj;var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},i915GemRingSlice:function(ts,eventName,dev,ring,args){var kthread=this.importer.getOrCreatePseudoThread('i915_gem_ring');kthread.openSlice=eventName+':'+dev+'.'+ring;var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},i915RegSlice:function(ts,eventName,reg,args){var kthread=this.importer.getOrCreatePseudoThread('i915_reg');kthread.openSlice=eventName+':'+reg;var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},i915FreqChangeSlice:function(ts,eventName,args){var kthread=this.importer.getOrCreatePseudoThread('i915_gpu_freq');kthread.openSlice=eventName;var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},gemObjectCreateEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/obj=(\w+), size=(\d+)/.exec(eventBase.details);if(!event)
+return false;var obj=event[1];var size=parseInt(event[2]);this.i915GemObjectSlice(ts,eventName,obj,{obj:obj,size:size});return true;},gemObjectBindEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/obj=(\w+), offset=(\w+), size=(\d+)/.exec(eventBase.details);if(!event)
+return false;var obj=event[1];var offset=event[2];var size=parseInt(event[3]);this.i915ObjectGemSlice(ts,eventName+':'+obj,{obj:obj,offset:offset,size:size});return true;},gemObjectChangeDomainEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/obj=(\w+), read=(\w+=>\w+), write=(\w+=>\w+)/.exec(eventBase.details);if(!event)
+return false;var obj=event[1];var read=event[2];var write=event[3];this.i915GemObjectSlice(ts,eventName,obj,{obj:obj,read:read,write:write});return true;},gemObjectPreadWriteEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/obj=(\w+), offset=(\d+), len=(\d+)/.exec(eventBase.details);if(!event)
+return false;var obj=event[1];var offset=parseInt(event[2]);var len=parseInt(event[3]);this.i915GemObjectSlice(ts,eventName,obj,{obj:obj,offset:offset,len:len});return true;},gemObjectFaultEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/obj=(\w+), (\w+) index=(\d+)/.exec(eventBase.details);if(!event)
+return false;var obj=event[1];var type=event[2];var index=parseInt(event[3]);this.i915GemObjectSlice(ts,eventName,obj,{obj:obj,type:type,index:index});return true;},gemObjectDestroyEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/obj=(\w+)/.exec(eventBase.details);if(!event)
+return false;var obj=event[1];this.i915GemObjectSlice(ts,eventName,obj,{obj:obj});return true;},gemRingDispatchEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev=(\d+), ring=(\d+), seqno=(\d+)/.exec(eventBase.details);if(!event)
+return false;var dev=parseInt(event[1]);var ring=parseInt(event[2]);var seqno=parseInt(event[3]);this.i915GemRingSlice(ts,eventName,dev,ring,{dev:dev,ring:ring,seqno:seqno});return true;},gemRingFlushEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev=(\d+), ring=(\w+), invalidate=(\w+), flush=(\w+)/.exec(eventBase.details);if(!event)
+return false;var dev=parseInt(event[1]);var ring=parseInt(event[2]);var invalidate=event[3];var flush=event[4];this.i915GemRingSlice(ts,eventName,dev,ring,{dev:dev,ring:ring,invalidate:invalidate,flush:flush});return true;},gemRequestEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev=(\d+), ring=(\d+), seqno=(\d+)/.exec(eventBase.details);if(!event)
+return false;var dev=parseInt(event[1]);var ring=parseInt(event[2]);var seqno=parseInt(event[3]);this.i915GemRingSlice(ts,eventName,dev,ring,{dev:dev,ring:ring,seqno:seqno});return true;},gemRingWaitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev=(\d+), ring=(\d+)/.exec(eventBase.details);if(!event)
+return false;var dev=parseInt(event[1]);var ring=parseInt(event[2]);this.i915GemRingSlice(ts,eventName,dev,ring,{dev:dev,ring:ring});return true;},regRWEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/(\w+) reg=(\w+), len=(\d+), val=(\(\w+, \w+\))/.exec(eventBase.details);if(!event)
+return false;var rw=event[1];var reg=event[2];var len=event[3];var data=event[3];this.i915RegSlice(ts,rw,reg,{rw:rw,reg:reg,len:len,data:data});return true;},flipEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/plane=(\d+), obj=(\w+)/.exec(eventBase.details);if(!event)
+return false;var plane=parseInt(event[1]);var obj=event[2];if(eventName=='i915_flip_request')
+this.i915FlipOpenSlice(ts,obj,plane);else
+this.i915FlipCloseSlice(ts,{obj:obj,plane:plane});return true;},gpuFrequency:function(eventName,cpuNumver,pid,ts,eventBase){var event=/new_freq=(\d+)/.exec(eventBase.details);if(!event)
+return false;var freq=parseInt(event[1]);this.i915FreqChangeSlice(ts,eventName,{freq:freq});return true;}};Parser.register(I915Parser);return{I915Parser:I915Parser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function IrqParser(importer){Parser.call(this,importer);importer.registerEventHandler('irq_handler_entry',IrqParser.prototype.irqHandlerEntryEvent.bind(this));importer.registerEventHandler('irq_handler_exit',IrqParser.prototype.irqHandlerExitEvent.bind(this));importer.registerEventHandler('softirq_raise',IrqParser.prototype.softirqRaiseEvent.bind(this));importer.registerEventHandler('softirq_entry',IrqParser.prototype.softirqEntryEvent.bind(this));importer.registerEventHandler('softirq_exit',IrqParser.prototype.softirqExitEvent.bind(this));importer.registerEventHandler('ipi_entry',IrqParser.prototype.ipiEntryEvent.bind(this));importer.registerEventHandler('ipi_exit',IrqParser.prototype.ipiExitEvent.bind(this));}
+var irqHandlerEntryRE=/irq=(\d+) name=(.+)/;var irqHandlerExitRE=/irq=(\d+) ret=(.+)/;var softirqRE=/vec=(\d+) \[action=(.+)\]/;var ipiHandlerExitRE=/\((.+)\)/;IrqParser.prototype={__proto__:Parser.prototype,irqHandlerEntryEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=irqHandlerEntryRE.exec(eventBase.details);if(!event)
+return false;var irq=parseInt(event[1]);var name=event[2];var thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);thread.lastEntryTs=ts;thread.irqName=name;return true;},irqHandlerExitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=irqHandlerExitRE.exec(eventBase.details);if(!event)
+return false;var irq=parseInt(event[1]);var ret=event[2];var thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);if(thread.lastEntryTs!==undefined){var duration=ts-thread.lastEntryTs;var slice=new tr.model.Slice('','IRQ ('+thread.irqName+')',ColorScheme.getColorIdForGeneralPurposeString(event[1]),thread.lastEntryTs,{ret:ret},duration);thread.thread.sliceGroup.pushSlice(slice);}
+thread.lastEntryTs=undefined;thread.irqName=undefined;return true;},softirqRaiseEvent:function(eventName,cpuNumber,pid,ts,eventBase){return true;},softirqEntryEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=softirqRE.exec(eventBase.details);if(!event)
+return false;var action=event[2];var thread=this.importer.getOrCreatePseudoThread('softirq cpu '+cpuNumber);thread.lastEntryTs=ts;return true;},softirqExitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=softirqRE.exec(eventBase.details);if(!event)
+return false;var vec=parseInt(event[1]);var action=event[2];var thread=this.importer.getOrCreatePseudoThread('softirq cpu '+cpuNumber);if(thread.lastEntryTs!==undefined){var duration=ts-thread.lastEntryTs;var slice=new tr.model.Slice('',action,ColorScheme.getColorIdForGeneralPurposeString(event[1]),thread.lastEntryTs,{vec:vec},duration);thread.thread.sliceGroup.pushSlice(slice);}
+thread.lastEntryTs=undefined;return true;},ipiEntryEvent:function(eventName,cpuNumber,pid,ts,eventBase){var thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);thread.lastEntryTs=ts;return true;},ipiExitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=ipiHandlerExitRE.exec(eventBase.details);if(!event)
+return false;var ipiName=event[1];var thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);if(thread.lastEntryTs!==undefined){var duration=ts-thread.lastEntryTs;var slice=new tr.model.Slice('','IPI ('+ipiName+')',ColorScheme.getColorIdForGeneralPurposeString(ipiName),thread.lastEntryTs,{},duration);thread.thread.sliceGroup.pushSlice(slice);}
+thread.lastEntryTs=undefined;return true;}};Parser.register(IrqParser);return{IrqParser:IrqParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var LinuxPerfParser=tr.e.importer.linux_perf.Parser;function KernelFuncParser(importer){LinuxPerfParser.call(this,importer);importer.registerEventHandler('graph_ent',KernelFuncParser.prototype.traceKernelFuncEnterEvent.bind(this));importer.registerEventHandler('graph_ret',KernelFuncParser.prototype.traceKernelFuncReturnEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
+var TestExports={};var funcEnterRE=new RegExp('func=(.+)');TestExports.funcEnterRE=funcEnterRE;KernelFuncParser.prototype={__proto__:LinuxPerfParser.prototype,traceKernelFuncEnterEvent:function(eventName,cpuNumber,pid,ts,eventBase){var eventData=funcEnterRE.exec(eventBase.details);if(!eventData)
+return false;if(eventBase.tgid===undefined){return false;}
+var tgid=parseInt(eventBase.tgid);var name=eventData[1];var thread=this.model_.getOrCreateProcess(tgid).getOrCreateThread(pid);thread.name=eventBase.threadName;var slices=thread.kernelSliceGroup;if(!slices.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
+var slice=slices.beginSlice(null,name,ts,{});return true;},traceKernelFuncReturnEvent:function(eventName,cpuNumber,pid,ts,eventBase){if(eventBase.tgid===undefined){return false;}
+var tgid=parseInt(eventBase.tgid);var thread=this.model_.getOrCreateProcess(tgid).getOrCreateThread(pid);thread.name=eventBase.threadName;var slices=thread.kernelSliceGroup;if(!slices.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
+if(slices.openSliceCount>0){slices.endSlice(ts);}
+return true;}};LinuxPerfParser.register(KernelFuncParser);return{KernelFuncParser:KernelFuncParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function MaliParser(importer){Parser.call(this,importer);importer.registerEventHandler('mali_dvfs_event',MaliParser.prototype.dvfsEventEvent.bind(this));importer.registerEventHandler('mali_dvfs_set_clock',MaliParser.prototype.dvfsSetClockEvent.bind(this));importer.registerEventHandler('mali_dvfs_set_voltage',MaliParser.prototype.dvfsSetVoltageEvent.bind(this));this.addJMCounter('mali_hwc_MESSAGES_SENT','Messages Sent');this.addJMCounter('mali_hwc_MESSAGES_RECEIVED','Messages Received');this.addJMCycles('mali_hwc_GPU_ACTIVE','GPU Active');this.addJMCycles('mali_hwc_IRQ_ACTIVE','IRQ Active');for(var i=0;i<7;i++){var jobStr='JS'+i;var jobHWCStr='mali_hwc_'+jobStr;this.addJMCounter(jobHWCStr+'_JOBS',jobStr+' Jobs');this.addJMCounter(jobHWCStr+'_TASKS',jobStr+' Tasks');this.addJMCycles(jobHWCStr+'_ACTIVE',jobStr+' Active');this.addJMCycles(jobHWCStr+'_WAIT_READ',jobStr+' Wait Read');this.addJMCycles(jobHWCStr+'_WAIT_ISSUE',jobStr+' Wait Issue');this.addJMCycles(jobHWCStr+'_WAIT_DEPEND',jobStr+' Wait Depend');this.addJMCycles(jobHWCStr+'_WAIT_FINISH',jobStr+' Wait Finish');}
+this.addTilerCounter('mali_hwc_TRIANGLES','Triangles');this.addTilerCounter('mali_hwc_QUADS','Quads');this.addTilerCounter('mali_hwc_POLYGONS','Polygons');this.addTilerCounter('mali_hwc_POINTS','Points');this.addTilerCounter('mali_hwc_LINES','Lines');this.addTilerCounter('mali_hwc_VCACHE_HIT','VCache Hit');this.addTilerCounter('mali_hwc_VCACHE_MISS','VCache Miss');this.addTilerCounter('mali_hwc_FRONT_FACING','Front Facing');this.addTilerCounter('mali_hwc_BACK_FACING','Back Facing');this.addTilerCounter('mali_hwc_PRIM_VISIBLE','Prim Visible');this.addTilerCounter('mali_hwc_PRIM_CULLED','Prim Culled');this.addTilerCounter('mali_hwc_PRIM_CLIPPED','Prim Clipped');this.addTilerCounter('mali_hwc_WRBUF_HIT','Wrbuf Hit');this.addTilerCounter('mali_hwc_WRBUF_MISS','Wrbuf Miss');this.addTilerCounter('mali_hwc_WRBUF_LINE','Wrbuf Line');this.addTilerCounter('mali_hwc_WRBUF_PARTIAL','Wrbuf Partial');this.addTilerCounter('mali_hwc_WRBUF_STALL','Wrbuf Stall');this.addTilerCycles('mali_hwc_ACTIVE','Tiler Active');this.addTilerCycles('mali_hwc_INDEX_WAIT','Index Wait');this.addTilerCycles('mali_hwc_INDEX_RANGE_WAIT','Index Range Wait');this.addTilerCycles('mali_hwc_VERTEX_WAIT','Vertex Wait');this.addTilerCycles('mali_hwc_PCACHE_WAIT','Pcache Wait');this.addTilerCycles('mali_hwc_WRBUF_WAIT','Wrbuf Wait');this.addTilerCycles('mali_hwc_BUS_READ','Bus Read');this.addTilerCycles('mali_hwc_BUS_WRITE','Bus Write');this.addTilerCycles('mali_hwc_TILER_UTLB_STALL','Tiler UTLB Stall');this.addTilerCycles('mali_hwc_TILER_UTLB_HIT','Tiler UTLB Hit');this.addFragCycles('mali_hwc_FRAG_ACTIVE','Active');this.addFragCounter('mali_hwc_FRAG_PRIMATIVES','Primitives');this.addFragCounter('mali_hwc_FRAG_PRIMATIVES_DROPPED','Primitives Dropped');this.addFragCycles('mali_hwc_FRAG_CYCLE_DESC','Descriptor Processing');this.addFragCycles('mali_hwc_FRAG_CYCLES_PLR','PLR Processing??');this.addFragCycles('mali_hwc_FRAG_CYCLES_VERT','Vertex Processing');this.addFragCycles('mali_hwc_FRAG_CYCLES_TRISETUP','Triangle Setup');this.addFragCycles('mali_hwc_FRAG_CYCLES_RAST','Rasterization???');this.addFragCounter('mali_hwc_FRAG_THREADS','Threads');this.addFragCounter('mali_hwc_FRAG_DUMMY_THREADS','Dummy Threads');this.addFragCounter('mali_hwc_FRAG_QUADS_RAST','Quads Rast');this.addFragCounter('mali_hwc_FRAG_QUADS_EZS_TEST','Quads EZS Test');this.addFragCounter('mali_hwc_FRAG_QUADS_EZS_KILLED','Quads EZS Killed');this.addFragCounter('mali_hwc_FRAG_QUADS_LZS_TEST','Quads LZS Test');this.addFragCounter('mali_hwc_FRAG_QUADS_LZS_KILLED','Quads LZS Killed');this.addFragCycles('mali_hwc_FRAG_CYCLE_NO_TILE','No Tiles');this.addFragCounter('mali_hwc_FRAG_NUM_TILES','Tiles');this.addFragCounter('mali_hwc_FRAG_TRANS_ELIM','Transactions Eliminated');this.addComputeCycles('mali_hwc_COMPUTE_ACTIVE','Active');this.addComputeCounter('mali_hwc_COMPUTE_TASKS','Tasks');this.addComputeCounter('mali_hwc_COMPUTE_THREADS','Threads Started');this.addComputeCycles('mali_hwc_COMPUTE_CYCLES_DESC','Waiting for Descriptors');this.addTripipeCycles('mali_hwc_TRIPIPE_ACTIVE','Active');this.addArithCounter('mali_hwc_ARITH_WORDS','Instructions (/Pipes)');this.addArithCycles('mali_hwc_ARITH_CYCLES_REG','Reg scheduling stalls (/Pipes)');this.addArithCycles('mali_hwc_ARITH_CYCLES_L0','L0 cache miss stalls (/Pipes)');this.addArithCounter('mali_hwc_ARITH_FRAG_DEPEND','Frag dep check failures (/Pipes)');this.addLSCounter('mali_hwc_LS_WORDS','Instruction Words Completed');this.addLSCounter('mali_hwc_LS_ISSUES','Full Pipeline Issues');this.addLSCounter('mali_hwc_LS_RESTARTS','Restarts (unpairable insts)');this.addLSCounter('mali_hwc_LS_REISSUES_MISS','Pipeline reissue (cache miss/uTLB)');this.addLSCounter('mali_hwc_LS_REISSUES_VD','Pipeline reissue (varying data)');this.addLSCounter('mali_hwc_LS_REISSUE_ATTRIB_MISS','Pipeline reissue (attribute cache miss)');this.addLSCounter('mali_hwc_LS_REISSUE_NO_WB','Writeback not used');this.addTexCounter('mali_hwc_TEX_WORDS','Words');this.addTexCounter('mali_hwc_TEX_BUBBLES','Bubbles');this.addTexCounter('mali_hwc_TEX_WORDS_L0','Words L0');this.addTexCounter('mali_hwc_TEX_WORDS_DESC','Words Desc');this.addTexCounter('mali_hwc_TEX_THREADS','Threads');this.addTexCounter('mali_hwc_TEX_RECIRC_FMISS','Recirc due to Full Miss');this.addTexCounter('mali_hwc_TEX_RECIRC_DESC','Recirc due to Desc Miss');this.addTexCounter('mali_hwc_TEX_RECIRC_MULTI','Recirc due to Multipass');this.addTexCounter('mali_hwc_TEX_RECIRC_PMISS','Recirc due to Partial Cache Miss');this.addTexCounter('mali_hwc_TEX_RECIRC_CONF','Recirc due to Cache Conflict');this.addLSCCounter('mali_hwc_LSC_READ_HITS','Read Hits');this.addLSCCounter('mali_hwc_LSC_READ_MISSES','Read Misses');this.addLSCCounter('mali_hwc_LSC_WRITE_HITS','Write Hits');this.addLSCCounter('mali_hwc_LSC_WRITE_MISSES','Write Misses');this.addLSCCounter('mali_hwc_LSC_ATOMIC_HITS','Atomic Hits');this.addLSCCounter('mali_hwc_LSC_ATOMIC_MISSES','Atomic Misses');this.addLSCCounter('mali_hwc_LSC_LINE_FETCHES','Line Fetches');this.addLSCCounter('mali_hwc_LSC_DIRTY_LINE','Dirty Lines');this.addLSCCounter('mali_hwc_LSC_SNOOPS','Snoops');this.addAXICounter('mali_hwc_AXI_TLB_STALL','Address channel stall');this.addAXICounter('mali_hwc_AXI_TLB_MISS','Cache Miss');this.addAXICounter('mali_hwc_AXI_TLB_TRANSACTION','Transactions');this.addAXICounter('mali_hwc_LS_TLB_MISS','LS Cache Miss');this.addAXICounter('mali_hwc_LS_TLB_HIT','LS Cache Hit');this.addAXICounter('mali_hwc_AXI_BEATS_READ','Read Beats');this.addAXICounter('mali_hwc_AXI_BEATS_WRITE','Write Beats');this.addMMUCounter('mali_hwc_MMU_TABLE_WALK','Page Table Walks');this.addMMUCounter('mali_hwc_MMU_REPLAY_MISS','Cache Miss from Replay Buffer');this.addMMUCounter('mali_hwc_MMU_REPLAY_FULL','Replay Buffer Full');this.addMMUCounter('mali_hwc_MMU_NEW_MISS','Cache Miss on New Request');this.addMMUCounter('mali_hwc_MMU_HIT','Cache Hit');this.addMMUCycles('mali_hwc_UTLB_STALL','UTLB Stalled');this.addMMUCycles('mali_hwc_UTLB_REPLAY_MISS','UTLB Replay Miss');this.addMMUCycles('mali_hwc_UTLB_REPLAY_FULL','UTLB Replay Full');this.addMMUCycles('mali_hwc_UTLB_NEW_MISS','UTLB New Miss');this.addMMUCycles('mali_hwc_UTLB_HIT','UTLB Hit');this.addL2Counter('mali_hwc_L2_READ_BEATS','Read Beats');this.addL2Counter('mali_hwc_L2_WRITE_BEATS','Write Beats');this.addL2Counter('mali_hwc_L2_ANY_LOOKUP','Any Lookup');this.addL2Counter('mali_hwc_L2_READ_LOOKUP','Read Lookup');this.addL2Counter('mali_hwc_L2_SREAD_LOOKUP','Shareable Read Lookup');this.addL2Counter('mali_hwc_L2_READ_REPLAY','Read Replayed');this.addL2Counter('mali_hwc_L2_READ_SNOOP','Read Snoop');this.addL2Counter('mali_hwc_L2_READ_HIT','Read Cache Hit');this.addL2Counter('mali_hwc_L2_CLEAN_MISS','CleanUnique Miss');this.addL2Counter('mali_hwc_L2_WRITE_LOOKUP','Write Lookup');this.addL2Counter('mali_hwc_L2_SWRITE_LOOKUP','Shareable Write Lookup');this.addL2Counter('mali_hwc_L2_WRITE_REPLAY','Write Replayed');this.addL2Counter('mali_hwc_L2_WRITE_SNOOP','Write Snoop');this.addL2Counter('mali_hwc_L2_WRITE_HIT','Write Cache Hit');this.addL2Counter('mali_hwc_L2_EXT_READ_FULL','ExtRD with BIU Full');this.addL2Counter('mali_hwc_L2_EXT_READ_HALF','ExtRD with BIU >1/2 Full');this.addL2Counter('mali_hwc_L2_EXT_WRITE_FULL','ExtWR with BIU Full');this.addL2Counter('mali_hwc_L2_EXT_WRITE_HALF','ExtWR with BIU >1/2 Full');this.addL2Counter('mali_hwc_L2_EXT_READ','External Read (ExtRD)');this.addL2Counter('mali_hwc_L2_EXT_READ_LINE','ExtRD (linefill)');this.addL2Counter('mali_hwc_L2_EXT_WRITE','External Write (ExtWR)');this.addL2Counter('mali_hwc_L2_EXT_WRITE_LINE','ExtWR (linefill)');this.addL2Counter('mali_hwc_L2_EXT_WRITE_SMALL','ExtWR (burst size <64B)');this.addL2Counter('mali_hwc_L2_EXT_BARRIER','External Barrier');this.addL2Counter('mali_hwc_L2_EXT_AR_STALL','Address Read stalls');this.addL2Counter('mali_hwc_L2_EXT_R_BUF_FULL','Response Buffer full stalls');this.addL2Counter('mali_hwc_L2_EXT_RD_BUF_FULL','Read Data Buffer full stalls');this.addL2Counter('mali_hwc_L2_EXT_R_RAW','RAW hazard stalls');this.addL2Counter('mali_hwc_L2_EXT_W_STALL','Write Data stalls');this.addL2Counter('mali_hwc_L2_EXT_W_BUF_FULL','Write Data Buffer full');this.addL2Counter('mali_hwc_L2_EXT_R_W_HAZARD','WAW or WAR hazard stalls');this.addL2Counter('mali_hwc_L2_TAG_HAZARD','Tag hazard replays');this.addL2Cycles('mali_hwc_L2_SNOOP_FULL','Snoop buffer full');this.addL2Cycles('mali_hwc_L2_REPLAY_FULL','Replay buffer full');importer.registerEventHandler('tracing_mark_write:mali_driver',MaliParser.prototype.maliDDKEvent.bind(this));this.model_=importer.model_;}
+MaliParser.prototype={__proto__:Parser.prototype,maliDDKOpenSlice:function(pid,tid,ts,func,blockinfo){var thread=this.importer.model_.getOrCreateProcess(pid).getOrCreateThread(tid);var funcArgs=/^([\w\d_]*)(?:\(\))?:?\s*(.*)$/.exec(func);thread.sliceGroup.beginSlice('gpu-driver',funcArgs[1],ts,{'args':funcArgs[2],'blockinfo':blockinfo});},maliDDKCloseSlice:function(pid,tid,ts,args,blockinfo){var thread=this.importer.model_.getOrCreateProcess(pid).getOrCreateThread(tid);if(!thread.sliceGroup.openSliceCount){return;}
+thread.sliceGroup.endSlice(ts);},autoDetectLineRE:function(line){var lineREWithThread=/^\s*\(([\w\-]*)\)\s*(\w+):\s*([\w\\\/\.\-]*@\d*):?\s*(.*)$/;if(lineREWithThread.test(line))
+return lineREWithThread;var lineRENoThread=/^s*()(\w+):\s*([\w\\\/.\-]*):?\s*(.*)$/;if(lineRENoThread.test(line))
+return lineRENoThread;return null;},lineRE:null,maliDDKEvent:function(eventName,cpuNumber,pid,ts,eventBase){if(this.lineRE==null){this.lineRE=this.autoDetectLineRE(eventBase.details);if(this.lineRE==null)
+return false;}
+var maliEvent=this.lineRE.exec(eventBase.details);var tid=(maliEvent[1]===''?'mali':maliEvent[1]);switch(maliEvent[2]){case'cros_trace_print_enter':this.maliDDKOpenSlice(pid,tid,ts,maliEvent[4],maliEvent[3]);break;case'cros_trace_print_exit':this.maliDDKCloseSlice(pid,tid,ts,[],maliEvent[3]);}
+return true;},dvfsSample:function(counterName,seriesName,ts,s){var value=parseInt(s);var counter=this.model_.kernel.getOrCreateCounter('DVFS',counterName);if(counter.numSeries===0){counter.addSeries(new tr.model.CounterSeries(seriesName,ColorScheme.getColorIdForGeneralPurposeString(counter.name)));}
+counter.series.forEach(function(series){series.addCounterSample(ts,value);});},dvfsEventEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/utilization=(\d+)/.exec(eventBase.details);if(!event)
+return false;this.dvfsSample('DVFS Utilization','utilization',ts,event[1]);return true;},dvfsSetClockEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/frequency=(\d+)/.exec(eventBase.details);if(!event)
+return false;this.dvfsSample('DVFS Frequency','frequency',ts,event[1]);return true;},dvfsSetVoltageEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/voltage=(\d+)/.exec(eventBase.details);if(!event)
+return false;this.dvfsSample('DVFS Voltage','voltage',ts,event[1]);return true;},hwcSample:function(cat,counterName,seriesName,ts,eventBase){var event=/val=(\d+)/.exec(eventBase.details);if(!event)
+return false;var value=parseInt(event[1]);var counter=this.model_.kernel.getOrCreateCounter(cat,counterName);if(counter.numSeries===0){counter.addSeries(new tr.model.CounterSeries(seriesName,ColorScheme.getColorIdForGeneralPurposeString(counter.name)));}
+counter.series.forEach(function(series){series.addCounterSample(ts,value);});return true;},jmSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:jm','JM: '+ctrName,seriesName,ts,eventBase);},addJMCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.jmSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addJMCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.jmSample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},tilerSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:tiler','Tiler: '+ctrName,seriesName,ts,eventBase);},addTilerCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.tilerSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addTilerCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.tilerSample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},fragSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:fragment','Fragment: '+ctrName,seriesName,ts,eventBase);},addFragCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.fragSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addFragCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.fragSample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},computeSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:compute','Compute: '+ctrName,seriesName,ts,eventBase);},addComputeCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.computeSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addComputeCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.computeSample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addTripipeCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:shader','Tripipe: '+hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},arithSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:arith','Arith: '+ctrName,seriesName,ts,eventBase);},addArithCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.arithSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addArithCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.arithSample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addLSCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:ls','LS: '+hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},textureSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:texture','Texture: '+ctrName,seriesName,ts,eventBase);},addTexCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.textureSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addLSCCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:lsc','LSC: '+hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addAXICounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:axi','AXI: '+hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},mmuSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:mmu','MMU: '+ctrName,seriesName,ts,eventBase);},addMMUCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.mmuSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addMMUCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.mmuSample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},l2Sample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:l2','L2: '+ctrName,seriesName,ts,eventBase);},addL2Counter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.l2Sample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addL2Cycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.l2Sample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));}};Parser.register(MaliParser);return{MaliParser:MaliParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var Parser=tr.e.importer.linux_perf.Parser;function MemReclaimParser(importer){Parser.call(this,importer);importer.registerEventHandler('mm_vmscan_kswapd_wake',MemReclaimParser.prototype.kswapdWake.bind(this));importer.registerEventHandler('mm_vmscan_kswapd_sleep',MemReclaimParser.prototype.kswapdSleep.bind(this));importer.registerEventHandler('mm_vmscan_direct_reclaim_begin',MemReclaimParser.prototype.reclaimBegin.bind(this));importer.registerEventHandler('mm_vmscan_direct_reclaim_end',MemReclaimParser.prototype.reclaimEnd.bind(this));}
+var kswapdWakeRE=/nid=(\d+) order=(\d+)/;var kswapdSleepRE=/nid=(\d+)/;var reclaimBeginRE=/order=(\d+) may_writepage=\d+ gfp_flags=(.+)/;var reclaimEndRE=/nr_reclaimed=(\d+)/;MemReclaimParser.prototype={__proto__:Parser.prototype,kswapdWake:function(eventName,cpuNumber,pid,ts,eventBase){var event=kswapdWakeRE.exec(eventBase.details);if(!event)
+return false;var tgid=parseInt(eventBase.tgid);var nid=parseInt(event[1]);var order=parseInt(event[2]);var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);if(kthread.openSliceTS){if(order>kthread.order){kthread.order=order;}}else{kthread.openSliceTS=ts;kthread.order=order;}
+return true;},kswapdSleep:function(eventName,cpuNumber,pid,ts,eventBase){var tgid=parseInt(eventBase.tgid);var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);if(kthread.openSliceTS){kthread.thread.sliceGroup.pushCompleteSlice('memreclaim',eventBase.threadName,kthread.openSliceTS,ts-kthread.openSliceTS,0,0,{order:kthread.order});}
+kthread.openSliceTS=undefined;kthread.order=undefined;return true;},reclaimBegin:function(eventName,cpuNumber,pid,ts,eventBase){var event=reclaimBeginRE.exec(eventBase.details);if(!event)
+return false;var order=parseInt(event[1]);var gfp=event[2];var tgid=parseInt(eventBase.tgid);var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);kthread.openSliceTS=ts;kthread.order=order;kthread.gfp=gfp;return true;},reclaimEnd:function(eventName,cpuNumber,pid,ts,eventBase){var event=reclaimEndRE.exec(eventBase.details);if(!event)
+return false;var nr_reclaimed=parseInt(event[1]);var tgid=parseInt(eventBase.tgid);var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);if(kthread.openSliceTS!==undefined){kthread.thread.sliceGroup.pushCompleteSlice('memreclaim','direct reclaim',kthread.openSliceTS,ts-kthread.openSliceTS,0,0,{order:kthread.order,gfp:kthread.gfp,nr_reclaimed:nr_reclaimed});}
+kthread.openSliceTS=undefined;kthread.order=undefined;kthread.gfp=undefined;return true;}};Parser.register(MemReclaimParser);return{MemReclaimParser:MemReclaimParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function PowerParser(importer){Parser.call(this,importer);importer.registerEventHandler('power_start',PowerParser.prototype.powerStartEvent.bind(this));importer.registerEventHandler('power_frequency',PowerParser.prototype.powerFrequencyEvent.bind(this));importer.registerEventHandler('cpu_frequency',PowerParser.prototype.cpuFrequencyEvent.bind(this));importer.registerEventHandler('cpu_idle',PowerParser.prototype.cpuIdleEvent.bind(this));}
+PowerParser.prototype={__proto__:Parser.prototype,cpuStateSlice:function(ts,targetCpuNumber,eventType,cpuState){var targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);var powerCounter;if(eventType!='1'){this.importer.model.importWarning({type:'parse_error',message:'Don\'t understand power_start events of '+'type '+eventType});return;}
+powerCounter=targetCpu.getOrCreateCounter('','C-State');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('state',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'state')));}
+powerCounter.series.forEach(function(series){series.addCounterSample(ts,cpuState);});},cpuIdleSlice:function(ts,targetCpuNumber,cpuState){var targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);var powerCounter=targetCpu.getOrCreateCounter('','C-State');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('state',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name)));}
+var val=(cpuState!=4294967295?cpuState+1:0);powerCounter.series.forEach(function(series){series.addCounterSample(ts,val);});},cpuFrequencySlice:function(ts,targetCpuNumber,powerState){var targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);var powerCounter=targetCpu.getOrCreateCounter('','Clock Frequency');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('state',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'state')));}
+powerCounter.series.forEach(function(series){series.addCounterSample(ts,powerState);});},powerStartEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/type=(\d+) state=(\d) cpu_id=(\d)+/.exec(eventBase.details);if(!event)
+return false;var targetCpuNumber=parseInt(event[3]);var cpuState=parseInt(event[2]);this.cpuStateSlice(ts,targetCpuNumber,event[1],cpuState);return true;},powerFrequencyEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/type=(\d+) state=(\d+) cpu_id=(\d)+/.exec(eventBase.details);if(!event)
+return false;var targetCpuNumber=parseInt(event[3]);var powerState=parseInt(event[2]);this.cpuFrequencySlice(ts,targetCpuNumber,powerState);return true;},cpuFrequencyEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/state=(\d+) cpu_id=(\d)+/.exec(eventBase.details);if(!event)
+return false;var targetCpuNumber=parseInt(event[2]);var powerState=parseInt(event[1]);this.cpuFrequencySlice(ts,targetCpuNumber,powerState);return true;},cpuIdleEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/state=(\d+) cpu_id=(\d)+/.exec(eventBase.details);if(!event)
+return false;var targetCpuNumber=parseInt(event[2]);var cpuState=parseInt(event[1]);this.cpuIdleSlice(ts,targetCpuNumber,cpuState);return true;}};Parser.register(PowerParser);return{PowerParser:PowerParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function RegulatorParser(importer){Parser.call(this,importer);importer.registerEventHandler('regulator_enable',RegulatorParser.prototype.regulatorEnableEvent.bind(this));importer.registerEventHandler('regulator_enable_delay',RegulatorParser.prototype.regulatorEnableDelayEvent.bind(this));importer.registerEventHandler('regulator_enable_complete',RegulatorParser.prototype.regulatorEnableCompleteEvent.bind(this));importer.registerEventHandler('regulator_disable',RegulatorParser.prototype.regulatorDisableEvent.bind(this));importer.registerEventHandler('regulator_disable_complete',RegulatorParser.prototype.regulatorDisableCompleteEvent.bind(this));importer.registerEventHandler('regulator_set_voltage',RegulatorParser.prototype.regulatorSetVoltageEvent.bind(this));importer.registerEventHandler('regulator_set_voltage_complete',RegulatorParser.prototype.regulatorSetVoltageCompleteEvent.bind(this));this.model_=importer.model_;}
+var regulatorEnableRE=/name=(.+)/;var regulatorDisableRE=/name=(.+)/;var regulatorSetVoltageCompleteRE=/name=(\S+), val=(\d+)/;RegulatorParser.prototype={__proto__:Parser.prototype,getCtr_:function(ctrName,valueName){var ctr=this.model_.kernel.getOrCreateCounter(null,'vreg '+ctrName+' '+valueName);if(ctr.series[0]===undefined){ctr.addSeries(new tr.model.CounterSeries(valueName,ColorScheme.getColorIdForGeneralPurposeString(ctrName+'.'+valueName)));}
+return ctr;},regulatorEnableEvent:function(eventName,cpuNum,pid,ts,eventBase){var event=regulatorEnableRE.exec(eventBase.details);if(!event)
+return false;var name=event[1];var ctr=this.getCtr_(name,'enabled');ctr.series[0].addCounterSample(ts,1);return true;},regulatorEnableDelayEvent:function(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorEnableCompleteEvent:function(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorDisableEvent:function(eventName,cpuNum,pid,ts,eventBase){var event=regulatorDisableRE.exec(eventBase.details);if(!event)
+return false;var name=event[1];var ctr=this.getCtr_(name,'enabled');ctr.series[0].addCounterSample(ts,0);return true;},regulatorDisableCompleteEvent:function(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorSetVoltageEvent:function(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorSetVoltageCompleteEvent:function(eventName,cpuNum,pid,ts,eventBase){var event=regulatorSetVoltageCompleteRE.exec(eventBase.details);if(!event)
+return false;var name=event[1];var voltage=parseInt(event[2]);var ctr=this.getCtr_(name,'voltage');ctr.series[0].addCounterSample(ts,voltage);return true;}};Parser.register(RegulatorParser);return{RegulatorParser:RegulatorParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var Parser=tr.e.importer.linux_perf.Parser;function SchedParser(importer){Parser.call(this,importer);importer.registerEventHandler('sched_switch',SchedParser.prototype.schedSwitchEvent.bind(this));importer.registerEventHandler('sched_wakeup',SchedParser.prototype.schedWakeupEvent.bind(this));}
+var TestExports={};var schedSwitchRE=new RegExp('prev_comm=(.+) prev_pid=(\\d+) prev_prio=(\\d+) '+'prev_state=(\\S\\+?|\\S\\|\\S) ==> '+'next_comm=(.+) next_pid=(\\d+) next_prio=(\\d+)');TestExports.schedSwitchRE=schedSwitchRE;var schedWakeupRE=/comm=(.+) pid=(\d+) prio=(\d+) success=(\d+) target_cpu=(\d+)/;TestExports.schedWakeupRE=schedWakeupRE;SchedParser.prototype={__proto__:Parser.prototype,schedSwitchEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=schedSwitchRE.exec(eventBase.details);if(!event)
+return false;var prevState=event[4];var nextComm=event[5];var nextPid=parseInt(event[6]);var nextPrio=parseInt(event[7]);var nextThread=this.importer.threadsByLinuxPid[nextPid];var nextName;if(nextThread)
+nextName=nextThread.userFriendlyName;else
+nextName=nextComm;var cpu=this.importer.getOrCreateCpu(cpuNumber);cpu.switchActiveThread(ts,{stateWhenDescheduled:prevState},nextPid,nextName,{comm:nextComm,tid:nextPid,prio:nextPrio});return true;},schedWakeupEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=schedWakeupRE.exec(eventBase.details);if(!event)
+return false;var fromPid=pid;var comm=event[1];var pid=parseInt(event[2]);var prio=parseInt(event[3]);this.importer.markPidRunnable(ts,pid,comm,prio,fromPid);return true;}};Parser.register(SchedParser);return{SchedParser:SchedParser,_SchedParserTestExports:TestExports};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function SyncParser(importer){Parser.call(this,importer);importer.registerEventHandler('sync_timeline',SyncParser.prototype.timelineEvent.bind(this));importer.registerEventHandler('sync_wait',SyncParser.prototype.syncWaitEvent.bind(this));importer.registerEventHandler('sync_pt',SyncParser.prototype.syncPtEvent.bind(this));this.model_=importer.model_;}
+var syncTimelineRE=/name=(\S+) value=(\S*)/;var syncWaitRE=/(\S+) name=(\S+) state=(\d+)/;var syncPtRE=/name=(\S+) value=(\S*)/;SyncParser.prototype={__proto__:Parser.prototype,timelineEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=syncTimelineRE.exec(eventBase.details);if(!event)
+return false;var thread=this.importer.getOrCreatePseudoThread(event[1]);if(thread.lastActiveTs!==undefined){var duration=ts-thread.lastActiveTs;var value=thread.lastActiveValue;if(value==undefined)
+value=' ';var slice=new tr.model.Slice('',value,ColorScheme.getColorIdForGeneralPurposeString(value),thread.lastActiveTs,{},duration);thread.thread.sliceGroup.pushSlice(slice);}
+thread.lastActiveTs=ts;thread.lastActiveValue=event[2];return true;},syncWaitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=syncWaitRE.exec(eventBase.details);if(!event)
+return false;if(eventBase.tgid===undefined){return false;}
+var tgid=parseInt(eventBase.tgid);var thread=this.model_.getOrCreateProcess(tgid).getOrCreateThread(pid);thread.name=eventBase.threadName;var slices=thread.kernelSliceGroup;if(!slices.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
+var name='fence_wait("'+event[2]+'")';if(event[1]=='begin'){var slice=slices.beginSlice(null,name,ts,{'Start state':event[3]});}else if(event[1]=='end'){if(slices.openSliceCount>0){slices.endSlice(ts);}}else{return false;}
+return true;},syncPtEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=syncPtRE.exec(eventBase.details);if(!event)
+return false;return true;var thread=this.importer.getOrCreateKernelThread(eventBase[1]).thread;thread.syncWaitSyncPts[event[1]]=event[2];return true;}};Parser.register(SyncParser);return{SyncParser:SyncParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function WorkqueueParser(importer){Parser.call(this,importer);importer.registerEventHandler('workqueue_execute_start',WorkqueueParser.prototype.executeStartEvent.bind(this));importer.registerEventHandler('workqueue_execute_end',WorkqueueParser.prototype.executeEndEvent.bind(this));importer.registerEventHandler('workqueue_queue_work',WorkqueueParser.prototype.executeQueueWork.bind(this));importer.registerEventHandler('workqueue_activate_work',WorkqueueParser.prototype.executeActivateWork.bind(this));}
+var workqueueExecuteStartRE=/work struct (.+): function (\S+)/;var workqueueExecuteEndRE=/work struct (.+)/;WorkqueueParser.prototype={__proto__:Parser.prototype,executeStartEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=workqueueExecuteStartRE.exec(eventBase.details);if(!event)
+return false;var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,pid,pid);kthread.openSliceTS=ts;kthread.openSlice=event[2];return true;},executeEndEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=workqueueExecuteEndRE.exec(eventBase.details);if(!event)
+return false;var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,pid,pid);if(kthread.openSlice){var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),kthread.openSliceTS,{},ts-kthread.openSliceTS);kthread.thread.sliceGroup.pushSlice(slice);}
+kthread.openSlice=undefined;return true;},executeQueueWork:function(eventName,cpuNumber,pid,ts,eventBase){return true;},executeActivateWork:function(eventName,cpuNumber,pid,ts,eventBase){return true;}};Parser.register(WorkqueueParser);return{WorkqueueParser:WorkqueueParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ClockSyncRecord=tr.ClockSyncRecord;function LinuxPerfImporter(model,events){this.importPriority=2;this.model_=model;this.events_=events;this.newlyAddedClockSyncRecords_=[];this.wakeups_=[];this.kernelThreadStates_={};this.buildMapFromLinuxPidsToThreads();this.lines_=[];this.pseudoThreadCounter=1;this.parsers_=[];this.eventHandlers_={};}
+var TestExports={};var lineREWithTGID=new RegExp('^\\s*(.+)-(\\d+)\\s+\\(\\s*(\\d+|-+)\\)\\s\\[(\\d+)\\]'+'\\s+[dX.][Nnp.][Hhs.][0-9a-f.]'+'\\s+(\\d+\\.\\d+):\\s+(\\S+):\\s(.*)$');var lineParserWithTGID=function(line){var groups=lineREWithTGID.exec(line);if(!groups){return groups;}
+var tgid=groups[3];if(tgid[0]==='-')
+tgid=undefined;return{threadName:groups[1],pid:groups[2],tgid:tgid,cpuNumber:groups[4],timestamp:groups[5],eventName:groups[6],details:groups[7]};};TestExports.lineParserWithTGID=lineParserWithTGID;var lineREWithIRQInfo=new RegExp('^\\s*(.+)-(\\d+)\\s+\\[(\\d+)\\]'+'\\s+[dX.][Nnp.][Hhs.][0-9a-f.]'+'\\s+(\\d+\\.\\d+):\\s+(\\S+):\\s(.*)$');var lineParserWithIRQInfo=function(line){var groups=lineREWithIRQInfo.exec(line);if(!groups){return groups;}
+return{threadName:groups[1],pid:groups[2],cpuNumber:groups[3],timestamp:groups[4],eventName:groups[5],details:groups[6]};};TestExports.lineParserWithIRQInfo=lineParserWithIRQInfo;var lineREWithLegacyFmt=/^\s*(.+)-(\d+)\s+\[(\d+)\]\s*(\d+\.\d+):\s+(\S+):\s(.*)$/;var lineParserWithLegacyFmt=function(line){var groups=lineREWithLegacyFmt.exec(line);if(!groups){return groups;}
+return{threadName:groups[1],pid:groups[2],cpuNumber:groups[3],timestamp:groups[4],eventName:groups[5],details:groups[6]};};TestExports.lineParserWithLegacyFmt=lineParserWithLegacyFmt;var traceEventClockSyncRE=/trace_event_clock_sync: parent_ts=(\d+\.?\d*)/;TestExports.traceEventClockSyncRE=traceEventClockSyncRE;var realTimeClockSyncRE=/trace_event_clock_sync: realtime_ts=(\d+)/;var genericClockSyncRE=/trace_event_clock_sync: name=(\w+)/;var pseudoKernelPID=0;function autoDetectLineParser(line){if(line[0]=='{')
+return false;if(lineREWithTGID.test(line))
+return lineParserWithTGID;if(lineREWithIRQInfo.test(line))
+return lineParserWithIRQInfo;if(lineREWithLegacyFmt.test(line))
+return lineParserWithLegacyFmt;return null;};TestExports.autoDetectLineParser=autoDetectLineParser;LinuxPerfImporter.canImport=function(events){if(!(typeof(events)==='string'||events instanceof String))
+return false;if(LinuxPerfImporter._extractEventsFromSystraceHTML(events,false).ok)
+return true;if(LinuxPerfImporter._extractEventsFromSystraceMultiHTML(events,false).ok)
+return true;if(/^# tracer:/.test(events))
+return true;var lineBreakIndex=events.indexOf('\n');if(lineBreakIndex>-1)
+events=events.substring(0,lineBreakIndex);if(autoDetectLineParser(events))
+return true;return false;};LinuxPerfImporter._extractEventsFromSystraceHTML=function(incoming_events,produce_result){var failure={ok:false};if(produce_result===undefined)
+produce_result=true;if(/^<!DOCTYPE html>/.test(incoming_events)==false)
+return failure;var r=new tr.importer.SimpleLineReader(incoming_events);if(!r.advanceToLineMatching(/^  <script>$/))
+return failure;if(!r.advanceToLineMatching(/^  var linuxPerfData = "\\$/))
+return failure;var events_begin_at_line=r.curLineNumber+1;r.beginSavingLines();if(!r.advanceToLineMatching(/^  <\/script>$/))
+return failure;var raw_events=r.endSavingLinesAndGetResult();raw_events=raw_events.slice(1,raw_events.length-1);if(!r.advanceToLineMatching(/^<\/body>$/))
+return failure;if(!r.advanceToLineMatching(/^<\/html>$/))
+return failure;function endsWith(str,suffix){return str.indexOf(suffix,str.length-suffix.length)!==-1;}
+function stripSuffix(str,suffix){if(!endsWith(str,suffix))
+return str;return str.substring(str,str.length-suffix.length);}
+var events=[];if(produce_result){for(var i=0;i<raw_events.length;i++){var event=raw_events[i];event=stripSuffix(event,'\\n\\');events.push(event);}}else{events=[raw_events[raw_events.length-1]];}
+var oldLastEvent=events[events.length-1];var newLastEvent=stripSuffix(oldLastEvent,'\\n";');if(newLastEvent==oldLastEvent)
+return failure;events[events.length-1]=newLastEvent;return{ok:true,lines:produce_result?events:undefined,events_begin_at_line:events_begin_at_line};};LinuxPerfImporter._extractEventsFromSystraceMultiHTML=function(incoming_events,produce_result){var failure={ok:false};if(produce_result===undefined)
+produce_result=true;if(new RegExp('^<!DOCTYPE HTML>','i').test(incoming_events)==false)
+return failure;var r=new tr.importer.SimpleLineReader(incoming_events);var events=[];while(!/^# tracer:/.test(events)){if(!r.advanceToLineMatching(/^  <script class="trace-data" type="application\/text">$/))
+return failure;var events_begin_at_line=r.curLineNumber+1;r.beginSavingLines();if(!r.advanceToLineMatching(/^  <\/script>$/))
+return failure;events=r.endSavingLinesAndGetResult();events=events.slice(1,events.length-1);}
+if(!r.advanceToLineMatching(/^<\/body>$/))
+return failure;if(!r.advanceToLineMatching(/^<\/html>$/))
+return failure;return{ok:true,lines:produce_result?events:undefined,events_begin_at_line:events_begin_at_line};};LinuxPerfImporter.prototype={__proto__:tr.importer.Importer.prototype,get model(){return this.model_;},buildMapFromLinuxPidsToThreads:function(){this.threadsByLinuxPid={};this.model_.getAllThreads().forEach(function(thread){this.threadsByLinuxPid[thread.tid]=thread;}.bind(this));},getOrCreateCpu:function(cpuNumber){return this.model_.kernel.getOrCreateCpu(cpuNumber);},getOrCreateKernelThread:function(kernelThreadName,pid,tid){if(!this.kernelThreadStates_[kernelThreadName]){var thread=this.model_.getOrCreateProcess(pid).getOrCreateThread(tid);thread.name=kernelThreadName;this.kernelThreadStates_[kernelThreadName]={pid:pid,thread:thread,openSlice:undefined,openSliceTS:undefined};this.threadsByLinuxPid[pid]=thread;}
+return this.kernelThreadStates_[kernelThreadName];},getOrCreateBinderKernelThread:function(kernelThreadName,pid,tid){var key=kernelThreadName+pid+tid;if(!this.kernelThreadStates_[key]){var thread=this.model_.getOrCreateProcess(pid).getOrCreateThread(tid);thread.name=kernelThreadName;this.kernelThreadStates_[key]={pid:pid,thread:thread,openSlice:undefined,openSliceTS:undefined};this.threadsByLinuxPid[pid]=thread;}
+return this.kernelThreadStates_[key];},getOrCreatePseudoThread:function(threadName){var thread=this.kernelThreadStates_[threadName];if(!thread){thread=this.getOrCreateKernelThread(threadName,pseudoKernelPID,this.pseudoThreadCounter);this.pseudoThreadCounter++;}
+return thread;},importEvents:function(isSecondaryImport){this.parsers_=this.createParsers_();this.registerDefaultHandlers_();this.parseLines();this.importClockSyncRecords();var timeShift=this.computeTimeTransform();if(timeShift===undefined){this.model_.importWarning({type:'clock_sync',message:'Cannot import kernel trace without a clock sync.'});return;}
+this.shiftNewlyAddedClockSyncRecords(timeShift);this.importCpuData(timeShift);this.buildMapFromLinuxPidsToThreads();this.buildPerThreadCpuSlicesFromCpuState();this.computeCpuTimestampsForSlicesAsNeeded();},buildPerThreadCpuSlicesFromCpuState:function(){var SCHEDULING_STATE=tr.model.SCHEDULING_STATE;for(var cpuNumber in this.model_.kernel.cpus){var cpu=this.model_.kernel.cpus[cpuNumber];for(var i=0;i<cpu.slices.length;i++){var cpuSlice=cpu.slices[i];var thread=this.threadsByLinuxPid[cpuSlice.args.tid];if(!thread)
+continue;cpuSlice.threadThatWasRunning=thread;if(!thread.tempCpuSlices)
+thread.tempCpuSlices=[];thread.tempCpuSlices.push(cpuSlice);}}
+for(var i in this.wakeups_){var wakeup=this.wakeups_[i];var thread=this.threadsByLinuxPid[wakeup.tid];if(!thread)
+continue;thread.tempWakeups=thread.tempWakeups||[];thread.tempWakeups.push(wakeup);}
+this.model_.getAllThreads().forEach(function(thread){if(thread.tempCpuSlices===undefined)
+return;var origSlices=thread.tempCpuSlices;delete thread.tempCpuSlices;origSlices.sort(function(x,y){return x.start-y.start;});var wakeups=thread.tempWakeups||[];delete thread.tempWakeups;wakeups.sort(function(x,y){return x.ts-y.ts;});var slices=[];if(origSlices.length){var slice=origSlices[0];if(wakeups.length&&wakeups[0].ts<slice.start){var wakeup=wakeups.shift();var wakeupDuration=slice.start-wakeup.ts;var args={'wakeup from tid':wakeup.fromTid};slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNABLE,'',wakeup.ts,args,wakeupDuration));}
+var runningSlice=new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNING,'',slice.start,{},slice.duration);runningSlice.cpuOnWhichThreadWasRunning=slice.cpu;slices.push(runningSlice);}
+var wakeup=undefined;for(var i=1;i<origSlices.length;i++){var prevSlice=origSlices[i-1];var nextSlice=origSlices[i];var midDuration=nextSlice.start-prevSlice.end;while(wakeups.length&&wakeups[0].ts<nextSlice.start){var w=wakeups.shift();if(wakeup===undefined&&w.ts>prevSlice.end){wakeup=w;}}
+var pushSleep=function(state){if(wakeup!==undefined){midDuration=wakeup.ts-prevSlice.end;}
+slices.push(new tr.model.ThreadTimeSlice(thread,state,'',prevSlice.end,{},midDuration));if(wakeup!==undefined){var wakeupDuration=nextSlice.start-wakeup.ts;var args={'wakeup from tid':wakeup.fromTid};slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNABLE,'',wakeup.ts,args,wakeupDuration));wakeup=undefined;}};if(prevSlice.args.stateWhenDescheduled=='S'){pushSleep(SCHEDULING_STATE.SLEEPING);}else if(prevSlice.args.stateWhenDescheduled=='R'||prevSlice.args.stateWhenDescheduled=='R+'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNABLE,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='D'){pushSleep(SCHEDULING_STATE.UNINTR_SLEEP);}else if(prevSlice.args.stateWhenDescheduled=='T'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.STOPPED,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='t'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.DEBUG,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='Z'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.ZOMBIE,'',ioWaitId,prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='X'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.EXIT_DEAD,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='x'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.TASK_DEAD,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='K'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.WAKE_KILL,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='W'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.WAKING,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='D|K'){pushSleep(SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL);}else if(prevSlice.args.stateWhenDescheduled=='D|W'){pushSleep(SCHEDULING_STATE.UNINTR_SLEEP_WAKING);}else{slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.UNKNOWN,'',prevSlice.end,{},midDuration));this.model_.importWarning({type:'parse_error',message:'Unrecognized sleep state: '+
+prevSlice.args.stateWhenDescheduled});}
+var runningSlice=new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNING,'',nextSlice.start,{},nextSlice.duration);runningSlice.cpuOnWhichThreadWasRunning=prevSlice.cpu;slices.push(runningSlice);}
+thread.timeSlices=slices;},this);},computeCpuTimestampsForSlicesAsNeeded:function(){},computeTimeTransform:function(){var isSecondaryImport=this.model.getClockSyncRecordsNamed('ftrace_importer').length!==0;var mSyncs=this.model_.getClockSyncRecordsNamed('monotonic');if(mSyncs.length==0)
+return isSecondaryImport?undefined:0;var sync=mSyncs[0].args;if(sync.parentTS==0||sync.parentTS==sync.perfTS)
+return 0;return sync.parentTS-sync.perfTS;},createParsers_:function(){var allTypeInfos=tr.e.importer.linux_perf.Parser.getAllRegisteredTypeInfos();var parsers=allTypeInfos.map(function(typeInfo){return new typeInfo.constructor(this);},this);return parsers;},registerDefaultHandlers_:function(){this.registerEventHandler('tracing_mark_write',LinuxPerfImporter.prototype.traceMarkingWriteEvent.bind(this));this.registerEventHandler('0',LinuxPerfImporter.prototype.traceMarkingWriteEvent.bind(this));this.registerEventHandler('tracing_mark_write:trace_event_clock_sync',function(){return true;});this.registerEventHandler('0:trace_event_clock_sync',function(){return true;});},registerEventHandler:function(eventName,handler){this.eventHandlers_[eventName]=handler;},markPidRunnable:function(ts,pid,comm,prio,fromPid){this.wakeups_.push({ts:ts,tid:pid,fromTid:fromPid});},traceClockSyncEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/name=(\w+?)\s(.+)/.exec(eventBase.details);if(event){var name=event[1];var pieces=event[2].split(' ');var args={perfTS:ts};for(var i=0;i<pieces.length;i++){var parts=pieces[i].split('=');if(parts.length!=2)
+throw new Error('omgbbq');args[parts[0]]=parts[1];}
+this.addClockSyncRecord(new ClockSyncRecord(name,ts,args));return true;}
+event=/parent_ts=(\d+\.?\d*)/.exec(eventBase.details);if(!event)
+return false;this.addClockSyncRecord(new ClockSyncRecord('monotonic',ts,{perfTS:ts,parentTS:event[1]*1000}));return true;},traceMarkingWriteEvent:function(eventName,cpuNumber,pid,ts,eventBase,threadName){eventBase.details=eventBase.details.replace(/\\n.*$/,'');var event=/^\s*(\w+):\s*(.*)$/.exec(eventBase.details);if(!event){var tag=eventBase.details.substring(0,2);if(tag=='B|'||tag=='E'||tag=='E|'||tag=='X|'||tag=='C|'||tag=='S|'||tag=='F|'){eventBase.subEventName='android';}else{return false;}}else{eventBase.subEventName=event[1];eventBase.details=event[2];}
+var writeEventName=eventName+':'+eventBase.subEventName;var handler=this.eventHandlers_[writeEventName];if(!handler){this.model_.importWarning({type:'parse_error',message:'Unknown trace_marking_write event '+writeEventName});return true;}
+return handler(writeEventName,cpuNumber,pid,ts,eventBase,threadName);},importClockSyncRecords:function(){this.forEachLine(function(text,eventBase,cpuNumber,pid,ts){var eventName=eventBase.eventName;if(eventName!=='tracing_mark_write'&&eventName!=='0')
+return;if(traceEventClockSyncRE.exec(eventBase.details))
+this.traceClockSyncEvent(eventName,cpuNumber,pid,ts,eventBase);if(realTimeClockSyncRE.exec(eventBase.details)){var match=realTimeClockSyncRE.exec(eventBase.details);this.model_.realtime_to_monotonic_offset_ms=ts-match[1];}
+if(genericClockSyncRE.exec(eventBase.details))
+this.traceClockSyncEvent(eventName,cpuNumber,pid,ts,eventBase);}.bind(this));},addClockSyncRecord:function(csr){this.newlyAddedClockSyncRecords_.push(csr);this.model_.clockSyncRecords.push(csr);},shiftNewlyAddedClockSyncRecords:function(timeShift){this.newlyAddedClockSyncRecords_.forEach(function(csr){csr.ts+=timeShift;});},importCpuData:function(timeShift){this.forEachLine(function(text,eventBase,cpuNumber,pid,ts){var eventName=eventBase.eventName;var handler=this.eventHandlers_[eventName];if(!handler){this.model_.importWarning({type:'parse_error',message:'Unknown event '+eventName+' ('+text+')'});return;}
+ts+=timeShift;if(!handler(eventName,cpuNumber,pid,ts,eventBase)){this.model_.importWarning({type:'parse_error',message:'Malformed '+eventName+' event ('+text+')'});}}.bind(this));},parseLines:function(){var lines=[];var extractResult=LinuxPerfImporter._extractEventsFromSystraceHTML(this.events_,true);if(!extractResult.ok)
+extractResult=LinuxPerfImporter._extractEventsFromSystraceMultiHTML(this.events_,true);var lines=extractResult.ok?extractResult.lines:this.events_.split('\n');var lineParser=null;for(var lineNumber=0;lineNumber<lines.length;++lineNumber){var line=lines[lineNumber].trim();if(line.length==0||/^#/.test(line))
+continue;if(lineParser==null){lineParser=autoDetectLineParser(line);if(lineParser==null){this.model_.importWarning({type:'parse_error',message:'Cannot parse line: '+line});continue;}}
+var eventBase=lineParser(line);if(!eventBase){this.model_.importWarning({type:'parse_error',message:'Unrecognized line: '+line});continue;}
+this.lines_.push([line,eventBase,parseInt(eventBase.cpuNumber),parseInt(eventBase.pid),parseFloat(eventBase.timestamp)*1000]);}},forEachLine:function(handler){for(var i=0;i<this.lines_.length;++i){var line=this.lines_[i];handler.apply(this,line);}}};tr.importer.Importer.register(LinuxPerfImporter);return{LinuxPerfImporter:LinuxPerfImporter,_LinuxPerfImporterTestExports:TestExports};});'use strict';tr.exportTo('tr.b.u',function(){function TimeDuration(duration){tr.b.u.Scalar.call(this,duration,tr.b.u.Units.timeDurationInMs);};TimeDuration.prototype={__proto__:tr.b.u.Scalar.prototype,get duration(){return this.value;}};TimeDuration.format=function(duration){return tr.b.u.Units.timeDurationInMs.format(duration);};return{TimeDuration:TimeDuration};});'use strict';tr.exportTo('tr.b',function(){function convertEventsToRanges(events){return events.map(function(event){return tr.b.Range.fromExplicitRange(event.start,event.end);});}
+function mergeRanges(inRanges,mergeThreshold,mergeFunction){var remainingEvents=inRanges.slice();remainingEvents.sort(function(x,y){return x.min-y.min;});if(remainingEvents.length<=1){var merged=[];if(remainingEvents.length==1){merged.push(mergeFunction(remainingEvents));}
+return merged;}
+var mergedEvents=[];var currentMergeBuffer=[];var rightEdge;function beginMerging(){currentMergeBuffer.push(remainingEvents[0]);remainingEvents.splice(0,1);rightEdge=currentMergeBuffer[0].max;}
+function flushCurrentMergeBuffer(){if(currentMergeBuffer.length==0)
+return;mergedEvents.push(mergeFunction(currentMergeBuffer));currentMergeBuffer=[];if(remainingEvents.length!=0)
+beginMerging();}
+beginMerging();while(remainingEvents.length){var currentEvent=remainingEvents[0];var distanceFromRightEdge=currentEvent.min-rightEdge;if(distanceFromRightEdge<mergeThreshold){rightEdge=Math.max(rightEdge,currentEvent.max);remainingEvents.splice(0,1);currentMergeBuffer.push(currentEvent);continue;}
+flushCurrentMergeBuffer();}
+flushCurrentMergeBuffer();return mergedEvents;}
+function findEmptyRangesBetweenRanges(inRanges,opt_totalRange){if(opt_totalRange&&opt_totalRange.isEmpty)
+opt_totalRange=undefined;var emptyRanges=[];if(!inRanges.length){if(opt_totalRange)
+emptyRanges.push(opt_totalRange);return emptyRanges;}
+inRanges=inRanges.slice();inRanges.sort(function(x,y){return x.min-y.min;});if(opt_totalRange&&(opt_totalRange.min<inRanges[0].min)){emptyRanges.push(tr.b.Range.fromExplicitRange(opt_totalRange.min,inRanges[0].min));}
+inRanges.forEach(function(range,index){for(var otherIndex=0;otherIndex<inRanges.length;++otherIndex){if(index===otherIndex)
+continue;var other=inRanges[otherIndex];if(other.min>range.max){emptyRanges.push(tr.b.Range.fromExplicitRange(range.max,other.min));return;}
+if(other.max>range.max){return;}}
+if(opt_totalRange&&(range.max<opt_totalRange.max)){emptyRanges.push(tr.b.Range.fromExplicitRange(range.max,opt_totalRange.max));}});return emptyRanges;}
+return{convertEventsToRanges:convertEventsToRanges,findEmptyRangesBetweenRanges:findEmptyRangesBetweenRanges,mergeRanges:mergeRanges};});'use strict';tr.exportTo('tr.e.audits',function(){var Frame=tr.model.Frame;var Statistics=tr.b.Statistics;var UI_DRAW_TYPE={NONE:'none',LEGACY:'legacy',MARSHMALLOW:'marshmallow'};var UI_THREAD_DRAW_NAMES={'performTraversals':UI_DRAW_TYPE.LEGACY,'Choreographer#doFrame':UI_DRAW_TYPE.MARSHMALLOW};var RENDER_THREAD_DRAW_NAME='DrawFrame';var RENDER_THREAD_INDEP_DRAW_NAME='doFrame';var THREAD_SYNC_NAME='syncFrameState';function getSlicesForThreadTimeRanges(threadTimeRanges){var ret=[];threadTimeRanges.forEach(function(threadTimeRange){var slices=[];threadTimeRange.thread.sliceGroup.iterSlicesInTimeRange(function(slice){slices.push(slice);},threadTimeRange.start,threadTimeRange.end);ret.push.apply(ret,slices);});return ret;}
+function makeFrame(threadTimeRanges,surfaceFlinger){var args={};if(surfaceFlinger&&surfaceFlinger.hasVsyncs){var start=Statistics.min(threadTimeRanges,function(threadTimeRanges){return threadTimeRanges.start;});args['deadline']=surfaceFlinger.getFrameDeadline(start);args['frameKickoff']=surfaceFlinger.getFrameKickoff(start);}
+var events=getSlicesForThreadTimeRanges(threadTimeRanges);return new Frame(events,threadTimeRanges,args);}
+function findOverlappingDrawFrame(renderThread,time){if(!renderThread)
+return undefined;var slices=renderThread.sliceGroup.slices;for(var i=0;i<slices.length;i++){var slice=slices[i];if(slice.title==RENDER_THREAD_DRAW_NAME&&slice.start<=time&&time<=slice.end){return slice;}}
+return undefined;}
+function getPreTraversalWorkRanges(uiThread){if(!uiThread)
+return[];var preFrameEvents=[];uiThread.sliceGroup.slices.forEach(function(slice){if(slice.title=='obtainView'||slice.title=='setupListItem'||slice.title=='deliverInputEvent'||slice.title=='RV Scroll')
+preFrameEvents.push(slice);});uiThread.asyncSliceGroup.slices.forEach(function(slice){if(slice.title=='deliverInputEvent')
+preFrameEvents.push(slice);});return tr.b.mergeRanges(tr.b.convertEventsToRanges(preFrameEvents),3,function(events){return{start:events[0].min,end:events[events.length-1].max};});}
+function getFrameStartTime(traversalStart,preTraversalWorkRanges){var preTraversalWorkRange=tr.b.findClosestIntervalInSortedIntervals(preTraversalWorkRanges,function(range){return range.start},function(range){return range.end},traversalStart,3);if(preTraversalWorkRange)
+return preTraversalWorkRange.start;return traversalStart;}
+function getUiThreadDrivenFrames(app){if(!app.uiThread)
+return[];var preTraversalWorkRanges=[];if(app.uiDrawType==UI_DRAW_TYPE.LEGACY)
+preTraversalWorkRanges=getPreTraversalWorkRanges(app.uiThread);var frames=[];app.uiThread.sliceGroup.slices.forEach(function(slice){if(!(slice.title in UI_THREAD_DRAW_NAMES)){return;}
+var threadTimeRanges=[];var uiThreadTimeRange={thread:app.uiThread,start:getFrameStartTime(slice.start,preTraversalWorkRanges),end:slice.end};threadTimeRanges.push(uiThreadTimeRange);var rtDrawSlice=findOverlappingDrawFrame(app.renderThread,slice.end);if(rtDrawSlice){var rtSyncSlice=rtDrawSlice.findDescendentSlice(THREAD_SYNC_NAME);if(rtSyncSlice){uiThreadTimeRange.end=Math.min(uiThreadTimeRange.end,rtSyncSlice.start);}
+threadTimeRanges.push({thread:app.renderThread,start:rtDrawSlice.start,end:rtDrawSlice.end});}
+frames.push(makeFrame(threadTimeRanges,app.surfaceFlinger));});return frames;}
+function getRenderThreadDrivenFrames(app){if(!app.renderThread)
+return[];var frames=[];app.renderThread.sliceGroup.getSlicesOfName(RENDER_THREAD_INDEP_DRAW_NAME).forEach(function(slice){var threadTimeRanges=[{thread:app.renderThread,start:slice.start,end:slice.end}];frames.push(makeFrame(threadTimeRanges,app.surfaceFlinger));});return frames;}
+function getUiDrawType(uiThread){if(!uiThread)
+return UI_DRAW_TYPE.NONE;var slices=uiThread.sliceGroup.slices;for(var i=0;i<slices.length;i++){if(slices[i].title in UI_THREAD_DRAW_NAMES){return UI_THREAD_DRAW_NAMES[slices[i].title];}}
+return UI_DRAW_TYPE.NONE;}
+function getInputSamples(process){var samples=undefined;for(var counterName in process.counters){if(/^android\.aq\:pending/.test(counterName)&&process.counters[counterName].numSeries==1){samples=process.counters[counterName].series[0].samples;break;}}
+if(!samples)
+return[];var inputSamples=[];var lastValue=0;samples.forEach(function(sample){if(sample.value>lastValue){inputSamples.push(sample);}
+lastValue=sample.value;});return inputSamples;}
+function getAnimationAsyncSlices(uiThread){if(!uiThread)
+return[];var slices=[];uiThread.asyncSliceGroup.iterateAllEvents(function(slice){if(/^animator\:/.test(slice.title))
+slices.push(slice);});return slices;}
+function AndroidApp(process,uiThread,renderThread,surfaceFlinger,uiDrawType){this.process=process;this.uiThread=uiThread;this.renderThread=renderThread;this.surfaceFlinger=surfaceFlinger;this.uiDrawType=uiDrawType;this.frames_=undefined;this.inputs_=undefined;};AndroidApp.createForProcessIfPossible=function(process,surfaceFlinger){var uiThread=process.getThread(process.pid);var uiDrawType=getUiDrawType(uiThread);if(uiDrawType==UI_DRAW_TYPE.NONE){uiThread=undefined;}
+var renderThreads=process.findAllThreadsNamed('RenderThread');var renderThread=renderThreads.length==1?renderThreads[0]:undefined;if(uiThread||renderThread){return new AndroidApp(process,uiThread,renderThread,surfaceFlinger,uiDrawType);}}
+AndroidApp.prototype={getFrames:function(){if(!this.frames_){var uiFrames=getUiThreadDrivenFrames(this);var rtFrames=getRenderThreadDrivenFrames(this);this.frames_=uiFrames.concat(rtFrames);this.frames_.sort(function(a,b){a.end-b.end});}
+return this.frames_;},getInputSamples:function(){if(!this.inputs_){this.inputs_=getInputSamples(this.process);}
+return this.inputs_;},getAnimationAsyncSlices:function(){if(!this.animations_){this.animations_=getAnimationAsyncSlices(this.uiThread);}
+return this.animations_;}};return{AndroidApp:AndroidApp};});'use strict';tr.exportTo('tr.e.audits',function(){var findLowIndexInSortedArray=tr.b.findLowIndexInSortedArray;var VSYNC_SF_NAME='android.VSYNC-sf';var VSYNC_APP_NAME='android.VSYNC-app';var VSYNC_FALLBACK_NAME='android.VSYNC';var TIMESTAMP_FUDGE_MS=0.01;function getVsyncTimestamps(process,counterName){var vsync=process.counters[counterName];if(!vsync)
+vsync=process.counters[VSYNC_FALLBACK_NAME];if(vsync&&vsync.numSeries==1&&vsync.numSamples>1)
+return vsync.series[0].timestamps;return undefined;}
+function AndroidSurfaceFlinger(process,thread){this.process=process;this.thread=thread;this.appVsync_=undefined;this.sfVsync_=undefined;this.appVsyncTimestamps_=getVsyncTimestamps(process,VSYNC_APP_NAME);this.sfVsyncTimestamps_=getVsyncTimestamps(process,VSYNC_SF_NAME);};AndroidSurfaceFlinger.createForProcessIfPossible=function(process){var mainThread=process.getThread(process.pid);if(mainThread&&mainThread.name&&/surfaceflinger/.test(mainThread.name))
+return new AndroidSurfaceFlinger(process,mainThread);var primaryThreads=process.findAllThreadsNamed('SurfaceFlinger');if(primaryThreads.length==1)
+return new AndroidSurfaceFlinger(process,primaryThreads[0]);return undefined;};AndroidSurfaceFlinger.prototype={get hasVsyncs(){return!!this.appVsyncTimestamps_&&!!this.sfVsyncTimestamps_;},getFrameKickoff:function(timestamp){if(!this.hasVsyncs)
+throw new Error('cannot query vsync info without vsyncs');var firstGreaterIndex=findLowIndexInSortedArray(this.appVsyncTimestamps_,function(x){return x;},timestamp+TIMESTAMP_FUDGE_MS);if(firstGreaterIndex<1)
+return undefined;return this.appVsyncTimestamps_[firstGreaterIndex-1];},getFrameDeadline:function(timestamp){if(!this.hasVsyncs)
+throw new Error('cannot query vsync info without vsyncs');var firstGreaterIndex=findLowIndexInSortedArray(this.sfVsyncTimestamps_,function(x){return x;},timestamp+TIMESTAMP_FUDGE_MS);if(firstGreaterIndex>=this.sfVsyncTimestamps_.length)
+return undefined;return this.sfVsyncTimestamps_[firstGreaterIndex];}};return{AndroidSurfaceFlinger:AndroidSurfaceFlinger};});'use strict';tr.exportTo('tr.e.audits',function(){var AndroidApp=tr.e.audits.AndroidApp;var AndroidSurfaceFlinger=tr.e.audits.AndroidSurfaceFlinger;var IMPORTANT_SURFACE_FLINGER_SLICES={'doComposition':true,'updateTexImage':true,'postFramebuffer':true};var IMPORTANT_UI_THREAD_SLICES={'Choreographer#doFrame':true,'performTraversals':true,'deliverInputEvent':true};var IMPORTANT_RENDER_THREAD_SLICES={'doFrame':true};function iterateImportantThreadSlices(thread,important,callback){if(!thread)
+return;thread.sliceGroup.slices.forEach(function(slice){if(slice.title in important)
+callback(slice);});}
+function AndroidModelHelper(model){this.model=model;this.apps=[];this.surfaceFlinger=undefined;var processes=model.getAllProcesses();for(var i=0;i<processes.length&&!this.surfaceFlinger;i++){this.surfaceFlinger=AndroidSurfaceFlinger.createForProcessIfPossible(processes[i]);}
+model.getAllProcesses().forEach(function(process){var app=AndroidApp.createForProcessIfPossible(process,this.surfaceFlinger);if(app)
+this.apps.push(app);},this);};AndroidModelHelper.prototype={iterateImportantSlices:function(callback){if(this.surfaceFlinger){iterateImportantThreadSlices(this.surfaceFlinger.thread,IMPORTANT_SURFACE_FLINGER_SLICES,callback);}
+this.apps.forEach(function(app){iterateImportantThreadSlices(app.uiThread,IMPORTANT_UI_THREAD_SLICES,callback);iterateImportantThreadSlices(app.renderThread,IMPORTANT_RENDER_THREAD_SLICES,callback);});}};return{AndroidModelHelper:AndroidModelHelper};});'use strict';tr.exportTo('tr.e.audits',function(){var SCHEDULING_STATE=tr.model.SCHEDULING_STATE;var Auditor=tr.c.Auditor;var AndroidModelHelper=tr.e.audits.AndroidModelHelper;var ColorScheme=tr.b.ColorScheme;var Statistics=tr.b.Statistics;var FRAME_PERF_CLASS=tr.model.FRAME_PERF_CLASS;var InteractionRecord=tr.model.InteractionRecord;var Alert=tr.model.Alert;var EventInfo=tr.model.EventInfo;var TimeDuration=tr.b.u.TimeDuration;var EXPECTED_FRAME_TIME_MS=16.67;function getStart(e){return e.start;}
+function getDuration(e){return e.duration;}
+function getCpuDuration(e){return(e.cpuDuration!==undefined)?e.cpuDuration:e.duration;}
+function frameIsActivityStart(frame){for(var i=0;i<frame.associatedEvents.length;i++){if(frame.associatedEvents[i].title=='activityStart')
+return true;}
+return false;}
+var Auditor=tr.c.Auditor;var AndroidModelHelper=tr.e.audits.AndroidModelHelper;function frameMissedDeadline(frame){return frame.args['deadline']&&frame.args['deadline']<frame.end;}
+function DocLinkBuilder(){this.docLinks=[];}
+DocLinkBuilder.prototype={addAppVideo:function(name,videoId){this.docLinks.push({label:'Video Link',textContent:('Android Performance Patterns: '+name),href:'https://www.youtube.com/watch?list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE&v='+videoId});return this;},addDacRef:function(name,link){this.docLinks.push({label:'Doc Link',textContent:(name+' documentation'),href:'https://developer.android.com/reference/'+link});return this;},build:function(){return this.docLinks;}};function AndroidAuditor(model){Auditor.call(this,model);var helper=new AndroidModelHelper(model);if(helper.apps.length||helper.surfaceFlinger)
+this.helper=helper;};AndroidAuditor.viewAlphaAlertInfo_=new EventInfo('Inefficient View alpha usage','Setting an alpha between 0 and 1 has significant performance costs, if one of the fast alpha paths is not used.',new DocLinkBuilder().addAppVideo('Hidden Cost of Transparency','wIy8g8yNhNk').addDacRef('View#setAlpha()','android/view/View.html#setAlpha(float)').build());AndroidAuditor.saveLayerAlertInfo_=new EventInfo('Expensive rendering with Canvas#saveLayer()','Canvas#saveLayer() incurs extremely high rendering cost. They disrupt the rendering pipeline when drawn, forcing a flush of drawing content. Instead use View hardware layers, or static Bitmaps. This enables the offscreen buffers to be reused in between frames, and avoids the disruptive render target switch.',new DocLinkBuilder().addAppVideo('Hidden Cost of Transparency','wIy8g8yNhNk').addDacRef('Canvas#saveLayerAlpha()','android/graphics/Canvas.html#saveLayerAlpha(android.graphics.RectF, int, int)').build());AndroidAuditor.getSaveLayerAlerts_=function(frame){var badAlphaRegEx=/^(.+) alpha caused (unclipped )?saveLayer (\d+)x(\d+)$/;var saveLayerRegEx=/^(unclipped )?saveLayer (\d+)x(\d+)$/;var ret=[];var events=[];frame.associatedEvents.forEach(function(slice){var match=badAlphaRegEx.exec(slice.title);if(match){var args={'view name':match[1],width:parseInt(match[3]),height:parseInt(match[4])};ret.push(new Alert(AndroidAuditor.viewAlphaAlertInfo_,slice.start,[slice],args));}else if(saveLayerRegEx.test(slice.title))
+events.push(slice);},this);if(events.length>ret.length){var unclippedSeen=Statistics.sum(events,function(slice){return saveLayerRegEx.exec(slice.title)[1]?1:0;});var clippedSeen=events.length-unclippedSeen;var earliestStart=Statistics.min(events,function(slice){return slice.start;});var args={'Unclipped saveLayer count (especially bad!)':unclippedSeen,'Clipped saveLayer count':clippedSeen};events.push(frame);ret.push(new Alert(AndroidAuditor.saveLayerAlertInfo_,earliestStart,events,args));}
+return ret;};AndroidAuditor.pathAlertInfo_=new EventInfo('Path texture churn','Paths are drawn with a mask texture, so when a path is modified / newly drawn, that texture must be generated and uploaded to the GPU. Ensure that you cache paths between frames and do not unnecessarily call Path#reset(). You can cut down on this cost by sharing Path object instances between drawables/views.');AndroidAuditor.getPathAlert_=function(frame){var uploadRegEx=/^Generate Path Texture$/;var events=frame.associatedEvents.filter(function(event){return event.title=='Generate Path Texture';});var start=Statistics.min(events,getStart);var duration=Statistics.sum(events,getDuration);if(duration<3)
+return undefined;events.push(frame);return new Alert(AndroidAuditor.pathAlertInfo_,start,events,{'Time spent':new TimeDuration(duration)});}
+AndroidAuditor.uploadAlertInfo_=new EventInfo('Expensive Bitmap uploads','Bitmaps that have been modified / newly drawn must be uploaded to the GPU. Since this is expensive if the total number of pixels uploaded is large, reduce the amount of Bitmap churn in this animation/context, per frame.');AndroidAuditor.getUploadAlert_=function(frame){var uploadRegEx=/^Upload (\d+)x(\d+) Texture$/;var events=[];var start=Number.POSITIVE_INFINITY;var duration=0;var pixelsUploaded=0;frame.associatedEvents.forEach(function(event){var match=uploadRegEx.exec(event.title);if(match){events.push(event);start=Math.min(start,event.start);duration+=event.duration;pixelsUploaded+=parseInt(match[1])*parseInt(match[2]);}});if(events.length==0||duration<3)
+return undefined;var mPixels=(pixelsUploaded/1000000).toFixed(2)+' million';var args={'Pixels uploaded':mPixels,'Time spent':new TimeDuration(duration)};events.push(frame);return new Alert(AndroidAuditor.uploadAlertInfo_,start,events,args);}
+AndroidAuditor.ListViewInflateAlertInfo_=new EventInfo('Inflation during ListView recycling','ListView item recycling involved inflating views. Ensure your Adapter#getView() recycles the incoming View, instead of constructing a new one.');AndroidAuditor.ListViewBindAlertInfo_=new EventInfo('Inefficient ListView recycling/rebinding','ListView recycling taking too much time per frame. Ensure your Adapter#getView() binds data efficiently.');AndroidAuditor.getListViewAlert_=function(frame){var events=frame.associatedEvents.filter(function(event){return event.title=='obtainView'||event.title=='setupListItem';});var duration=Statistics.sum(events,getCpuDuration);if(events.length==0||duration<3)
+return undefined;var hasInflation=false;for(var i=0;i<events.length;i++){if(events[i]instanceof tr.model.Slice&&events[i].findDescendentSlice('inflate')){hasInflation=true;break;}}
+var start=Statistics.min(events,getStart);var args={'Time spent':new TimeDuration(duration)};args['ListView items '+(hasInflation?'inflated':'rebound')]=events.length/2;var eventInfo=hasInflation?AndroidAuditor.ListViewInflateAlertInfo_:AndroidAuditor.ListViewBindAlertInfo_;events.push(frame);return new Alert(eventInfo,start,events,args);}
+AndroidAuditor.measureLayoutAlertInfo_=new EventInfo('Expensive measure/layout pass','Measure/Layout took a significant time, contributing to jank. Avoid triggering layout during animations.',new DocLinkBuilder().addAppVideo('Invalidations, Layouts, and Performance','we6poP0kw6E').build());AndroidAuditor.getMeasureLayoutAlert_=function(frame){var events=frame.associatedEvents.filter(function(event){return event.title=='measure'||event.title=='layout';});var duration=Statistics.sum(events,getCpuDuration);if(events.length==0||duration<3)
+return undefined;var start=Statistics.min(events,getStart);events.push(frame);return new Alert(AndroidAuditor.measureLayoutAlertInfo_,start,events,{'Time spent':new TimeDuration(duration)});}
+AndroidAuditor.viewDrawAlertInfo_=new EventInfo('Long View#draw()','Recording the drawing commands of invalidated Views took a long time. Avoid significant work in View or Drawable custom drawing, especially allocations or drawing to Bitmaps.',new DocLinkBuilder().addAppVideo('Invalidations, Layouts, and Performance','we6poP0kw6E').addAppVideo('Avoiding Allocations in onDraw()','HAK5acHQ53E').build());AndroidAuditor.getViewDrawAlert_=function(frame){var slice=undefined;for(var i=0;i<frame.associatedEvents.length;i++){if(frame.associatedEvents[i].title=='getDisplayList'||frame.associatedEvents[i].title=='Record View#draw()'){slice=frame.associatedEvents[i];break;}}
+if(!slice||getCpuDuration(slice)<3)
+return undefined;return new Alert(AndroidAuditor.viewDrawAlertInfo_,slice.start,[slice,frame],{'Time spent':new TimeDuration(getCpuDuration(slice))});}
+AndroidAuditor.blockingGcAlertInfo_=new EventInfo('Blocking Garbage Collection','Blocking GCs are caused by object churn, and made worse by having large numbers of objects in the heap. Avoid allocating objects during animations/scrolling, and recycle Bitmaps to avoid triggering garbage collection.',new DocLinkBuilder().addAppVideo('Garbage Collection in Android','pzfzz50W5Uo').addAppVideo('Avoiding Allocations in onDraw()','HAK5acHQ53E').build());AndroidAuditor.getBlockingGcAlert_=function(frame){var events=frame.associatedEvents.filter(function(event){return event.title=='DVM Suspend'||event.title=='GC: Wait For Concurrent';});var blockedDuration=Statistics.sum(events,getDuration);if(blockedDuration<3)
+return undefined;var start=Statistics.min(events,getStart);events.push(frame);return new Alert(AndroidAuditor.blockingGcAlertInfo_,start,events,{'Blocked duration':new TimeDuration(blockedDuration)});};AndroidAuditor.lockContentionAlertInfo_=new EventInfo('Lock contention','UI thread lock contention is caused when another thread holds a lock that the UI thread is trying to use. UI thread progress is blocked until the lock is released. Inspect locking done within the UI thread, and ensure critical sections are short.');AndroidAuditor.getLockContentionAlert_=function(frame){var events=frame.associatedEvents.filter(function(event){return/^Lock Contention on /.test(event.title);});var blockedDuration=Statistics.sum(events,getDuration);if(blockedDuration<1)
+return undefined;var start=Statistics.min(events,getStart);events.push(frame);return new Alert(AndroidAuditor.lockContentionAlertInfo_,start,events,{'Blocked duration':new TimeDuration(blockedDuration)});};AndroidAuditor.schedulingAlertInfo_=new EventInfo('Scheduling delay','Work to produce this frame was descheduled for several milliseconds, contributing to jank. Ensure that code on the UI thread doesn\'t block on work being done on other threads, and that background threads (doing e.g. network or bitmap loading) are running at android.os.Process#THREAD_PRIORITY_BACKGROUND or lower so they are less likely to interrupt the UI thread. These background threads should show up with a priority number of 130 or higher in the scheduling section under the Kernel process.');AndroidAuditor.getSchedulingAlert_=function(frame){var totalDuration=0;var totalStats={};frame.threadTimeRanges.forEach(function(ttr){var stats=ttr.thread.getSchedulingStatsForRange(ttr.start,ttr.end);tr.b.iterItems(stats,function(key,value){if(!(key in totalStats))
+totalStats[key]=0;totalStats[key]+=value;totalDuration+=value;});});if(!(SCHEDULING_STATE.RUNNING in totalStats)||totalDuration==0||totalDuration-totalStats[SCHEDULING_STATE.RUNNING]<3)
+return;var args={};tr.b.iterItems(totalStats,function(key,value){if(key===SCHEDULING_STATE.RUNNABLE)
+key='Not scheduled, but runnable';else if(key===SCHEDULING_STATE.UNINTR_SLEEP)
+key='Blocking I/O delay';args[key]=new TimeDuration(value);});return new Alert(AndroidAuditor.schedulingAlertInfo_,frame.start,[frame],args);};AndroidAuditor.prototype={__proto__:Auditor.prototype,renameAndSort_:function(){this.model.kernel.important=false;this.model.getAllProcesses().forEach(function(process){if(this.helper.surfaceFlinger&&process==this.helper.surfaceFlinger.process){if(!process.name)
+process.name='SurfaceFlinger';process.sortIndex=Number.NEGATIVE_INFINITY;process.important=false;return;}
+var uiThread=process.getThread(process.pid);if(!process.name&&uiThread&&uiThread.name){if(/^ndroid\./.test(uiThread.name))
+uiThread.name='a'+uiThread.name;process.name=uiThread.name;uiThread.name='UI Thread';}
+process.sortIndex=0;for(var tid in process.threads){process.sortIndex-=process.threads[tid].sliceGroup.slices.length;}},this);this.model.getAllThreads().forEach(function(thread){if(thread.tid==thread.parent.pid)
+thread.sortIndex=-3;if(thread.name=='RenderThread')
+thread.sortIndex=-2;if(/^hwuiTask/.test(thread.name))
+thread.sortIndex=-1;});},pushFramesAndJudgeJank_:function(){var badFramesObserved=0;var framesObserved=0;var surfaceFlinger=this.helper.surfaceFlinger;this.helper.apps.forEach(function(app){app.process.frames=app.getFrames();app.process.frames.forEach(function(frame){if(frame.totalDuration>EXPECTED_FRAME_TIME_MS*2){badFramesObserved+=2;frame.perfClass=FRAME_PERF_CLASS.TERRIBLE;}else if(frame.totalDuration>EXPECTED_FRAME_TIME_MS||frameMissedDeadline(frame)){badFramesObserved++;frame.perfClass=FRAME_PERF_CLASS.BAD;}else{frame.perfClass=FRAME_PERF_CLASS.GOOD;}});framesObserved+=app.process.frames.length;});if(framesObserved){var portionBad=badFramesObserved/framesObserved;if(portionBad>0.3)
+this.model.faviconHue='red';else if(portionBad>0.05)
+this.model.faviconHue='yellow';else
+this.model.faviconHue='green';}},pushEventInfo_:function(){var appAnnotator=new AppAnnotator();this.helper.apps.forEach(function(app){if(app.uiThread)
+appAnnotator.applyEventInfos(app.uiThread.sliceGroup);if(app.renderThread)
+appAnnotator.applyEventInfos(app.renderThread.sliceGroup);});},runAnnotate:function(){if(!this.helper)
+return;this.renameAndSort_();this.pushFramesAndJudgeJank_();this.pushEventInfo_();this.helper.iterateImportantSlices(function(slice){slice.important=true;});},runAudit:function(){if(!this.helper)
+return;var alerts=this.model.alerts;this.helper.apps.forEach(function(app){app.getFrames().forEach(function(frame){alerts.push.apply(alerts,AndroidAuditor.getSaveLayerAlerts_(frame));if(frame.perfClass==FRAME_PERF_CLASS.NEUTRAL||frame.perfClass==FRAME_PERF_CLASS.GOOD)
+return;var alert=AndroidAuditor.getPathAlert_(frame);if(alert)
+alerts.push(alert);var alert=AndroidAuditor.getUploadAlert_(frame);if(alert)
+alerts.push(alert);var alert=AndroidAuditor.getListViewAlert_(frame);if(alert)
+alerts.push(alert);var alert=AndroidAuditor.getMeasureLayoutAlert_(frame);if(alert)
+alerts.push(alert);var alert=AndroidAuditor.getViewDrawAlert_(frame);if(alert)
+alerts.push(alert);var alert=AndroidAuditor.getBlockingGcAlert_(frame);if(alert)
+alerts.push(alert);var alert=AndroidAuditor.getLockContentionAlert_(frame);if(alert)
+alerts.push(alert);var alert=AndroidAuditor.getSchedulingAlert_(frame);if(alert)
+alerts.push(alert);});},this);this.addRenderingInteractionRecords();this.addInputInteractionRecords();},addRenderingInteractionRecords:function(){var events=[];this.helper.apps.forEach(function(app){events.push.apply(events,app.getAnimationAsyncSlices());events.push.apply(events,app.getFrames());});var mergerFunction=function(events){var ir=new InteractionRecord(this.model,'Rendering',ColorScheme.getColorIdForGeneralPurposeString('mt_rendering'),events[0].min,events[events.length-1].max-events[0].min);this.model.addInteractionRecord(ir);}.bind(this);tr.b.mergeRanges(tr.b.convertEventsToRanges(events),30,mergerFunction);},addInputInteractionRecords:function(){var inputSamples=[];this.helper.apps.forEach(function(app){inputSamples.push.apply(inputSamples,app.getInputSamples());});var mergerFunction=function(events){var ir=new InteractionRecord(this.model,'Input',ColorScheme.getColorIdForGeneralPurposeString('mt_input'),events[0].min,events[events.length-1].max-events[0].min);this.model.addInteractionRecord(ir);}.bind(this);var inputRanges=inputSamples.map(function(sample){return tr.b.Range.fromExplicitRange(sample.timestamp,sample.timestamp);});tr.b.mergeRanges(inputRanges,30,mergerFunction);}};Auditor.register(AndroidAuditor);function AppAnnotator(){this.titleInfoLookup={};this.titleParentLookup={};this.build_();}
+AppAnnotator.prototype={build_:function(){var registerEventInfo=function(dict){this.titleInfoLookup[dict.title]=new EventInfo(dict.title,dict.description,dict.docLinks);if(dict.parents)
+this.titleParentLookup[dict.title]=dict.parents;}.bind(this);registerEventInfo({title:'inflate',description:'Constructing a View hierarchy from pre-processed XML via LayoutInflater#layout. This includes constructing all of the View objects in the hierarchy, and applying styled attributes.'});registerEventInfo({title:'obtainView',description:'Adapter#getView() called to bind content to a recycled View that is being presented.'});registerEventInfo({title:'setupListItem',description:'Attached a newly-bound, recycled View to its parent ListView.'});registerEventInfo({title:'setupGridItem',description:'Attached a newly-bound, recycled View to its parent GridView.'});var choreographerLinks=new DocLinkBuilder().addDacRef('Choreographer','android/view/Choreographer.html').build();registerEventInfo({title:'Choreographer#doFrame',docLinks:choreographerLinks,description:'Choreographer executes frame callbacks for inputs, animations, and rendering traversals. When this work is done, a frame will be presented to the user.'});registerEventInfo({title:'input',parents:['Choreographer#doFrame'],docLinks:choreographerLinks,description:'Input callbacks are processed. This generally encompasses dispatching input to Views, as well as any work the Views do to process this input/gesture.'});registerEventInfo({title:'animation',parents:['Choreographer#doFrame'],docLinks:choreographerLinks,description:'Animation callbacks are processed. This is generally minimal work, as animations determine progress for the frame, and push new state to animated objects (such as setting View properties).'});registerEventInfo({title:'traversals',parents:['Choreographer#doFrame'],docLinks:choreographerLinks,description:'Primary draw traversals. This is the primary traversal of the View hierarchy, including layout and draw passes.'});var traversalParents=['Choreographer#doFrame','performTraversals'];var layoutLinks=new DocLinkBuilder().addDacRef('View#Layout','android/view/View.html#Layout').build();registerEventInfo({title:'performTraversals',description:'A drawing traversal of the View hierarchy, comprised of all layout and drawing needed to produce the frame.'});registerEventInfo({title:'measure',parents:traversalParents,docLinks:layoutLinks,description:'First of two phases in view hierarchy layout. Views are asked to size themselves according to constraints supplied by their parent. Some ViewGroups may measure a child more than once to help satisfy their own constraints. Nesting ViewGroups that measure children more than once can lead to excessive and repeated work.'});registerEventInfo({title:'layout',parents:traversalParents,docLinks:layoutLinks,description:'Second of two phases in view hierarchy layout, repositioning content and child Views into their new locations.'});var drawString='Draw pass over the View hierarchy. Every invalidated View will have its drawing commands recorded. On Android versions prior to Lollipop, this would also include the issuing of draw commands to the GPU. Starting with Lollipop, it only includes the recording of commands, and syncing that information to the RenderThread.';registerEventInfo({title:'draw',parents:traversalParents,description:drawString});var recordString='Every invalidated View\'s drawing commands are recorded. Each will have View#draw() called, and is passed a Canvas that will record and store its drawing commands until it is next invalidated/rerecorded.';registerEventInfo({title:'getDisplayList',parents:['draw'],description:recordString});registerEventInfo({title:'Record View#draw()',parents:['draw'],description:recordString});registerEventInfo({title:'drawDisplayList',parents:['draw'],description:'Execution of recorded draw commands to generate a frame. This represents the actual formation and issuing of drawing commands to the GPU. On Android L and higher devices, this work is done on a dedicated RenderThread, instead of on the UI Thread.'});registerEventInfo({title:'DrawFrame',description:'RenderThread portion of the standard UI/RenderThread split frame. This represents the actual formation and issuing of drawing commands to the GPU.'});registerEventInfo({title:'doFrame',description:'RenderThread animation frame. Represents drawing work done by the RenderThread on a frame where the UI thread did not produce new drawing content.'});registerEventInfo({title:'syncFrameState',description:'Sync stage between the UI thread and the RenderThread, where the UI thread hands off a frame (including information about modified Views). Time in this method primarily consists of uploading modified Bitmaps to the GPU. After this sync is completed, the UI thread is unblocked, and the RenderThread starts to render the frame.'});registerEventInfo({title:'flush drawing commands',description:'Issuing the now complete drawing commands to the GPU.'});registerEventInfo({title:'eglSwapBuffers',description:'Complete GPU rendering of the frame.'});registerEventInfo({title:'RV Scroll',description:'RecyclerView is calculating a scroll. If there are too many of these in Systrace, some Views inside RecyclerView might be causing it. Try to avoid using EditText, focusable views or handle them with care.'});registerEventInfo({title:'RV OnLayout',description:'OnLayout has been called by the View system. If this shows up too many times in Systrace, make sure the children of RecyclerView do not update themselves directly. This will cause a full re-layout but when it happens via the Adapter notifyItemChanged, RecyclerView can avoid full layout calculation.'});registerEventInfo({title:'RV FullInvalidate',description:'NotifyDataSetChanged or equal has been called. If this is taking a long time, try sending granular notify adapter changes instead of just calling notifyDataSetChanged or setAdapter / swapAdapter. Adding stable ids to your adapter might help.'});registerEventInfo({title:'RV PartialInvalidate',description:'RecyclerView is rebinding a View. If this is taking a lot of time, consider optimizing your layout or make sure you are not doing extra operations in onBindViewHolder call.'});registerEventInfo({title:'RV OnBindView',description:'RecyclerView is rebinding a View. If this is taking a lot of time, consider optimizing your layout or make sure you are not doing extra operations in onBindViewHolder call.'});registerEventInfo({title:'RV CreateView',description:'RecyclerView is creating a new View. If too many of these are present: 1) There might be a problem in Recycling (e.g. custom Animations that set transient state and prevent recycling or ItemAnimator not implementing the contract properly. See Adapter#onFailedToRecycleView(ViewHolder). 2) There may be too many item view types. Try merging them. 3) There might be too many itemChange animations and not enough space in RecyclerPool. Try increasing your pool size and item cache size.'});registerEventInfo({title:'eglSwapBuffers',description:'The CPU has finished producing drawing commands, and is flushing drawing work to the GPU, and posting that buffer to the consumer (which is often SurfaceFlinger window composition). Once this is completed, the GPU can produce the frame content without any involvement from the CPU.'});},applyEventInfosRecursive_:function(parentNames,slice){var checkExpectedParentNames=function(expectedParentNames){if(!expectedParentNames)
+return true;return expectedParentNames.some(function(name){return name in parentNames;});}
+if(slice.title in this.titleInfoLookup){if(checkExpectedParentNames(this.titleParentLookup[slice.title]))
+slice.info=this.titleInfoLookup[slice.title];}
+if(slice.subSlices.length>0){if(!(slice.title in parentNames))
+parentNames[slice.title]=0;parentNames[slice.title]++;slice.subSlices.forEach(function(subSlice){this.applyEventInfosRecursive_(parentNames,subSlice);},this);parentNames[slice.title]--;if(parentNames[slice.title]==0)
+delete parentNames[slice.title];}},applyEventInfos:function(sliceGroup){sliceGroup.topLevelSlices.forEach(function(slice){this.applyEventInfosRecursive_({},slice);},this);}};return{AndroidAuditor:AndroidAuditor};});'use strict';tr.exportTo('tr.e.audits',function(){var VSYNC_COUNTER_PRECISIONS={'android.VSYNC-app':15,'android.VSYNC':15};var VSYNC_SLICE_PRECISIONS={'RenderWidgetHostViewAndroid::OnVSync':5,'VSYNC':10,'vblank':10,'DisplayLinkMac::GetVSyncParameters':5};var BEGIN_FRAME_SLICE_PRECISION={'Scheduler::BeginFrame':10};function VSyncAuditor(model){tr.c.Auditor.call(this,model);};VSyncAuditor.prototype={__proto__:tr.c.Auditor.prototype,runAnnotate:function(){this.model.device.vSyncTimestamps=this.findVSyncTimestamps(this.model);},findVSyncTimestamps:function(model){var times=[];var maxPrecision=Number.NEGATIVE_INFINITY;var maxTitle=undefined;function useInstead(title,precisions){var precision=precisions[title];if(precision===undefined)
+return false;if(title===maxTitle)
+return true;if(precision<=maxPrecision){if(precision===maxPrecision){console.warn('Encountered two different VSync events ('+
+maxTitle+', '+title+') with the same precision, '+'ignoring the newer one ('+title+')');}
+return false;}
+maxPrecision=precision;maxTitle=title;times=[];return true;}
+for(var pid in model.processes){var process=model.processes[pid];for(var cid in process.counters){if(useInstead(cid,VSYNC_COUNTER_PRECISIONS)){var counter=process.counters[cid];for(var i=0;i<counter.series.length;i++){var series=counter.series[i];Array.prototype.push.apply(times,series.timestamps);}}}
+for(var tid in process.threads){var thread=process.threads[tid];for(var i=0;i<thread.sliceGroup.slices.length;i++){var slice=thread.sliceGroup.slices[i];if(useInstead(slice.title,VSYNC_SLICE_PRECISIONS))
+times.push(slice.start);else if(useInstead(slice.title,BEGIN_FRAME_SLICE_PRECISION)&&slice.args.args&&slice.args.args.frame_time_us)
+times.push(slice.args.args.frame_time_us/1000.0);}}}
+times.sort(function(x,y){return x-y;});return times;}};tr.c.Auditor.register(VSyncAuditor);return{VSyncAuditor:VSyncAuditor};});'use strict';tr.exportTo('tr.b',function(){var tmpVec2s=[];for(var i=0;i<8;i++)
+tmpVec2s[i]=vec2.create();var tmpVec2a=vec4.create();var tmpVec4a=vec4.create();var tmpVec4b=vec4.create();var tmpMat4=mat4.create();var tmpMat4b=mat4.create();var p00=vec2.createXY(0,0);var p10=vec2.createXY(1,0);var p01=vec2.createXY(0,1);var p11=vec2.createXY(1,1);var lerpingVecA=vec2.create();var lerpingVecB=vec2.create();function lerpVec2(out,a,b,amt){vec2.scale(lerpingVecA,a,amt);vec2.scale(lerpingVecB,b,1-amt);vec2.add(out,lerpingVecA,lerpingVecB);vec2.normalize(out,out);return out;}
+function Quad(){this.p1=vec2.create();this.p2=vec2.create();this.p3=vec2.create();this.p4=vec2.create();}
+Quad.fromXYWH=function(x,y,w,h){var q=new Quad();vec2.set(q.p1,x,y);vec2.set(q.p2,x+w,y);vec2.set(q.p3,x+w,y+h);vec2.set(q.p4,x,y+h);return q;}
+Quad.fromRect=function(r){return new Quad.fromXYWH(r.x,r.y,r.width,r.height);}
+Quad.from4Vecs=function(p1,p2,p3,p4){var q=new Quad();vec2.set(q.p1,p1[0],p1[1]);vec2.set(q.p2,p2[0],p2[1]);vec2.set(q.p3,p3[0],p3[1]);vec2.set(q.p4,p4[0],p4[1]);return q;}
+Quad.from8Array=function(arr){if(arr.length!=8)
+throw new Error('Array must be 8 long');var q=new Quad();q.p1[0]=arr[0];q.p1[1]=arr[1];q.p2[0]=arr[2];q.p2[1]=arr[3];q.p3[0]=arr[4];q.p3[1]=arr[5];q.p4[0]=arr[6];q.p4[1]=arr[7];return q;};Quad.prototype={pointInside:function(point){return pointInImplicitQuad(point,this.p1,this.p2,this.p3,this.p4);},boundingRect:function(){var x0=Math.min(this.p1[0],this.p2[0],this.p3[0],this.p4[0]);var y0=Math.min(this.p1[1],this.p2[1],this.p3[1],this.p4[1]);var x1=Math.max(this.p1[0],this.p2[0],this.p3[0],this.p4[0]);var y1=Math.max(this.p1[1],this.p2[1],this.p3[1],this.p4[1]);return new tr.b.Rect.fromXYWH(x0,y0,x1-x0,y1-y0);},clone:function(){var q=new Quad();vec2.copy(q.p1,this.p1);vec2.copy(q.p2,this.p2);vec2.copy(q.p3,this.p3);vec2.copy(q.p4,this.p4);return q;},scale:function(s){var q=new Quad();this.scaleFast(q,s);return q;},scaleFast:function(dstQuad,s){vec2.copy(dstQuad.p1,this.p1,s);vec2.copy(dstQuad.p2,this.p2,s);vec2.copy(dstQuad.p3,this.p3,s);vec2.copy(dstQuad.p3,this.p3,s);},isRectangle:function(){var bounds=this.boundingRect();return(bounds.x==this.p1[0]&&bounds.y==this.p1[1]&&bounds.width==this.p2[0]-this.p1[0]&&bounds.y==this.p2[1]&&bounds.width==this.p3[0]-this.p1[0]&&bounds.height==this.p3[1]-this.p2[1]&&bounds.x==this.p4[0]&&bounds.height==this.p4[1]-this.p2[1]);},projectUnitRect:function(rect){var q=new Quad();this.projectUnitRectFast(q,rect);return q;},projectUnitRectFast:function(dstQuad,rect){var v12=tmpVec2s[0];var v14=tmpVec2s[1];var v23=tmpVec2s[2];var v43=tmpVec2s[3];var l12,l14,l23,l43;vec2.sub(v12,this.p2,this.p1);l12=vec2.length(v12);vec2.scale(v12,v12,1/l12);vec2.sub(v14,this.p4,this.p1);l14=vec2.length(v14);vec2.scale(v14,v14,1/l14);vec2.sub(v23,this.p3,this.p2);l23=vec2.length(v23);vec2.scale(v23,v23,1/l23);vec2.sub(v43,this.p3,this.p4);l43=vec2.length(v43);vec2.scale(v43,v43,1/l43);var b12=tmpVec2s[0];var b14=tmpVec2s[1];var b23=tmpVec2s[2];var b43=tmpVec2s[3];lerpVec2(b12,v12,v43,rect.y);lerpVec2(b43,v12,v43,1-rect.bottom);lerpVec2(b14,v14,v23,rect.x);lerpVec2(b23,v14,v23,1-rect.right);vec2.addTwoScaledUnitVectors(tmpVec2a,b12,l12*rect.x,b14,l14*rect.y);vec2.add(dstQuad.p1,this.p1,tmpVec2a);vec2.addTwoScaledUnitVectors(tmpVec2a,b12,l12*-(1.0-rect.right),b23,l23*rect.y);vec2.add(dstQuad.p2,this.p2,tmpVec2a);vec2.addTwoScaledUnitVectors(tmpVec2a,b43,l43*-(1.0-rect.right),b23,l23*-(1.0-rect.bottom));vec2.add(dstQuad.p3,this.p3,tmpVec2a);vec2.addTwoScaledUnitVectors(tmpVec2a,b43,l43*rect.left,b14,l14*-(1.0-rect.bottom));vec2.add(dstQuad.p4,this.p4,tmpVec2a);},toString:function(){return'Quad('+
+vec2.toString(this.p1)+', '+
+vec2.toString(this.p2)+', '+
+vec2.toString(this.p3)+', '+
+vec2.toString(this.p4)+')';}};function sign(p1,p2,p3){return(p1[0]-p3[0])*(p2[1]-p3[1])-
+(p2[0]-p3[0])*(p1[1]-p3[1]);}
+function pointInTriangle2(pt,p1,p2,p3){var b1=sign(pt,p1,p2)<0.0;var b2=sign(pt,p2,p3)<0.0;var b3=sign(pt,p3,p1)<0.0;return((b1==b2)&&(b2==b3));}
+function pointInImplicitQuad(point,p1,p2,p3,p4){return pointInTriangle2(point,p1,p2,p3)||pointInTriangle2(point,p1,p3,p4);}
+return{pointInTriangle2:pointInTriangle2,pointInImplicitQuad:pointInImplicitQuad,Quad:Quad};});'use strict';tr.exportTo('tr.model.source_info',function(){function SourceInfo(file,opt_line,opt_column){this.file_=file;this.line_=opt_line||-1;this.column_=opt_column||-1;}
+SourceInfo.prototype={get file(){return this.file_;},get line(){return this.line_;},get column(){return this.column_;},get domain(){if(!this.file_)
+return undefined;var domain=this.file_.match(/(.*:\/\/[^:\/]*)/i);return domain?domain[1]:undefined;},toString:function(){var str='';if(this.file_)
+str+=this.file_;if(this.line_>0)
+str+=':'+this.line_;if(this.column_>0)
+str+=':'+this.column_;return str;}};return{SourceInfo:SourceInfo};});'use strict';tr.exportTo('tr.model.source_info',function(){function JSSourceInfo(file,line,column,isNative,scriptId,state){tr.model.source_info.SourceInfo.call(this,file,line,column);this.isNative_=isNative;this.scriptId_=scriptId;this.state_=state;}
+JSSourceInfo.prototype={__proto__:tr.model.source_info.SourceInfo.prototype,get state(){return this.state_;},get isNative(){return this.isNative_;},get scriptId(){return this.scriptId_;},toString:function(){var str=this.isNative_?'[native v8] ':'';return str+
+tr.model.source_info.SourceInfo.prototype.toString.call(this);}};return{JSSourceInfo:JSSourceInfo,JSSourceState:{COMPILED:'compiled',OPTIMIZABLE:'optimizable',OPTIMIZED:'optimized',UNKNOWN:'unknown'}};});'use strict';tr.exportTo('tr.e.importer',function(){function TraceCodeEntry(address,size,name,scriptId){this.id_=tr.b.GUID.allocate();this.address_=address;this.size_=size;var rePrefix=/^(\w*:)?([*~]?)(.*)$/m;var tokens=rePrefix.exec(name);var prefix=tokens[1];var state=tokens[2];var body=tokens[3];if(state==='*'){state=tr.model.source_info.JSSourceState.OPTIMIZED;}else if(state==='~'){state=tr.model.source_info.JSSourceState.OPTIMIZABLE;}else if(state===''){state=tr.model.source_info.JSSourceState.COMPILED;}else{console.warning('Unknown v8 code state '+state);state=tr.model.source_info.JSSourceState.UNKNOWN;}
+var rawName;var rawUrl;if(prefix==='Script:'){rawName='';rawUrl=body;}else{var spacePos=body.lastIndexOf(' ');rawName=spacePos!==-1?body.substr(0,spacePos):body;rawUrl=spacePos!==-1?body.substr(spacePos+1):'';}
+function splitLineAndColumn(url){var lineColumnRegEx=/(?::(\d+))?(?::(\d+))?$/;var lineColumnMatch=lineColumnRegEx.exec(url);var lineNumber;var columnNumber;if(typeof(lineColumnMatch[1])==='string'){lineNumber=parseInt(lineColumnMatch[1],10);lineNumber=isNaN(lineNumber)?undefined:lineNumber-1;}
+if(typeof(lineColumnMatch[2])==='string'){columnNumber=parseInt(lineColumnMatch[2],10);columnNumber=isNaN(columnNumber)?undefined:columnNumber-1;}
+return{url:url.substring(0,url.length-lineColumnMatch[0].length),lineNumber:lineNumber,columnNumber:columnNumber};}
+var nativeSuffix=' native';var isNative=rawName.endsWith(nativeSuffix);this.name_=isNative?rawName.slice(0,-nativeSuffix.length):rawName;var urlData=splitLineAndColumn(rawUrl);var url=urlData.url||'';var line=urlData.lineNumber||0;var column=urlData.columnNumber||0;this.sourceInfo_=new tr.model.source_info.JSSourceInfo(url,line,column,isNative,scriptId,state);};TraceCodeEntry.prototype={get id(){return this.id_;},get sourceInfo(){return this.sourceInfo_;},get name(){return this.name_;},set address(address){this.address_=address;},get address(){return this.address_;},set size(size){this.size_=size;},get size(){return this.size_;}};return{TraceCodeEntry:TraceCodeEntry};});'use strict';tr.exportTo('tr.e.importer',function(){function TraceCodeMap(){this.banks_=new Map();}
+TraceCodeMap.prototype={addEntry:function(addressHex,size,name,scriptId){var entry=new tr.e.importer.TraceCodeEntry(this.getAddress_(addressHex),size,name,scriptId);this.addEntry_(addressHex,entry);},moveEntry:function(oldAddressHex,newAddressHex,size){var entry=this.getBank_(oldAddressHex).removeEntry(this.getAddress_(oldAddressHex));if(!entry)
+return;entry.address=this.getAddress_(newAddressHex);entry.size=size;this.addEntry_(newAddressHex,entry);},lookupEntry:function(addressHex){return this.getBank_(addressHex).lookupEntry(this.getAddress_(addressHex));},addEntry_:function(addressHex,entry){this.getBank_(addressHex).addEntry(entry);},getAddress_:function(addressHex){var bankSizeHexDigits=13;addressHex=addressHex.slice(2);return parseInt(addressHex.slice(-bankSizeHexDigits),16);},getBank_:function(addressHex){addressHex=addressHex.slice(2);var bankSizeHexDigits=13;var maxHexDigits=16;var bankName=addressHex.slice(-maxHexDigits,-bankSizeHexDigits);var bank=this.banks_.get(bankName);if(!bank){bank=new TraceCodeBank();this.banks_.set(bankName,bank);}
+return bank;}};function TraceCodeBank(){this.entries_=[];}
+TraceCodeBank.prototype={removeEntry:function(address){if(this.entries_.length===0)
+return undefined;var index=tr.b.findLowIndexInSortedArray(this.entries_,function(entry){return entry.address;},address);var entry=this.entries_[index];if(!entry||entry.address!==address)
+return undefined;this.entries_.splice(index,1);return entry;},lookupEntry:function(address){var index=tr.b.findHighIndexInSortedArray(this.entries_,function(e){return address-e.address;})-1;var entry=this.entries_[index];return entry&&address<entry.address+entry.size?entry:undefined;},addEntry:function(newEntry){if(this.entries_.length===0)
+this.entries_.push(newEntry);var endAddress=newEntry.address+newEntry.size;var lastIndex=tr.b.findLowIndexInSortedArray(this.entries_,function(entry){return entry.address;},endAddress);var index;for(index=lastIndex-1;index>=0;--index){var entry=this.entries_[index];var entryEndAddress=entry.address+entry.size;if(entryEndAddress<=newEntry.address)
+break;}
+++index;this.entries_.splice(index,lastIndex-index,newEntry);}};return{TraceCodeMap:TraceCodeMap};});'use strict';tr.exportTo('tr.e.importer.v8',function(){function SplayTree(){};SplayTree.prototype.root_=null;SplayTree.prototype.isEmpty=function(){return!this.root_;};SplayTree.prototype.insert=function(key,value){if(this.isEmpty()){this.root_=new SplayTree.Node(key,value);return;}
+this.splay_(key);if(this.root_.key==key){return;}
+var node=new SplayTree.Node(key,value);if(key>this.root_.key){node.left=this.root_;node.right=this.root_.right;this.root_.right=null;}else{node.right=this.root_;node.left=this.root_.left;this.root_.left=null;}
+this.root_=node;};SplayTree.prototype.remove=function(key){if(this.isEmpty()){throw Error('Key not found: '+key);}
+this.splay_(key);if(this.root_.key!=key){throw Error('Key not found: '+key);}
+var removed=this.root_;if(!this.root_.left){this.root_=this.root_.right;}else{var right=this.root_.right;this.root_=this.root_.left;this.splay_(key);this.root_.right=right;}
+return removed;};SplayTree.prototype.find=function(key){if(this.isEmpty()){return null;}
+this.splay_(key);return this.root_.key==key?this.root_:null;};SplayTree.prototype.findMin=function(){if(this.isEmpty()){return null;}
+var current=this.root_;while(current.left){current=current.left;}
+return current;};SplayTree.prototype.findMax=function(opt_startNode){if(this.isEmpty()){return null;}
+var current=opt_startNode||this.root_;while(current.right){current=current.right;}
+return current;};SplayTree.prototype.findGreatestLessThan=function(key){if(this.isEmpty()){return null;}
+this.splay_(key);if(this.root_.key<=key){return this.root_;}else if(this.root_.left){return this.findMax(this.root_.left);}else{return null;}};SplayTree.prototype.exportKeysAndValues=function(){var result=[];this.traverse_(function(node){result.push([node.key,node.value]);});return result;};SplayTree.prototype.exportValues=function(){var result=[];this.traverse_(function(node){result.push(node.value);});return result;};SplayTree.prototype.splay_=function(key){if(this.isEmpty()){return;}
+var dummy,left,right;dummy=left=right=new SplayTree.Node(null,null);var current=this.root_;while(true){if(key<current.key){if(!current.left){break;}
+if(key<current.left.key){var tmp=current.left;current.left=tmp.right;tmp.right=current;current=tmp;if(!current.left){break;}}
+right.left=current;right=current;current=current.left;}else if(key>current.key){if(!current.right){break;}
+if(key>current.right.key){var tmp=current.right;current.right=tmp.left;tmp.left=current;current=tmp;if(!current.right){break;}}
+left.right=current;left=current;current=current.right;}else{break;}}
+left.right=current.left;right.left=current.right;current.left=dummy.right;current.right=dummy.left;this.root_=current;};SplayTree.prototype.traverse_=function(f){var nodesToVisit=[this.root_];while(nodesToVisit.length>0){var node=nodesToVisit.shift();if(node==null){continue;}
+f(node);nodesToVisit.push(node.left);nodesToVisit.push(node.right);}};SplayTree.Node=function(key,value){this.key=key;this.value=value;};SplayTree.Node.prototype.left=null;SplayTree.Node.prototype.right=null;return{SplayTree:SplayTree};});'use strict';tr.exportTo('tr.e.importer.v8',function(){function CodeMap(){this.dynamics_=new tr.e.importer.v8.SplayTree();this.dynamicsNameGen_=new tr.e.importer.v8.CodeMap.NameGenerator();this.statics_=new tr.e.importer.v8.SplayTree();this.libraries_=new tr.e.importer.v8.SplayTree();this.pages_=[];};CodeMap.PAGE_ALIGNMENT=12;CodeMap.PAGE_SIZE=1<<CodeMap.PAGE_ALIGNMENT;CodeMap.prototype.addCode=function(start,codeEntry){this.deleteAllCoveredNodes_(this.dynamics_,start,start+codeEntry.size);this.dynamics_.insert(start,codeEntry);};CodeMap.prototype.moveCode=function(from,to){var removedNode=this.dynamics_.remove(from);this.deleteAllCoveredNodes_(this.dynamics_,to,to+removedNode.value.size);this.dynamics_.insert(to,removedNode.value);};CodeMap.prototype.deleteCode=function(start){var removedNode=this.dynamics_.remove(start);};CodeMap.prototype.addLibrary=function(start,codeEntry){this.markPages_(start,start+codeEntry.size);this.libraries_.insert(start,codeEntry);};CodeMap.prototype.addStaticCode=function(start,codeEntry){this.statics_.insert(start,codeEntry);};CodeMap.prototype.markPages_=function(start,end){for(var addr=start;addr<=end;addr+=CodeMap.PAGE_SIZE){this.pages_[addr>>>CodeMap.PAGE_ALIGNMENT]=1;}};CodeMap.prototype.deleteAllCoveredNodes_=function(tree,start,end){var to_delete=[];var addr=end-1;while(addr>=start){var node=tree.findGreatestLessThan(addr);if(!node)break;var start2=node.key,end2=start2+node.value.size;if(start2<end&&start<end2)to_delete.push(start2);addr=start2-1;}
+for(var i=0,l=to_delete.length;i<l;++i)tree.remove(to_delete[i]);};CodeMap.prototype.isAddressBelongsTo_=function(addr,node){return addr>=node.key&&addr<(node.key+node.value.size);};CodeMap.prototype.findInTree_=function(tree,addr){var node=tree.findGreatestLessThan(addr);return node&&this.isAddressBelongsTo_(addr,node)?node.value:null;};CodeMap.prototype.findEntry=function(addr){var pageAddr=addr>>>CodeMap.PAGE_ALIGNMENT;if(pageAddr in this.pages_){return this.findInTree_(this.statics_,addr)||this.findInTree_(this.libraries_,addr);}
+var min=this.dynamics_.findMin();var max=this.dynamics_.findMax();if(max!=null&&addr<(max.key+max.value.size)&&addr>=min.key){var dynaEntry=this.findInTree_(this.dynamics_,addr);if(dynaEntry==null)return null;if(!dynaEntry.nameUpdated_){dynaEntry.name=this.dynamicsNameGen_.getName(dynaEntry.name);dynaEntry.nameUpdated_=true;}
+return dynaEntry;}
+return null;};CodeMap.prototype.findDynamicEntryByStartAddress=function(addr){var node=this.dynamics_.find(addr);return node?node.value:null;};CodeMap.prototype.getAllDynamicEntries=function(){return this.dynamics_.exportValues();};CodeMap.prototype.getAllDynamicEntriesWithAddresses=function(){return this.dynamics_.exportKeysAndValues();};CodeMap.prototype.getAllStaticEntries=function(){return this.statics_.exportValues();};CodeMap.prototype.getAllLibrariesEntries=function(){return this.libraries_.exportValues();};CodeMap.CodeEntry=function(size,opt_name){this.id=tr.b.GUID.allocate();this.size=size;this.name=opt_name||'';this.nameUpdated_=false;};CodeMap.CodeEntry.prototype.getName=function(){return this.name;};CodeMap.CodeEntry.prototype.toString=function(){return this.name+': '+this.size.toString(16);};CodeMap.NameGenerator=function(){this.knownNames_={};};CodeMap.NameGenerator.prototype.getName=function(name){if(!(name in this.knownNames_)){this.knownNames_[name]=0;return name;}
+var count=++this.knownNames_[name];return name+' {'+count+'}';};return{CodeMap:CodeMap};});'use strict';tr.exportTo('tr.model',function(){function YComponent(stableId,yPercentOffset){this.stableId=stableId;this.yPercentOffset=yPercentOffset;}
+YComponent.prototype={toDict:function(){return{stableId:this.stableId,yPercentOffset:this.yPercentOffset};}};function Location(xWorld,yComponents){this.xWorld_=xWorld;this.yComponents_=yComponents;};Location.fromViewCoordinates=function(viewport,viewX,viewY){var dt=viewport.currentDisplayTransform;var xWorld=dt.xViewToWorld(viewX);var yComponents=[];var elem=document.elementFromPoint(viewX+viewport.modelTrackContainer.canvas.offsetLeft,viewY+viewport.modelTrackContainer.canvas.offsetTop);while(elem instanceof tr.ui.tracks.Track){if(elem.eventContainer){var boundRect=elem.getBoundingClientRect();var yPercentOffset=(viewY-boundRect.top)/boundRect.height;yComponents.push(new YComponent(elem.eventContainer.stableId,yPercentOffset));}
+elem=elem.parentElement;}
+if(yComponents.length==0)
+return;return new Location(xWorld,yComponents);}
+Location.fromStableIdAndTimestamp=function(viewport,stableId,ts){var xWorld=ts;var yComponents=[];var containerToTrack=viewport.containerToTrackMap;var elem=containerToTrack.getTrackByStableId(stableId);if(!elem)
+return;var firstY=elem.getBoundingClientRect().top;while(elem instanceof tr.ui.tracks.Track){if(elem.eventContainer){var boundRect=elem.getBoundingClientRect();var yPercentOffset=(firstY-boundRect.top)/boundRect.height;yComponents.push(new YComponent(elem.eventContainer.stableId,yPercentOffset));}
+elem=elem.parentElement;}
+if(yComponents.length==0)
+return;return new Location(xWorld,yComponents);}
+Location.prototype={get xWorld(){return this.xWorld_;},getContainingTrack:function(viewport){var containerToTrack=viewport.containerToTrackMap;for(var i in this.yComponents_){var yComponent=this.yComponents_[i];var track=containerToTrack.getTrackByStableId(yComponent.stableId);if(track!==undefined)
+return track;}},toViewCoordinates:function(viewport){var dt=viewport.currentDisplayTransform;var containerToTrack=viewport.containerToTrackMap;var viewX=dt.xWorldToView(this.xWorld_);var viewY=-1;for(var index in this.yComponents_){var yComponent=this.yComponents_[index];var track=containerToTrack.getTrackByStableId(yComponent.stableId);if(track!==undefined){var boundRect=track.getBoundingClientRect();viewY=yComponent.yPercentOffset*boundRect.height+boundRect.top;break;}}
+return{viewX:viewX,viewY:viewY};},toDict:function(){return{xWorld:this.xWorld_,yComponents:this.yComponents_};}};return{Location:Location};});'use strict';tr.exportTo('tr.model',function(){function Annotation(){this.guid_=tr.b.GUID.allocate();this.view_=undefined;};Annotation.fromDictIfPossible=function(args){if(args.typeName===undefined)
+throw new Error('Missing typeName argument');var typeInfo=Annotation.findTypeInfoMatching(function(typeInfo){return typeInfo.metadata.typeName===args.typeName;});if(typeInfo===undefined)
+return undefined;return typeInfo.constructor.fromDict(args);};Annotation.fromDict=function(){throw new Error('Not implemented');}
+Annotation.prototype={get guid(){return this.guid_;},onRemove:function(){},toDict:function(){throw new Error('Not implemented');},getOrCreateView:function(viewport){if(!this.view_)
+this.view_=this.createView_(viewport);return this.view_;},createView_:function(){throw new Error('Not implemented');}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(Annotation,options);Annotation.addEventListener('will-register',function(e){if(!e.typeInfo.constructor.hasOwnProperty('fromDict'))
+throw new Error('Must have fromDict method');if(!e.typeInfo.metadata.typeName)
+throw new Error('Registered Annotations must provide typeName');});return{Annotation:Annotation};});'use strict';tr.exportTo('tr.ui.annotations',function(){function AnnotationView(viewport,annotation){}
+AnnotationView.prototype={draw:function(ctx){throw new Error('Not implemented');}};return{AnnotationView:AnnotationView};});'use strict';tr.exportTo('tr.ui.annotations',function(){function RectAnnotationView(viewport,annotation){this.viewport_=viewport;this.annotation_=annotation;}
+RectAnnotationView.prototype={__proto__:tr.ui.annotations.AnnotationView.prototype,draw:function(ctx){var dt=this.viewport_.currentDisplayTransform;var startCoords=this.annotation_.startLocation.toViewCoordinates(this.viewport_);var endCoords=this.annotation_.endLocation.toViewCoordinates(this.viewport_);var startY=startCoords.viewY-ctx.canvas.getBoundingClientRect().top;var sizeY=endCoords.viewY-startCoords.viewY;if(startY+sizeY<0){startY=sizeY;}else if(startY<0){startY=0;}
+ctx.fillStyle=this.annotation_.fillStyle;ctx.fillRect(startCoords.viewX,startY,endCoords.viewX-startCoords.viewX,sizeY);}};return{RectAnnotationView:RectAnnotationView};});'use strict';tr.exportTo('tr.model',function(){function RectAnnotation(start,end){tr.model.Annotation.apply(this,arguments);this.startLocation_=start;this.endLocation_=end;this.fillStyle='rgba(255, 180, 0, 0.3)';}
+RectAnnotation.fromDict=function(dict){var args=dict.args;var startLoc=new tr.model.Location(args.start.xWorld,args.start.yComponents);var endLoc=new tr.model.Location(args.end.xWorld,args.end.yComponents);return new tr.model.RectAnnotation(startLoc,endLoc);}
+RectAnnotation.prototype={__proto__:tr.model.Annotation.prototype,get startLocation(){return this.startLocation_;},get endLocation(){return this.endLocation_;},toDict:function(){return{typeName:'rect',args:{start:this.startLocation.toDict(),end:this.endLocation.toDict()}};},createView_:function(viewport){return new tr.ui.annotations.RectAnnotationView(viewport,this);}};tr.model.Annotation.register(RectAnnotation,{typeName:'rect'});return{RectAnnotation:RectAnnotation};});'use strict';tr.exportTo('tr.ui.annotations',function(){function CommentBoxAnnotationView(viewport,annotation){this.viewport_=viewport;this.annotation_=annotation;this.textArea_=undefined;this.styleWidth=250;this.styleHeight=50;this.fontSize=10;this.rightOffset=50;this.topOffset=25;}
+CommentBoxAnnotationView.prototype={__proto__:tr.ui.annotations.AnnotationView.prototype,removeTextArea:function(){this.textArea_.parentNode.removeChild(this.textArea_);},draw:function(ctx){var coords=this.annotation_.location.toViewCoordinates(this.viewport_);if(coords.viewX<0){if(this.textArea_)
+this.textArea_.style.visibility='hidden';return;}
+if(!this.textArea_){this.textArea_=document.createElement('textarea');this.textArea_.style.position='absolute';this.textArea_.readOnly=true;this.textArea_.value=this.annotation_.text;this.textArea_.style.zIndex=1;ctx.canvas.parentNode.appendChild(this.textArea_);}
+this.textArea_.style.width=this.styleWidth+'px';this.textArea_.style.height=this.styleHeight+'px';this.textArea_.style.fontSize=this.fontSize+'px';this.textArea_.style.visibility='visible';this.textArea_.style.left=coords.viewX+ctx.canvas.getBoundingClientRect().left+
+this.rightOffset+'px';this.textArea_.style.top=coords.viewY-ctx.canvas.getBoundingClientRect().top-
+this.topOffset+'px';ctx.strokeStyle='rgb(0, 0, 0)';ctx.lineWidth=2;ctx.beginPath();tr.ui.b.drawLine(ctx,coords.viewX,coords.viewY-ctx.canvas.getBoundingClientRect().top,coords.viewX+this.rightOffset,coords.viewY-this.topOffset-
+ctx.canvas.getBoundingClientRect().top);ctx.stroke();}};return{CommentBoxAnnotationView:CommentBoxAnnotationView};});'use strict';tr.exportTo('tr.model',function(){function CommentBoxAnnotation(location,text){tr.model.Annotation.apply(this,arguments);this.location=location;this.text=text;}
+CommentBoxAnnotation.fromDict=function(dict){var args=dict.args;var location=new tr.model.Location(args.location.xWorld,args.location.yComponents);return new tr.model.CommentBoxAnnotation(location,args.text);};CommentBoxAnnotation.prototype={__proto__:tr.model.Annotation.prototype,onRemove:function(){this.view_.removeTextArea();},toDict:function(){return{typeName:'comment_box',args:{text:this.text,location:this.location.toDict()}};},createView_:function(viewport){return new tr.ui.annotations.CommentBoxAnnotationView(viewport,this);}};tr.model.Annotation.register(CommentBoxAnnotation,{typeName:'comment_box'});return{CommentBoxAnnotation:CommentBoxAnnotation};});'use strict';tr.exportTo('tr.model',function(){function HeapEntry(heapDump,leafStackFrame,size){this.heapDump=heapDump;this.leafStackFrame=leafStackFrame;this.size=size;}
+function HeapDump(processMemoryDump,allocatorName){this.processMemoryDump=processMemoryDump;this.allocatorName=allocatorName;this.entries=[];}
+HeapDump.prototype={addEntry:function(leafStackFrame,size){var entry=new HeapEntry(this,leafStackFrame,size);this.entries.push(entry);return entry;}};return{HeapEntry:HeapEntry,HeapDump:HeapDump};});'use strict';tr.exportTo('tr.ui.annotations',function(){function XMarkerAnnotationView(viewport,annotation){this.viewport_=viewport;this.annotation_=annotation;}
+XMarkerAnnotationView.prototype={__proto__:tr.ui.annotations.AnnotationView.prototype,draw:function(ctx){var dt=this.viewport_.currentDisplayTransform;var viewX=dt.xWorldToView(this.annotation_.timestamp);ctx.beginPath();tr.ui.b.drawLine(ctx,viewX,0,viewX,ctx.canvas.height);ctx.strokeStyle=this.annotation_.strokeStyle;ctx.stroke();}};return{XMarkerAnnotationView:XMarkerAnnotationView};});'use strict';tr.exportTo('tr.model',function(){function XMarkerAnnotation(timestamp){tr.model.Annotation.apply(this,arguments);this.timestamp=timestamp;this.strokeStyle='rgba(0, 0, 255, 0.5)';}
+XMarkerAnnotation.fromDict=function(dict){return new XMarkerAnnotation(dict.args.timestamp);}
+XMarkerAnnotation.prototype={__proto__:tr.model.Annotation.prototype,toDict:function(){return{typeName:'xmarker',args:{timestamp:this.timestamp}};},createView_:function(viewport){return new tr.ui.annotations.XMarkerAnnotationView(viewport,this);}};tr.model.Annotation.register(XMarkerAnnotation,{typeName:'xmarker'});return{XMarkerAnnotation:XMarkerAnnotation};});'use strict';tr.exportTo('tr.e.importer',function(){var deepCopy=tr.b.deepCopy;var ColorScheme=tr.b.ColorScheme;function getEventColor(event,opt_customName){if(event.cname)
+return ColorScheme.getColorIdForReservedName(event.cname);else if(opt_customName||event.name){return ColorScheme.getColorIdForGeneralPurposeString(opt_customName||event.name);}}
+var timestampFromUs=tr.b.u.Units.timestampFromUs;var maybeTimestampFromUs=tr.b.u.Units.maybeTimestampFromUs;var PRODUCER='producer';var CONSUMER='consumer';var STEP='step';function TraceEventImporter(model,eventData){this.importPriority=1;this.model_=model;this.events_=undefined;this.sampleEvents_=undefined;this.stackFrameEvents_=undefined;this.systemTraceEvents_=undefined;this.battorData_=undefined;this.eventsWereFromString_=false;this.softwareMeasuredCpuCount_=undefined;this.allAsyncEvents_=[];this.allFlowEvents_=[];this.allObjectEvents_=[];this.traceEventSampleStackFramesByName_={};this.v8ProcessCodeMaps_={};this.v8ProcessRootStackFrame_={};this.allMemoryDumpEvents_={};if(typeof(eventData)==='string'||eventData instanceof String){eventData=eventData.trim();if(eventData[0]==='['){eventData=eventData.replace(/\s*,\s*$/,'');if(eventData[eventData.length-1]!==']')
+eventData=eventData+']';}
+this.events_=JSON.parse(eventData);this.eventsWereFromString_=true;}else{this.events_=eventData;}
+this.traceAnnotations_=this.events_.traceAnnotations;if(this.events_.traceEvents){var container=this.events_;this.events_=this.events_.traceEvents;this.systemTraceEvents_=container.systemTraceEvents;this.battorData_=container.battorLogAsString;this.sampleEvents_=container.samples;this.stackFrameEvents_=container.stackFrames;if(container.displayTimeUnit){var unitName=container.displayTimeUnit;var unit=tr.b.u.TimeDisplayModes[unitName];if(unit===undefined){throw new Error('Unit '+unitName+' is not supported.');}
+this.model_.intrinsicTimeUnit=unit;}
+var knownFieldNames={battorLogAsString:true,samples:true,stackFrames:true,systemTraceEvents:true,traceAnnotations:true,traceEvents:true};for(var fieldName in container){if(fieldName in knownFieldNames)
+continue;this.model_.metadata.push({name:fieldName,value:container[fieldName]});}}}
+TraceEventImporter.canImport=function(eventData){if(typeof(eventData)==='string'||eventData instanceof String){eventData=eventData.trim();return eventData[0]==='{'||eventData[0]==='[';}
+if(eventData instanceof Array&&eventData.length&&eventData[0].ph)
+return true;if(eventData.traceEvents){if(eventData.traceEvents instanceof Array){if(eventData.traceEvents.length&&eventData.traceEvents[0].ph)
+return true;if(eventData.samples.length&&eventData.stackFrames!==undefined)
+return true;}}
+return false;};TraceEventImporter.prototype={__proto__:tr.importer.Importer.prototype,extractSubtraces:function(){var systemEventsTmp=this.systemTraceEvents_;var battorDataTmp=this.battorData_;this.systemTraceEvents_=undefined;this.battorData_=undefined;var subTraces=systemEventsTmp?[systemEventsTmp]:[];if(battorDataTmp)
+subTraces.push(battorDataTmp);return subTraces;},deepCopyIfNeeded_:function(obj){if(obj===undefined)
+obj={};if(this.eventsWereFromString_)
+return obj;return deepCopy(obj);},deepCopyAlways_:function(obj){if(obj===undefined)
+obj={};return deepCopy(obj);},processAsyncEvent:function(event){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.allAsyncEvents_.push({sequenceNumber:this.allAsyncEvents_.length,event:event,thread:thread});},processFlowEvent:function(event,opt_slice){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.allFlowEvents_.push({refGuid:tr.b.GUID.getLastGuid(),sequenceNumber:this.allFlowEvents_.length,event:event,slice:opt_slice,thread:thread});},processCounterEvent:function(event){var ctr_name;if(event.id!==undefined)
+ctr_name=event.name+'['+event.id+']';else
+ctr_name=event.name;var ctr=this.model_.getOrCreateProcess(event.pid).getOrCreateCounter(event.cat,ctr_name);var reservedColorId=event.cname?getEventColor(event):undefined;if(ctr.numSeries===0){for(var seriesName in event.args){var colorId=reservedColorId||getEventColor(event,ctr.name+'.'+seriesName);ctr.addSeries(new tr.model.CounterSeries(seriesName,colorId));}
+if(ctr.numSeries===0){this.model_.importWarning({type:'counter_parse_error',message:'Expected counter '+event.name+' to have at least one argument to use as a value.'});delete ctr.parent.counters[ctr.name];return;}}
+var ts=timestampFromUs(event.ts);ctr.series.forEach(function(series){var val=event.args[series.name]?event.args[series.name]:0;series.addCounterSample(ts,val);});},processObjectEvent:function(event){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.allObjectEvents_.push({sequenceNumber:this.allObjectEvents_.length,event:event,thread:thread});},processDurationEvent:function(event){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);var ts=timestampFromUs(event.ts);if(!thread.sliceGroup.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'duration_parse_error',message:'Timestamps are moving backward.'});return;}
+if(event.ph==='B'){var slice=thread.sliceGroup.beginSlice(event.cat,event.name,timestampFromUs(event.ts),this.deepCopyIfNeeded_(event.args),timestampFromUs(event.tts),event.argsStripped,getEventColor(event));slice.startStackFrame=this.getStackFrameForEvent_(event);}else if(event.ph==='I'||event.ph==='i'||event.ph==='R'){if(event.s!==undefined&&event.s!=='t')
+throw new Error('This should never happen');thread.sliceGroup.beginSlice(event.cat,event.name,timestampFromUs(event.ts),this.deepCopyIfNeeded_(event.args),timestampFromUs(event.tts),event.argsStripped,getEventColor(event));var slice=thread.sliceGroup.endSlice(timestampFromUs(event.ts),timestampFromUs(event.tts));slice.startStackFrame=this.getStackFrameForEvent_(event);slice.endStackFrame=undefined;}else{if(!thread.sliceGroup.openSliceCount){this.model_.importWarning({type:'duration_parse_error',message:'E phase event without a matching B phase event.'});return;}
+var slice=thread.sliceGroup.endSlice(timestampFromUs(event.ts),timestampFromUs(event.tts),getEventColor(event));if(event.name&&slice.title!=event.name){this.model_.importWarning({type:'title_match_error',message:'Titles do not match. Title is '+
+slice.title+' in openSlice, and is '+
+event.name+' in endSlice'});}
+slice.endStackFrame=this.getStackFrameForEvent_(event);this.mergeArgsInto_(slice.args,event.args,slice.title);}},mergeArgsInto_:function(dstArgs,srcArgs,eventName){for(var arg in srcArgs){if(dstArgs[arg]!==undefined){this.model_.importWarning({type:'arg_merge_error',message:'Different phases of '+eventName+' provided values for argument '+arg+'.'+' The last provided value will be used.'});}
+dstArgs[arg]=this.deepCopyIfNeeded_(srcArgs[arg]);}},processCompleteEvent:function(event){if(event.cat!==undefined&&event.cat.indexOf('trace_event_overhead')>-1)
+return undefined;var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);if(event.flow_out){if(event.flow_in)
+event.flowPhase=STEP;else
+event.flowPhase=PRODUCER;}else if(event.flow_in){event.flowPhase=CONSUMER;}
+var slice=thread.sliceGroup.pushCompleteSlice(event.cat,event.name,timestampFromUs(event.ts),maybeTimestampFromUs(event.dur),maybeTimestampFromUs(event.tts),maybeTimestampFromUs(event.tdur),this.deepCopyIfNeeded_(event.args),event.argsStripped,getEventColor(event),event.bind_id);slice.startStackFrame=this.getStackFrameForEvent_(event);slice.endStackFrame=this.getStackFrameForEvent_(event,true);return slice;},processMetadataEvent:function(event){if(event.argsStripped)
+return;if(event.name==='process_name'){var process=this.model_.getOrCreateProcess(event.pid);process.name=event.args.name;}else if(event.name==='process_labels'){var process=this.model_.getOrCreateProcess(event.pid);var labels=event.args.labels.split(',');for(var i=0;i<labels.length;i++)
+process.addLabelIfNeeded(labels[i]);}else if(event.name==='process_sort_index'){var process=this.model_.getOrCreateProcess(event.pid);process.sortIndex=event.args.sort_index;}else if(event.name==='thread_name'){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);thread.name=event.args.name;}else if(event.name==='thread_sort_index'){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);thread.sortIndex=event.args.sort_index;}else if(event.name==='num_cpus'){var n=event.args.number;if(this.softwareMeasuredCpuCount_!==undefined)
+n=Math.max(n,this.softwareMeasuredCpuCount_);this.softwareMeasuredCpuCount_=n;}else if(event.name==='stackFrames'){var stackFrames=event.args.stackFrames;if(stackFrames===undefined){this.model_.importWarning({type:'metadata_parse_error',message:'No stack frames found in a \''+event.name+'\' metadata event'});}else{this.importStackFrames_(stackFrames,'p'+event.pid+':',true);}}else{this.model_.importWarning({type:'metadata_parse_error',message:'Unrecognized metadata name: '+event.name});}},processJitCodeEvent:function(event){if(this.v8ProcessCodeMaps_[event.pid]===undefined)
+this.v8ProcessCodeMaps_[event.pid]=new tr.e.importer.TraceCodeMap();var map=this.v8ProcessCodeMaps_[event.pid];var data=event.args.data;if(event.name==='JitCodeMoved')
+map.moveEntry(data.code_start,data.new_code_start,data.code_len);else
+map.addEntry(data.code_start,data.code_len,data.name,data.script_id);},processInstantEvent:function(event){if(event.name==='JitCodeAdded'||event.name==='JitCodeMoved'){this.processJitCodeEvent(event);return;}
+if(event.s==='t'||event.s===undefined){this.processDurationEvent(event);return;}
+var constructor;switch(event.s){case'g':constructor=tr.model.GlobalInstantEvent;break;case'p':constructor=tr.model.ProcessInstantEvent;break;default:this.model_.importWarning({type:'instant_parse_error',message:'I phase event with unknown "s" field value.'});return;}
+var instantEvent=new constructor(event.cat,event.name,getEventColor(event),timestampFromUs(event.ts),this.deepCopyIfNeeded_(event.args));switch(instantEvent.type){case tr.model.InstantEventType.GLOBAL:this.model_.pushInstantEvent(instantEvent);break;case tr.model.InstantEventType.PROCESS:var process=this.model_.getOrCreateProcess(event.pid);process.pushInstantEvent(instantEvent);break;default:throw new Error('Unknown instant event type: '+event.s);}},processV8Sample:function(event){var data=event.args.data;if(data.vm_state==='js'&&!data.stack.length)
+return;var rootStackFrame=this.v8ProcessRootStackFrame_[event.pid];if(!rootStackFrame){rootStackFrame=new tr.model.StackFrame(undefined,'v8-root-stack-frame','v8-root-stack-frame',0);this.v8ProcessRootStackFrame_[event.pid]=rootStackFrame;}
+function findChildWithEntryID(stackFrame,entryID){return tr.b.findFirstInArray(stackFrame.children,function(child){return child.entryID===entryID;});}
+var model=this.model_;function addStackFrame(lastStackFrame,entry){var childFrame=findChildWithEntryID(lastStackFrame,entry.id);if(childFrame)
+return childFrame;var frame=new tr.model.StackFrame(lastStackFrame,tr.b.GUID.allocate(),entry.name,ColorScheme.getColorIdForGeneralPurposeString(entry.name),entry.sourceInfo);frame.entryID=entry.id;model.addStackFrame(frame);return frame;}
+var lastStackFrame=rootStackFrame;if(data.stack.length>0&&this.v8ProcessCodeMaps_[event.pid]){var map=this.v8ProcessCodeMaps_[event.pid];data.stack.reverse();for(var i=0;i<data.stack.length;i++){var entry=map.lookupEntry(data.stack[i]);if(entry===undefined){entry={id:'unknown',name:'unknown',sourceInfo:undefined};}
+lastStackFrame=addStackFrame(lastStackFrame,entry);}}else{var entry={id:data.vm_state,name:data.vm_state,sourceInfo:undefined};lastStackFrame=addStackFrame(lastStackFrame,entry);}
+var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);var sample=new tr.model.Sample(undefined,thread,'V8 Sample',timestampFromUs(event.ts),lastStackFrame,1,this.deepCopyIfNeeded_(event.args));this.model_.samples.push(sample);},processTraceSampleEvent:function(event){if(event.name==='V8Sample'){this.processV8Sample(event);return;}
+var stackFrame=this.getStackFrameForEvent_(event);if(stackFrame===undefined){stackFrame=this.traceEventSampleStackFramesByName_[event.name];}
+if(stackFrame===undefined){var id='te-'+tr.b.GUID.allocate();stackFrame=new tr.model.StackFrame(undefined,id,event.name,ColorScheme.getColorIdForGeneralPurposeString(event.name));this.model_.addStackFrame(stackFrame);this.traceEventSampleStackFramesByName_[event.name]=stackFrame;}
+var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);var sample=new tr.model.Sample(undefined,thread,'Trace Event Sample',timestampFromUs(event.ts),stackFrame,1,this.deepCopyIfNeeded_(event.args));this.model_.samples.push(sample);},getOrCreateMemoryDumpEvents_:function(dumpId){if(this.allMemoryDumpEvents_[dumpId]===undefined){this.allMemoryDumpEvents_[dumpId]={global:undefined,process:[]};}
+return this.allMemoryDumpEvents_[dumpId];},processMemoryDumpEvent:function(event){if(event.id===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:event.ph+' phase event without a dump ID.'});return;}
+var events=this.getOrCreateMemoryDumpEvents_(event.id);if(event.ph==='v'){events.process.push(event);}else if(event.ph==='V'){if(events.global!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple V phase events with the same dump ID.'});return;}
+events.global=event;}else{throw new Error('Invalid memory dump event phase "'+event.ph+'".');}},importEvents:function(){var csr=new tr.ClockSyncRecord('ftrace_importer',0,{});this.model_.clockSyncRecords.push(csr);if(this.stackFrameEvents_){this.importStackFrames_(this.stackFrameEvents_,'g',false);}
+if(this.traceAnnotations_)
+this.importAnnotations_();var events=this.events_;for(var eI=0;eI<events.length;eI++){var event=events[eI];if(event.args==='__stripped__'){event.argsStripped=true;event.args=undefined;}
+if(event.ph==='B'||event.ph==='E'){this.processDurationEvent(event);}else if(event.ph==='X'){var slice=this.processCompleteEvent(event);if(slice!==undefined&&event.bind_id!==undefined)
+this.processFlowEvent(event,slice);}else if(event.ph==='b'||event.ph==='e'||event.ph==='n'||event.ph==='S'||event.ph==='F'||event.ph==='T'||event.ph==='p'){this.processAsyncEvent(event);}else if(event.ph==='I'||event.ph==='i'||event.ph==='R'){this.processInstantEvent(event);}else if(event.ph==='P'){this.processTraceSampleEvent(event);}else if(event.ph==='C'){this.processCounterEvent(event);}else if(event.ph==='M'){this.processMetadataEvent(event);}else if(event.ph==='N'||event.ph==='D'||event.ph==='O'){this.processObjectEvent(event);}else if(event.ph==='s'||event.ph==='t'||event.ph==='f'){this.processFlowEvent(event);}else if(event.ph==='v'||event.ph==='V'){this.processMemoryDumpEvent(event);}else{this.model_.importWarning({type:'parse_error',message:'Unrecognized event phase: '+
+event.ph+' ('+event.name+')'});}}
+tr.b.iterItems(this.v8ProcessRootStackFrame_,function(name,frame){frame.removeAllChildren();});},importStackFrames_:function(rawStackFrames,idPrefix,addRootFrame){var model=this.model_;var rootStackFrame;if(addRootFrame){rootStackFrame=new tr.model.StackFrame(undefined,idPrefix,undefined,undefined);model.addStackFrame(rootStackFrame);}else{rootStackFrame=undefined;}
+for(var id in rawStackFrames){var rawStackFrame=rawStackFrames[id];var fullId=idPrefix+id;var textForColor=rawStackFrame.category?rawStackFrame.category:rawStackFrame.name;var stackFrame=new tr.model.StackFrame(undefined,fullId,rawStackFrame.name,ColorScheme.getColorIdForGeneralPurposeString(textForColor));model.addStackFrame(stackFrame);}
+for(var id in rawStackFrames){var fullId=idPrefix+id;var stackFrame=model.stackFrames[fullId];if(stackFrame===undefined)
+throw new Error('Internal error');var rawStackFrame=rawStackFrames[id];var parentId=rawStackFrame.parent;var parentStackFrame;if(parentId===undefined){parentStackFrame=rootStackFrame;}else{var parentFullId=idPrefix+parentId;parentStackFrame=model.stackFrames[parentFullId];if(parentStackFrame===undefined){this.model_.importWarning({type:'metadata_parse_error',message:'Missing parent frame with ID '+parentFullId+' for stack frame \''+stackFrame.name+'\' (ID '+fullId+').'});parentStackFrame=rootStackFrame;}}
+stackFrame.parentFrame=parentStackFrame;}},importAnnotations_:function(){for(var id in this.traceAnnotations_){var annotation=tr.model.Annotation.fromDictIfPossible(this.traceAnnotations_[id]);if(!annotation){this.model_.importWarning({type:'annotation_warning',message:'Unrecognized traceAnnotation typeName \"'+
+this.traceAnnotations_[id].typeName+'\"'});continue;}
+this.model_.addAnnotation(annotation);}},finalizeImport:function(){if(this.softwareMeasuredCpuCount_!==undefined){this.model_.kernel.softwareMeasuredCpuCount=this.softwareMeasuredCpuCount_;}
+this.createAsyncSlices_();this.createFlowSlices_();this.createExplicitObjects_();this.createImplicitObjects_();this.createMemoryDumps_();},getStackFrameForEvent_:function(event,opt_lookForEndEvent){var sf;var stack;if(opt_lookForEndEvent){sf=event.esf;stack=event.estack;}else{sf=event.sf;stack=event.stack;}
+if(stack!==undefined&&sf!==undefined){this.model_.importWarning({type:'stack_frame_and_stack_error',message:'Event at '+event.ts+' cannot have both a stack and a stackframe.'});return undefined;}
+if(stack!==undefined)
+return this.model_.resolveStackToStackFrame_(event.pid,stack);if(sf===undefined)
+return undefined;var stackFrame=this.model_.stackFrames['g'+sf];if(stackFrame===undefined){this.model_.importWarning({type:'sample_import_error',message:'No frame for '+sf});return;}
+return stackFrame;},resolveStackToStackFrame_:function(pid,stack){return undefined;},importSampleData:function(){if(!this.sampleEvents_)
+return;var m=this.model_;var events=this.sampleEvents_;if(this.events_.length===0){for(var i=0;i<events.length;i++){var event=events[i];m.getOrCreateProcess(event.tid).getOrCreateThread(event.tid);}}
+var threadsByTid={};m.getAllThreads().forEach(function(t){threadsByTid[t.tid]=t;});for(var i=0;i<events.length;i++){var event=events[i];var thread=threadsByTid[event.tid];if(thread===undefined){m.importWarning({type:'sample_import_error',message:'Thread '+events.tid+'not found'});continue;}
+var cpu;if(event.cpu!==undefined)
+cpu=m.kernel.getOrCreateCpu(event.cpu);var stackFrame=this.getStackFrameForEvent_(event);var sample=new tr.model.Sample(cpu,thread,event.name,timestampFromUs(event.ts),stackFrame,event.weight);m.samples.push(sample);}},joinRefs:function(){this.joinObjectRefs_();},createAsyncSlices_:function(){if(this.allAsyncEvents_.length===0)
+return;this.allAsyncEvents_.sort(function(x,y){var d=x.event.ts-y.event.ts;if(d!==0)
+return d;return x.sequenceNumber-y.sequenceNumber;});var legacyEvents=[];var nestableAsyncEventsByKey={};for(var i=0;i<this.allAsyncEvents_.length;i++){var asyncEventState=this.allAsyncEvents_[i];var event=asyncEventState.event;if(event.ph==='S'||event.ph==='F'||event.ph==='T'||event.ph==='p'){legacyEvents.push(asyncEventState);continue;}
+if(event.cat===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async events (ph: b, e, or n) require a '+'cat parameter.'});continue;}
+if(event.name===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async events (ph: b, e, or n) require a '+'name parameter.'});continue;}
+if(event.id===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async events (ph: b, e, or n) require an '+'id parameter.'});continue;}
+var key=event.cat+':'+event.id;if(nestableAsyncEventsByKey[key]===undefined)
+nestableAsyncEventsByKey[key]=[];nestableAsyncEventsByKey[key].push(asyncEventState);}
+this.createLegacyAsyncSlices_(legacyEvents);for(var key in nestableAsyncEventsByKey){var eventStateEntries=nestableAsyncEventsByKey[key];var parentStack=[];for(var i=0;i<eventStateEntries.length;++i){var eventStateEntry=eventStateEntries[i];if(eventStateEntry.event.ph==='e'){var parentIndex=-1;for(var k=parentStack.length-1;k>=0;--k){if(parentStack[k].event.name===eventStateEntry.event.name){parentIndex=k;break;}}
+if(parentIndex===-1){eventStateEntry.finished=false;}else{parentStack[parentIndex].end=eventStateEntry;while(parentIndex<parentStack.length){parentStack.pop();}}}
+if(parentStack.length>0)
+eventStateEntry.parentEntry=parentStack[parentStack.length-1];if(eventStateEntry.event.ph==='b')
+parentStack.push(eventStateEntry);}
+var topLevelSlices=[];for(var i=0;i<eventStateEntries.length;++i){var eventStateEntry=eventStateEntries[i];if(eventStateEntry.event.ph==='e'&&eventStateEntry.finished===undefined){continue;}
+var startState=undefined;var endState=undefined;var sliceArgs=eventStateEntry.event.args||{};var sliceError=undefined;if(eventStateEntry.event.ph==='n'){startState=eventStateEntry;endState=eventStateEntry;}else if(eventStateEntry.event.ph==='b'){if(eventStateEntry.end===undefined){eventStateEntry.end=eventStateEntries[eventStateEntries.length-1];sliceError='Slice has no matching END. End time has been adjusted.';this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async BEGIN event at '+
+eventStateEntry.event.ts+' with name='+
+eventStateEntry.event.name+' and id='+eventStateEntry.event.id+' was unmatched.'});}else{function concatenateArguments(args1,args2){if(args1.params===undefined||args2.params===undefined)
+return tr.b.concatenateObjects(args1,args2);var args3={};args3.params=tr.b.concatenateObjects(args1.params,args2.params);return tr.b.concatenateObjects(args1,args2,args3);}
+var endArgs=eventStateEntry.end.event.args||{};sliceArgs=concatenateArguments(sliceArgs,endArgs);}
+startState=eventStateEntry;endState=eventStateEntry.end;}else{sliceError='Slice has no matching BEGIN. Start time has been adjusted.';this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async END event at '+
+eventStateEntry.event.ts+' with name='+
+eventStateEntry.event.name+' and id='+eventStateEntry.event.id+' was unmatched.'});startState=eventStateEntries[0];endState=eventStateEntry;}
+var isTopLevel=(eventStateEntry.parentEntry===undefined);var asyncSliceConstructor=tr.model.AsyncSlice.getConstructor(eventStateEntry.event.cat,eventStateEntry.event.name);var thread_start=undefined;var thread_duration=undefined;if(startState.event.tts&&startState.event.use_async_tts){thread_start=timestampFromUs(startState.event.tts);if(endState.event.tts){var thread_end=timestampFromUs(endState.event.tts);thread_duration=thread_end-thread_start;}}
+var slice=new asyncSliceConstructor(eventStateEntry.event.cat,eventStateEntry.event.name,getEventColor(endState.event),timestampFromUs(startState.event.ts),sliceArgs,timestampFromUs(endState.event.ts-startState.event.ts),isTopLevel,thread_start,thread_duration,startState.event.argsStripped);slice.startThread=startState.thread;slice.endThread=endState.thread;slice.startStackFrame=this.getStackFrameForEvent_(startState.event);slice.endStackFrame=this.getStackFrameForEvent_(endState.event);slice.id=key;if(sliceError!==undefined)
+slice.error=sliceError;eventStateEntry.slice=slice;if(isTopLevel){topLevelSlices.push(slice);}else if(eventStateEntry.parentEntry.slice!==undefined){eventStateEntry.parentEntry.slice.subSlices.push(slice);}}
+for(var si=0;si<topLevelSlices.length;si++){topLevelSlices[si].startThread.asyncSliceGroup.push(topLevelSlices[si]);}}},createLegacyAsyncSlices_:function(legacyEvents){if(legacyEvents.length===0)
+return;legacyEvents.sort(function(x,y){var d=x.event.ts-y.event.ts;if(d!=0)
+return d;return x.sequenceNumber-y.sequenceNumber;});var asyncEventStatesByNameThenID={};for(var i=0;i<legacyEvents.length;i++){var asyncEventState=legacyEvents[i];var event=asyncEventState.event;var name=event.name;if(name===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Async events (ph: S, T, p, or F) require a name '+' parameter.'});continue;}
+var id=event.id;if(id===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Async events (ph: S, T, p, or F) require an id parameter.'});continue;}
+if(event.ph==='S'){if(asyncEventStatesByNameThenID[name]===undefined)
+asyncEventStatesByNameThenID[name]={};if(asyncEventStatesByNameThenID[name][id]){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.ts+', a slice of the same id '+id+' was alrady open.'});continue;}
+asyncEventStatesByNameThenID[name][id]=[];asyncEventStatesByNameThenID[name][id].push(asyncEventState);}else{if(asyncEventStatesByNameThenID[name]===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.ts+', no slice named '+name+' was open.'});continue;}
+if(asyncEventStatesByNameThenID[name][id]===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.ts+', no slice named '+name+' with id='+id+' was open.'});continue;}
+var events=asyncEventStatesByNameThenID[name][id];events.push(asyncEventState);if(event.ph==='F'){var asyncSliceConstructor=tr.model.AsyncSlice.getConstructor(events[0].event.cat,name);var slice=new asyncSliceConstructor(events[0].event.cat,name,getEventColor(events[0].event),timestampFromUs(events[0].event.ts),tr.b.concatenateObjects(events[0].event.args,events[events.length-1].event.args),timestampFromUs(event.ts-events[0].event.ts),true,undefined,undefined,events[0].event.argsStripped);slice.startThread=events[0].thread;slice.endThread=asyncEventState.thread;slice.id=id;var stepType=events[1].event.ph;var isValid=true;for(var j=1;j<events.length-1;++j){if(events[j].event.ph==='T'||events[j].event.ph==='p'){isValid=this.assertStepTypeMatches_(stepType,events[j]);if(!isValid)
+break;}
+if(events[j].event.ph==='S'){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.event.ts+', a slice named '+
+event.event.name+' with id='+event.event.id+' had a step before the start event.'});continue;}
+if(events[j].event.ph==='F'){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.event.ts+', a slice named '+
+event.event.name+' with id='+event.event.id+' had a step after the finish event.'});continue;}
+var startIndex=j+(stepType==='T'?0:-1);var endIndex=startIndex+1;var subName=events[j].event.name;if(!events[j].event.argsStripped&&(events[j].event.ph==='T'||events[j].event.ph==='p'))
+subName=subName+':'+events[j].event.args.step;var asyncSliceConstructor=tr.model.AsyncSlice.getConstructor(events[0].event.cat,subName);var subSlice=new asyncSliceConstructor(events[0].event.cat,subName,getEventColor(event,subName+j),timestampFromUs(events[startIndex].event.ts),this.deepCopyIfNeeded_(events[j].event.args),timestampFromUs(events[endIndex].event.ts-events[startIndex].event.ts),undefined,undefined,events[startIndex].event.argsStripped);subSlice.startThread=events[startIndex].thread;subSlice.endThread=events[endIndex].thread;subSlice.id=id;slice.subSlices.push(subSlice);}
+if(isValid){slice.startThread.asyncSliceGroup.push(slice);}
+delete asyncEventStatesByNameThenID[name][id];}}}},assertStepTypeMatches_:function(stepType,event){if(stepType!=event.event.ph){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.event.ts+', a slice named '+
+event.event.name+' with id='+event.event.id+' had both begin and end steps, which is not allowed.'});return false;}
+return true;},createFlowSlices_:function(){if(this.allFlowEvents_.length===0)
+return;var that=this;function validateFlowEvent(){if(event.name===undefined){that.model_.importWarning({type:'flow_slice_parse_error',message:'Flow events (ph: s, t or f) require a name parameter.'});return false;}
+if(event.ph==='s'||event.ph==='f'||event.ph==='t'){if(event.id===undefined){that.model_.importWarning({type:'flow_slice_parse_error',message:'Flow events (ph: s, t or f) require an id parameter.'});return false;}
+return true;}
+if(event.bind_id){if(event.flow_in===undefined&&event.flow_out===undefined){that.model_.importWarning({type:'flow_slice_parse_error',message:'Flow producer or consumer require flow_in or flow_out.'});return false;}
+return true;}
+return false;}
+function createFlowEvent(thread,event,opt_slice){var startSlice,flowId,flowStartTs;if(event.bind_id){startSlice=opt_slice;flowId=event.bind_id;flowStartTs=timestampFromUs(event.ts+event.dur);}else{var ts=timestampFromUs(event.ts);startSlice=thread.sliceGroup.findSliceAtTs(ts);if(startSlice===undefined)
+return undefined;flowId=event.id;flowStartTs=ts;}
+var flowEvent=new tr.model.FlowEvent(event.cat,flowId,event.name,getEventColor(event),flowStartTs,that.deepCopyAlways_(event.args));flowEvent.startSlice=startSlice;flowEvent.startStackFrame=that.getStackFrameForEvent_(event);flowEvent.endStackFrame=undefined;startSlice.outFlowEvents.push(flowEvent);return flowEvent;}
+function finishFlowEventWith(flowEvent,thread,event,refGuid,bindToParent,opt_slice){var endSlice;if(event.bind_id){endSlice=opt_slice;}else{var ts=timestampFromUs(event.ts);if(bindToParent){endSlice=thread.sliceGroup.findSliceAtTs(ts);}else{endSlice=thread.sliceGroup.findNextSliceAfter(ts,refGuid);}
+if(endSlice===undefined)
+return false;}
+endSlice.inFlowEvents.push(flowEvent);flowEvent.endSlice=endSlice;flowEvent.duration=timestampFromUs(event.ts)-flowEvent.start;flowEvent.endStackFrame=that.getStackFrameForEvent_(event);that.mergeArgsInto_(flowEvent.args,event.args,flowEvent.title);return true;}
+function processFlowConsumer(flowIdToEvent,sliceGuidToEvent,event,slice){var flowEvent=flowIdToEvent[event.bind_id];if(flowEvent===undefined){that.model_.importWarning({type:'flow_slice_ordering_error',message:'Flow consumer '+event.bind_id+' does not have '+'a flow producer'});return false;}else if(flowEvent.endSlice){var flowProducer=flowEvent.startSlice;flowEvent=createFlowEvent(undefined,sliceGuidToEvent[flowProducer.guid],flowProducer);}
+var ok=finishFlowEventWith(flowEvent,undefined,event,refGuid,undefined,slice);if(ok){that.model_.flowEvents.push(flowEvent);}else{that.model_.importWarning({type:'flow_slice_end_error',message:'Flow consumer '+event.bind_id+' does not end '+'at an actual slice, so cannot be created.'});return false;}
+return true;}
+function processFlowProducer(flowIdToEvent,flowStatus,event,slice){if(flowIdToEvent[event.bind_id]&&flowStatus[event.bind_id]){that.model_.importWarning({type:'flow_slice_start_error',message:'Flow producer '+event.bind_id+' already seen'});return false;}
+var flowEvent=createFlowEvent(undefined,event,slice);if(!flowEvent){that.model_.importWarning({type:'flow_slice_start_error',message:'Flow producer '+event.bind_id+' does not start'+'a flow'});return false;}
+flowIdToEvent[event.bind_id]=flowEvent;return;}
+this.allFlowEvents_.sort(function(x,y){var d=x.event.ts-y.event.ts;if(d!=0)
+return d;return x.sequenceNumber-y.sequenceNumber;});var flowIdToEvent={};var sliceGuidToEvent={};var flowStatus={};for(var i=0;i<this.allFlowEvents_.length;++i){var data=this.allFlowEvents_[i];var refGuid=data.refGuid;var event=data.event;var thread=data.thread;if(!validateFlowEvent(event))
+continue;if(event.bind_id){var slice=data.slice;sliceGuidToEvent[slice.guid]=event;if(event.flowPhase===PRODUCER){if(!processFlowProducer(flowIdToEvent,flowStatus,event,slice))
+continue;flowStatus[event.bind_id]=true;}
+else{if(!processFlowConsumer(flowIdToEvent,sliceGuidToEvent,event,slice))
+continue;flowStatus[event.bind_id]=false;if(event.flowPhase===STEP){if(!processFlowProducer(flowIdToEvent,flowStatus,event,slice))
+continue;flowStatus[event.bind_id]=true;}}
+continue;}
+var flowEvent;if(event.ph==='s'){if(flowIdToEvent[event.id]){this.model_.importWarning({type:'flow_slice_start_error',message:'event id '+event.id+' already seen when '+'encountering start of flow event.'});continue;}
+flowEvent=createFlowEvent(thread,event);if(!flowEvent){this.model_.importWarning({type:'flow_slice_start_error',message:'event id '+event.id+' does not start '+'at an actual slice, so cannot be created.'});continue;}
+flowIdToEvent[event.id]=flowEvent;}else if(event.ph==='t'||event.ph==='f'){flowEvent=flowIdToEvent[event.id];if(flowEvent===undefined){this.model_.importWarning({type:'flow_slice_ordering_error',message:'Found flow phase '+event.ph+' for id: '+event.id+' but no flow start found.'});continue;}
+var bindToParent=event.ph==='t';if(event.ph==='f'){if(event.bp===undefined){if(event.cat.indexOf('input')>-1)
+bindToParent=true;else if(event.cat.indexOf('ipc.flow')>-1)
+bindToParent=true;}else{if(event.bp!=='e'){this.model_.importWarning({type:'flow_slice_bind_point_error',message:'Flow event with invalid binding point (event.bp).'});continue;}
+bindToParent=true;}}
+var ok=finishFlowEventWith(flowEvent,thread,event,refGuid,bindToParent);if(ok){that.model_.flowEvents.push(flowEvent);}else{this.model_.importWarning({type:'flow_slice_end_error',message:'event id '+event.id+' does not end '+'at an actual slice, so cannot be created.'});}
+flowIdToEvent[event.id]=undefined;if(ok&&event.ph==='t'){flowEvent=createFlowEvent(thread,event);flowIdToEvent[event.id]=flowEvent;}}}},createExplicitObjects_:function(){if(this.allObjectEvents_.length===0)
+return;function processEvent(objectEventState){var event=objectEventState.event;var thread=objectEventState.thread;if(event.name===undefined){this.model_.importWarning({type:'object_parse_error',message:'While processing '+JSON.stringify(event)+': '+'Object events require an name parameter.'});}
+if(event.id===undefined){this.model_.importWarning({type:'object_parse_error',message:'While processing '+JSON.stringify(event)+': '+'Object events require an id parameter.'});}
+var process=thread.parent;var ts=timestampFromUs(event.ts);var instance;if(event.ph==='N'){try{instance=process.objects.idWasCreated(event.id,event.cat,event.name,ts);}catch(e){this.model_.importWarning({type:'object_parse_error',message:'While processing create of '+
+event.id+' at ts='+ts+': '+e});return;}}else if(event.ph==='O'){if(event.args.snapshot===undefined){this.model_.importWarning({type:'object_parse_error',message:'While processing '+event.id+' at ts='+ts+': '+'Snapshots must have args: {snapshot: ...}'});return;}
+var snapshot;try{var args=this.deepCopyIfNeeded_(event.args.snapshot);var cat;if(args.cat){cat=args.cat;delete args.cat;}else{cat=event.cat;}
+var baseTypename;if(args.base_type){baseTypename=args.base_type;delete args.base_type;}else{baseTypename=undefined;}
+snapshot=process.objects.addSnapshot(event.id,cat,event.name,ts,args,baseTypename);snapshot.snapshottedOnThread=thread;}catch(e){this.model_.importWarning({type:'object_parse_error',message:'While processing snapshot of '+
+event.id+' at ts='+ts+': '+e});return;}
+instance=snapshot.objectInstance;}else if(event.ph==='D'){try{process.objects.idWasDeleted(event.id,event.cat,event.name,ts);var instanceMap=process.objects.getOrCreateInstanceMap_(event.id);instance=instanceMap.lastInstance;}catch(e){this.model_.importWarning({type:'object_parse_error',message:'While processing delete of '+
+event.id+' at ts='+ts+': '+e});return;}}
+if(instance)
+instance.colorId=getEventColor(event,instance.typeName);}
+this.allObjectEvents_.sort(function(x,y){var d=x.event.ts-y.event.ts;if(d!=0)
+return d;return x.sequenceNumber-y.sequenceNumber;});var allObjectEvents=this.allObjectEvents_;for(var i=0;i<allObjectEvents.length;i++){var objectEventState=allObjectEvents[i];try{processEvent.call(this,objectEventState);}catch(e){this.model_.importWarning({type:'object_parse_error',message:e.message});}}},createImplicitObjects_:function(){tr.b.iterItems(this.model_.processes,function(pid,process){this.createImplicitObjectsForProcess_(process);},this);},createImplicitObjectsForProcess_:function(process){function processField(referencingObject,referencingObjectFieldName,referencingObjectFieldValue,containingSnapshot){if(!referencingObjectFieldValue)
+return;if(referencingObjectFieldValue instanceof
+tr.model.ObjectSnapshot)
+return null;if(referencingObjectFieldValue.id===undefined)
+return;var implicitSnapshot=referencingObjectFieldValue;var rawId=implicitSnapshot.id;var m=/(.+)\/(.+)/.exec(rawId);if(!m)
+throw new Error('Implicit snapshots must have names.');delete implicitSnapshot.id;var name=m[1];var id=m[2];var res;var cat;if(implicitSnapshot.cat!==undefined)
+cat=implicitSnapshot.cat;else
+cat=containingSnapshot.objectInstance.category;var baseTypename;if(implicitSnapshot.base_type)
+baseTypename=implicitSnapshot.base_type;else
+baseTypename=undefined;try{res=process.objects.addSnapshot(id,cat,name,containingSnapshot.ts,implicitSnapshot,baseTypename);}catch(e){this.model_.importWarning({type:'object_snapshot_parse_error',message:'While processing implicit snapshot of '+
+rawId+' at ts='+containingSnapshot.ts+': '+e});return;}
+res.objectInstance.hasImplicitSnapshots=true;res.containingSnapshot=containingSnapshot;res.snapshottedOnThread=containingSnapshot.snapshottedOnThread;referencingObject[referencingObjectFieldName]=res;if(!(res instanceof tr.model.ObjectSnapshot))
+throw new Error('Created object must be instanceof snapshot');return res.args;}
+function iterObject(object,func,containingSnapshot,thisArg){if(!(object instanceof Object))
+return;if(object instanceof Array){for(var i=0;i<object.length;i++){var res=func.call(thisArg,object,i,object[i],containingSnapshot);if(res===null)
+continue;if(res)
+iterObject(res,func,containingSnapshot,thisArg);else
+iterObject(object[i],func,containingSnapshot,thisArg);}
+return;}
+for(var key in object){var res=func.call(thisArg,object,key,object[key],containingSnapshot);if(res===null)
+continue;if(res)
+iterObject(res,func,containingSnapshot,thisArg);else
+iterObject(object[key],func,containingSnapshot,thisArg);}}
+process.objects.iterObjectInstances(function(instance){instance.snapshots.forEach(function(snapshot){if(snapshot.args.id!==undefined)
+throw new Error('args cannot have an id field inside it');iterObject(snapshot.args,processField,snapshot,this);},this);},this);},createMemoryDumps_:function(){tr.b.iterItems(this.allMemoryDumpEvents_,function(id,events){var range=new tr.b.Range();if(events.global!==undefined)
+range.addValue(timestampFromUs(events.global.ts));for(var i=0;i<events.process.length;i++)
+range.addValue(timestampFromUs(events.process[i].ts));var globalMemoryDump=new tr.model.GlobalMemoryDump(this.model_,range.min);globalMemoryDump.duration=range.range;this.model_.globalMemoryDumps.push(globalMemoryDump);if(events.process.length===0){this.model_.importWarning({type:'memory_dump_parse_error',message:'No process memory dumps associated with global memory'+' dump '+id+'.'});}
+var allMemoryAllocatorDumpsByGuid={};var globalMemoryAllocatorDumpsByFullName={};var LEVELS_OF_DETAIL=[undefined,'light','detailed'];var globalLevelOfDetailIndex=undefined;events.process.forEach(function(processEvent){var pid=processEvent.pid;if(pid in globalMemoryDump.processMemoryDumps){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple process memory dumps with pid='+pid+' for dump id '+id+'.'});return;}
+var dumps=processEvent.args.dumps;if(dumps===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'dumps not found in process memory dump for '+'pid='+pid+' and dump id='+id+'.'});return;}
+var process=this.model_.getOrCreateProcess(pid);var processMemoryDump=new tr.model.ProcessMemoryDump(globalMemoryDump,process,timestampFromUs(processEvent.ts));var processLevelOfDetail=dumps.level_of_detail;var processLevelOfDetailIndex=LEVELS_OF_DETAIL.indexOf(processLevelOfDetail);if(processLevelOfDetailIndex<0){this.model_.importWarning({type:'memory_dump_parse_error',message:'unknown level of detail \''+processLevelOfDetail+'\' of process memory dump for pid='+pid+' and dump id='+id+'.'});}else{processMemoryDump.levelOfDetail=processLevelOfDetail;if(globalLevelOfDetailIndex===undefined){globalLevelOfDetailIndex=processLevelOfDetailIndex;}else if(globalLevelOfDetailIndex!==processLevelOfDetailIndex){this.model_.importWarning({type:'memory_dump_parse_error',message:'diffent levels of detail of process memory dumps '+'for dump id='+id+'.'});globalLevelOfDetailIndex=Math.max(globalLevelOfDetailIndex,processLevelOfDetailIndex);}}
+var rawTotals=dumps.process_totals;if(rawTotals!==undefined){processMemoryDump.totals={};if(rawTotals.resident_set_bytes!==undefined){processMemoryDump.totals.residentBytes=parseInt(rawTotals.resident_set_bytes,16);}
+if(rawTotals.peak_resident_set_bytes!==undefined){if(rawTotals.is_peak_rss_resetable===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Optional field peak_resident_set_bytes found'+' but is_peak_rss_resetable not found in'+' process memory dump for pid='+pid+' and dump id='+id+'.'});}
+processMemoryDump.totals.peakResidentBytes=parseInt(rawTotals.peak_resident_set_bytes,16);}
+if(rawTotals.is_peak_rss_resetable!==undefined){if(rawTotals.peak_resident_set_bytes===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Optional field is_peak_rss_resetable found'+' but peak_resident_set_bytes not found in'+' process memory dump for pid='+pid+' and dump id='+id+'.'});}
+processMemoryDump.totals.arePeakResidentBytesResettable=!!rawTotals.is_peak_rss_resetable;}}
+if(processMemoryDump.totals===undefined||processMemoryDump.totals.residentBytes===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Mandatory field resident_set_bytes not found in'+' process memory dump for pid='+pid+' and dump id='+id+'.'});}
+if(dumps.process_mmaps&&dumps.process_mmaps.vm_regions){function parseByteStat(rawValue){if(rawValue===undefined)
+return undefined;return parseInt(rawValue,16);}
+processMemoryDump.vmRegions=dumps.process_mmaps.vm_regions.map(function(rawRegion){var byteStats=new tr.model.VMRegionByteStats(parseByteStat(rawRegion.bs.pc),parseByteStat(rawRegion.bs.pd),parseByteStat(rawRegion.bs.sc),parseByteStat(rawRegion.bs.sd),parseByteStat(rawRegion.bs.pss),parseByteStat(rawRegion.bs.sw));return new tr.model.VMRegion(parseInt(rawRegion.sa,16),parseInt(rawRegion.sz,16),rawRegion.pf,rawRegion.mf,byteStats);});}
+var processMemoryAllocatorDumpsByFullName={};if(dumps.allocators!==undefined){tr.b.iterItems(dumps.allocators,function(fullName,rawAllocatorDump){var guid=rawAllocatorDump.guid;if(guid===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+fullName+' from pid='+pid+' does not have a GUID.'});}
+var GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX='global/';var containerMemoryDump;var dstIndex;if(fullName.startsWith(GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX)){fullName=fullName.substring(GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX.length);containerMemoryDump=globalMemoryDump;dstIndex=globalMemoryAllocatorDumpsByFullName;}else{containerMemoryDump=processMemoryDump;dstIndex=processMemoryAllocatorDumpsByFullName;}
+var allocatorDump=allMemoryAllocatorDumpsByGuid[guid];if(allocatorDump===undefined){if(fullName in dstIndex){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple GUIDs provided for'+' memory allocator dump '+fullName+': '+
+dstIndex[fullName].guid+', '+guid+' (ignored).'});return;}
+allocatorDump=new tr.model.MemoryAllocatorDump(containerMemoryDump,fullName,guid);dstIndex[fullName]=allocatorDump;if(guid!==undefined)
+allMemoryAllocatorDumpsByGuid[guid]=allocatorDump;}else{if(allocatorDump.containerMemoryDump!==containerMemoryDump){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+fullName+' (GUID='+guid+') dumped in different contexts.'});return;}
+if(allocatorDump.fullName!==fullName){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump with GUID='+guid+' has multiple names: '+allocatorDump.fullName+', '+fullName+' (ignored).'});return;}}
+var attributes=rawAllocatorDump.attrs;if(attributes===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+fullName+' from pid='+pid+' (GUID='+guid+') does not'+' have attributes.'});attributes={};}
+tr.b.iterItems(attributes,function(attrName,attrArgs){if(attrName in allocatorDump.attributes){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple values provided for attribute '+
+attrName+' of memory allocator dump '+fullName+' (GUID='+guid+').'});return;}
+var attrValue=tr.model.Attribute.fromDictIfPossible(attrArgs);allocatorDump.addAttribute(attrName,attrValue);},this);},this);}
+processMemoryDump.memoryAllocatorDumps=this.inferMemoryAllocatorDumpTree_(processMemoryAllocatorDumpsByFullName);if(dumps.heaps!==undefined){processMemoryDump.heapDumps=tr.b.mapItems(dumps.heaps,this.parseHeapDump_.bind(this,processMemoryDump));}
+process.memoryDumps.push(processMemoryDump);globalMemoryDump.processMemoryDumps[pid]=processMemoryDump;},this);globalMemoryDump.levelOfDetail=LEVELS_OF_DETAIL[globalLevelOfDetailIndex];globalMemoryDump.memoryAllocatorDumps=this.inferMemoryAllocatorDumpTree_(globalMemoryAllocatorDumpsByFullName);events.process.forEach(function(processEvent){var dumps=processEvent.args.dumps;if(dumps===undefined)
+return;var edges=dumps.allocators_graph;if(edges===undefined)
+return;edges.forEach(function(rawEdge){var sourceGuid=rawEdge.source;var sourceDump=allMemoryAllocatorDumpsByGuid[sourceGuid];if(sourceDump===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Edge is missing source memory allocator dump (GUID='+
+sourceGuid+')'});return;}
+var targetGuid=rawEdge.target;var targetDump=allMemoryAllocatorDumpsByGuid[targetGuid];if(targetDump===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Edge is missing target memory allocator dump (GUID='+
+targetGuid+')'});return;}
+var importance=rawEdge.importance;var edge=new tr.model.MemoryAllocatorDumpLink(sourceDump,targetDump,importance);switch(rawEdge.type){case'ownership':if(sourceDump.owns!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+sourceDump.fullName+' (GUID='+sourceGuid+') already owns a memory'+' allocator dump ('+
+sourceDump.owns.target.fullName+').'});return;}
+sourceDump.owns=edge;targetDump.ownedBy.push(edge);break;case'retention':sourceDump.retains.push(edge);targetDump.retainedBy.push(edge);break;default:this.model_.importWarning({type:'memory_dump_parse_error',message:'Invalid edge type: '+rawEdge.type+' (source='+sourceGuid+', target='+targetGuid+', importance='+importance+').'});}},this);},this);},this);},inferMemoryAllocatorDumpTree_:function(memoryAllocatorDumpsByFullName){var rootAllocatorDumps=[];var fullNames=Object.keys(memoryAllocatorDumpsByFullName);fullNames.sort();fullNames.forEach(function(fullName){var allocatorDump=memoryAllocatorDumpsByFullName[fullName];while(true){var lastSlashIndex=fullName.lastIndexOf('/');if(lastSlashIndex===-1){rootAllocatorDumps.push(allocatorDump);break;}
+var parentFullName=fullName.substring(0,lastSlashIndex);var parentAllocatorDump=memoryAllocatorDumpsByFullName[parentFullName];var parentAlreadyExisted=true;if(parentAllocatorDump===undefined){parentAlreadyExisted=false;parentAllocatorDump=new tr.model.MemoryAllocatorDump(allocatorDump.containerMemoryDump,parentFullName);memoryAllocatorDumpsByFullName[parentFullName]=parentAllocatorDump;}
+allocatorDump.parent=parentAllocatorDump;parentAllocatorDump.children.push(allocatorDump);if(parentAlreadyExisted)
+break;fullName=parentFullName;allocatorDump=parentAllocatorDump;}},this);return rootAllocatorDumps;},parseHeapDump_:function(processMemoryDump,allocatorName,rawHeapDump){var pid=processMemoryDump.process.pid;var entries=rawHeapDump.entries;if(entries===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing heap entries in a '+allocatorName+' heap dump for pid='+pid+'.'});return undefined;}
+var model=this.model_;var heapDump=new tr.model.HeapDump(processMemoryDump,allocatorName);var idPrefix='p'+pid+':';for(var i=0;i<entries.length;i++){var entry=entries[i];var size=parseInt(entry.size,16);var leafStackFrameIndex=entry.bt;var leafStackFrame;if(leafStackFrameIndex===undefined){leafStackFrame=undefined;}else{var leafStackFrameId=idPrefix+leafStackFrameIndex;leafStackFrame=model.stackFrames[leafStackFrameId];if(leafStackFrame===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing leaf stack frame (ID '+leafStackFrameId+') of heap entry '+i+' (size '+size+') in a '+
+allocatorName+' heap dump for pid='+pid+'.'});continue;}}
+heapDump.addEntry(leafStackFrame,size);}
+return heapDump;},joinObjectRefs_:function(){tr.b.iterItems(this.model_.processes,function(pid,process){this.joinObjectRefsForProcess_(process);},this);},joinObjectRefsForProcess_:function(process){var patchupsToApply=[];tr.b.iterItems(process.threads,function(tid,thread){thread.asyncSliceGroup.slices.forEach(function(item){this.searchItemForIDRefs_(patchupsToApply,process.objects,'start',item);},this);thread.sliceGroup.slices.forEach(function(item){this.searchItemForIDRefs_(patchupsToApply,process.objects,'start',item);},this);},this);process.objects.iterObjectInstances(function(instance){instance.snapshots.forEach(function(item){this.searchItemForIDRefs_(patchupsToApply,process.objects,'ts',item);},this);},this);patchupsToApply.forEach(function(patchup){patchup.object[patchup.field]=patchup.value;});},searchItemForIDRefs_:function(patchupsToApply,objectCollection,itemTimestampField,item){if(!item.args)
+throw new Error('item is missing its args');function handleField(object,fieldName,fieldValue){if(!fieldValue||(!fieldValue.id_ref&&!fieldValue.idRef))
+return;var id=fieldValue.id_ref||fieldValue.idRef;var ts=item[itemTimestampField];var snapshot=objectCollection.getSnapshotAt(id,ts);if(!snapshot)
+return;patchupsToApply.push({object:object,field:fieldName,value:snapshot});}
+function iterObjectFieldsRecursively(object){if(!(object instanceof Object))
+return;if((object instanceof tr.model.ObjectSnapshot)||(object instanceof Float32Array)||(object instanceof tr.b.Quad))
+return;if(object instanceof Array){for(var i=0;i<object.length;i++){handleField(object,i,object[i]);iterObjectFieldsRecursively(object[i]);}
+return;}
+for(var key in object){var value=object[key];handleField(object,key,value);iterObjectFieldsRecursively(value);}}
+iterObjectFieldsRecursively(item.args);}};tr.importer.Importer.register(TraceEventImporter);return{TraceEventImporter:TraceEventImporter};});'use strict';tr.exportTo('tr.e.importer',function(){var GZIP_MEMBER_HEADER_ID_SIZE=3;var GZIP_HEADER_ID1=0x1f;var GZIP_HEADER_ID2=0x8b;var GZIP_DEFLATE_COMPRESSION=8;function GzipImporter(model,eventData){if(typeof(eventData)==='string'||eventData instanceof String){eventData=JSZip.utils.transformTo('uint8array',eventData);}else if(eventData instanceof ArrayBuffer){eventData=new Uint8Array(eventData);}else
+throw new Error('Unknown gzip data format');this.model_=model;this.gzipData_=eventData;}
+GzipImporter.canImport=function(eventData){var header;if(eventData instanceof ArrayBuffer)
+header=new Uint8Array(eventData.slice(0,GZIP_MEMBER_HEADER_ID_SIZE));else if(typeof(eventData)==='string'||eventData instanceof String){header=eventData.substring(0,GZIP_MEMBER_HEADER_ID_SIZE);header=JSZip.utils.transformTo('uint8array',header);}else
+return false;return header[0]==GZIP_HEADER_ID1&&header[1]==GZIP_HEADER_ID2&&header[2]==GZIP_DEFLATE_COMPRESSION;};GzipImporter.inflateGzipData_=function(data){var position=0;function getByte(){if(position>=data.length)
+throw new Error('Unexpected end of gzip data');return data[position++];}
+function getWord(){var low=getByte();var high=getByte();return(high<<8)+low;}
+function skipBytes(amount){position+=amount;}
+function skipZeroTerminatedString(){while(getByte()!=0){}}
+var id1=getByte();var id2=getByte();if(id1!==GZIP_HEADER_ID1||id2!==GZIP_HEADER_ID2)
+throw new Error('Not gzip data');var compression_method=getByte();if(compression_method!==GZIP_DEFLATE_COMPRESSION)
+throw new Error('Unsupported compression method: '+compression_method);var flags=getByte();var have_header_crc=flags&(1<<1);var have_extra_fields=flags&(1<<2);var have_file_name=flags&(1<<3);var have_comment=flags&(1<<4);skipBytes(4+1+1);if(have_extra_fields){var bytes_to_skip=getWord();skipBytes(bytes_to_skip);}
+if(have_file_name)
+skipZeroTerminatedString();if(have_comment)
+skipZeroTerminatedString();if(have_header_crc)
+getWord();var inflated_data=JSZip.compressions['DEFLATE'].uncompress(data.subarray(position));return JSZip.utils.transformTo('string',inflated_data);},GzipImporter.prototype={__proto__:tr.importer.Importer.prototype,isTraceDataContainer:function(){return true;},extractSubtraces:function(){var eventData=GzipImporter.inflateGzipData_(this.gzipData_);return eventData?[eventData]:[];}};tr.importer.Importer.register(GzipImporter);return{GzipImporter:GzipImporter};});'use strict';tr.exportTo('tr.e.importer',function(){function ZipImporter(model,eventData){if(eventData instanceof ArrayBuffer)
+eventData=new Uint8Array(eventData);this.model_=model;this.eventData_=eventData;}
+ZipImporter.canImport=function(eventData){var header;if(eventData instanceof ArrayBuffer)
+header=new Uint8Array(eventData.slice(0,2));else if(typeof(eventData)==='string'||eventData instanceof String)
+header=[eventData.charCodeAt(0),eventData.charCodeAt(1)];else
+return false;return header[0]==='P'.charCodeAt(0)&&header[1]==='K'.charCodeAt(0);};ZipImporter.prototype={__proto__:tr.importer.Importer.prototype,isTraceDataContainer:function(){return true;},extractSubtraces:function(){var zip=new JSZip(this.eventData_);var subtraces=[];for(var idx in zip.files)
+subtraces.push(zip.files[idx].asBinary());return subtraces;}};tr.importer.Importer.register(ZipImporter);return{ZipImporter:ZipImporter};});'use strict';tr.exportTo('tr.e.importer.v8',function(){function CsvParser(){};CsvParser.CSV_FIELD_RE_=/^"((?:[^"]|"")*)"|([^,]*)/;CsvParser.DOUBLE_QUOTE_RE_=/""/g;CsvParser.prototype.parseLine=function(line){var fieldRe=CsvParser.CSV_FIELD_RE_;var doubleQuoteRe=CsvParser.DOUBLE_QUOTE_RE_;var pos=0;var endPos=line.length;var fields=[];if(endPos>0){do{var fieldMatch=fieldRe.exec(line.substr(pos));if(typeof fieldMatch[1]==='string'){var field=fieldMatch[1];pos+=field.length+3;fields.push(field.replace(doubleQuoteRe,'"'));}else{var field=fieldMatch[2];pos+=field.length+1;fields.push(field);}}while(pos<=endPos);}
+return fields;};function LogReader(dispatchTable){this.dispatchTable_=dispatchTable;this.lineNum_=0;this.csvParser_=new CsvParser();};LogReader.prototype.printError=function(str){};LogReader.prototype.processLogChunk=function(chunk){this.processLog_(chunk.split('\n'));};LogReader.prototype.processLogLine=function(line){this.processLog_([line]);};LogReader.prototype.processStack=function(pc,func,stack){var fullStack=func?[pc,func]:[pc];var prevFrame=pc;for(var i=0,n=stack.length;i<n;++i){var frame=stack[i];var firstChar=frame.charAt(0);if(firstChar=='+'||firstChar=='-'){prevFrame+=parseInt(frame,16);fullStack.push(prevFrame);}else if(firstChar!='o'){fullStack.push(parseInt(frame,16));}}
+return fullStack;};LogReader.prototype.skipDispatch=function(dispatch){return false;};LogReader.prototype.dispatchLogRow_=function(fields){var command=fields[0];if(!(command in this.dispatchTable_))return;var dispatch=this.dispatchTable_[command];if(dispatch===null||this.skipDispatch(dispatch)){return;}
+var parsedFields=[];for(var i=0;i<dispatch.parsers.length;++i){var parser=dispatch.parsers[i];if(parser===null){parsedFields.push(fields[1+i]);}else if(typeof parser=='function'){parsedFields.push(parser(fields[1+i]));}else{parsedFields.push(fields.slice(1+i));break;}}
+dispatch.processor.apply(this,parsedFields);};LogReader.prototype.processLog_=function(lines){for(var i=0,n=lines.length;i<n;++i,++this.lineNum_){var line=lines[i];if(!line){continue;}
+try{var fields=this.csvParser_.parseLine(line);this.dispatchLogRow_(fields);}catch(e){this.printError('line '+(this.lineNum_+1)+': '+
+(e.message||e));}}};return{LogReader:LogReader};});'use strict';tr.exportTo('tr.e.importer.v8',function(){var ColorScheme=tr.b.ColorScheme;function V8LogImporter(model,eventData){this.importPriority=3;this.model_=model;this.logData_=eventData;this.code_map_=new tr.e.importer.v8.CodeMap();this.v8_timer_thread_=undefined;this.v8_thread_=undefined;this.root_stack_frame_=new tr.model.StackFrame(undefined,'v8-root-stack-frame','v8-root-stack-frame',0);this.v8_stack_timeline_=new Array();}
+var kV8BinarySuffixes=['/d8','/libv8.so'];var TimerEventDefaultArgs={'V8.Execute':{pause:false,no_execution:false},'V8.External':{pause:false,no_execution:true},'V8.CompileFullCode':{pause:true,no_execution:true},'V8.RecompileSynchronous':{pause:true,no_execution:true},'V8.RecompileParallel':{pause:false,no_execution:false},'V8.CompileEval':{pause:true,no_execution:true},'V8.Parse':{pause:true,no_execution:true},'V8.PreParse':{pause:true,no_execution:true},'V8.ParseLazy':{pause:true,no_execution:true},'V8.GCScavenger':{pause:true,no_execution:true},'V8.GCCompactor':{pause:true,no_execution:true},'V8.GCContext':{pause:true,no_execution:true}};V8LogImporter.canImport=function(eventData){if(typeof(eventData)!=='string'&&!(eventData instanceof String))
+return false;return eventData.substring(0,11)=='v8-version,'||eventData.substring(0,12)=='timer-event,'||eventData.substring(0,5)=='tick,'||eventData.substring(0,15)=='shared-library,'||eventData.substring(0,9)=='profiler,'||eventData.substring(0,14)=='code-creation,';};V8LogImporter.prototype={__proto__:tr.importer.Importer.prototype,processTimerEvent_:function(name,start,length){var args=TimerEventDefaultArgs[name];if(args===undefined)return;start/=1000;length/=1000;var colorId=ColorScheme.getColorIdForGeneralPurposeString(name);var slice=new tr.model.Slice('v8',name,colorId,start,args,length);this.v8_timer_thread_.sliceGroup.pushSlice(slice);},processTimerEventStart_:function(name,start){var args=TimerEventDefaultArgs[name];if(args===undefined)return;start/=1000;this.v8_timer_thread_.sliceGroup.beginSlice('v8',name,start,args);},processTimerEventEnd_:function(name,end){end/=1000;this.v8_timer_thread_.sliceGroup.endSlice(end);},processCodeCreateEvent_:function(type,kind,address,size,name){var code_entry=new tr.e.importer.v8.CodeMap.CodeEntry(size,name);code_entry.kind=kind;this.code_map_.addCode(address,code_entry);},processCodeMoveEvent_:function(from,to){this.code_map_.moveCode(from,to);},processCodeDeleteEvent_:function(address){this.code_map_.deleteCode(address);},processSharedLibrary_:function(name,start,end){var code_entry=new tr.e.importer.v8.CodeMap.CodeEntry(end-start,name);code_entry.kind=-3;for(var i=0;i<kV8BinarySuffixes.length;i++){var suffix=kV8BinarySuffixes[i];if(name.indexOf(suffix,name.length-suffix.length)>=0){code_entry.kind=-1;break;}}
+this.code_map_.addLibrary(start,code_entry);},findCodeKind_:function(kind){for(name in CodeKinds){if(CodeKinds[name].kinds.indexOf(kind)>=0){return CodeKinds[name];}}},processTickEvent_:function(pc,start,unused_x,unused_y,vmstate,stack){start/=1000;function findChildWithEntryID(stackFrame,entryID){for(var i=0;i<stackFrame.children.length;i++){if(stackFrame.children[i].entryID==entryID)
+return stackFrame.children[i];}
+return undefined;}
+var lastStackFrame;if(stack&&stack.length){lastStackFrame=this.root_stack_frame_;stack=stack.reverse();for(var i=0;i<stack.length;i++){if(!stack[i])
+break;var entry=this.code_map_.findEntry(stack[i]);var entryID=entry?entry.id:'Unknown';var childFrame=findChildWithEntryID(lastStackFrame,entryID);if(childFrame===undefined){var entryName=entry?entry.name:'Unknown';lastStackFrame=new tr.model.StackFrame(lastStackFrame,'v8sf-'+tr.b.GUID.allocate(),entryName,ColorScheme.getColorIdForGeneralPurposeString(entryName));lastStackFrame.entryID=entryID;this.model_.addStackFrame(lastStackFrame);}else{lastStackFrame=childFrame;}}}else{var pcEntry=this.code_map_.findEntry(pc);var pcEntryID='v8pc-'+(pcEntry?pcEntry.id:'Unknown');if(this.model_.stackFrames[pcEntryID]===undefined){var pcEntryName=pcEntry?pcEntry.name:'Unknown';lastStackFrame=new tr.model.StackFrame(undefined,pcEntryID,pcEntryName,ColorScheme.getColorIdForGeneralPurposeString(pcEntryName));this.model_.addStackFrame(lastStackFrame);}
+lastStackFrame=this.model_.stackFrames[pcEntryID];}
+var sample=new tr.model.Sample(undefined,this.v8_thread_,'V8 PC',start,lastStackFrame,1);this.model_.samples.push(sample);},processDistortion_:function(distortion_in_picoseconds){distortion_per_entry=distortion_in_picoseconds/1000000;},processPlotRange_:function(start,end){xrange_start_override=start;xrange_end_override=end;},processV8Version_:function(major,minor,build,patch,candidate){},importEvents:function(){var logreader=new tr.e.importer.v8.LogReader({'timer-event':{parsers:[null,parseInt,parseInt],processor:this.processTimerEvent_.bind(this)},'shared-library':{parsers:[null,parseInt,parseInt],processor:this.processSharedLibrary_.bind(this)},'timer-event-start':{parsers:[null,parseInt],processor:this.processTimerEventStart_.bind(this)},'timer-event-end':{parsers:[null,parseInt],processor:this.processTimerEventEnd_.bind(this)},'code-creation':{parsers:[null,parseInt,parseInt,parseInt,null],processor:this.processCodeCreateEvent_.bind(this)},'code-move':{parsers:[parseInt,parseInt],processor:this.processCodeMoveEvent_.bind(this)},'code-delete':{parsers:[parseInt],processor:this.processCodeDeleteEvent_.bind(this)},'tick':{parsers:[parseInt,parseInt,null,null,parseInt,'var-args'],processor:this.processTickEvent_.bind(this)},'distortion':{parsers:[parseInt],processor:this.processDistortion_.bind(this)},'plot-range':{parsers:[parseInt,parseInt],processor:this.processPlotRange_.bind(this)},'v8-version':{parsers:[parseInt,parseInt,parseInt,parseInt,parseInt],processor:this.processV8Version_.bind(this)}});this.v8_timer_thread_=this.model_.getOrCreateProcess(-32).getOrCreateThread(1);this.v8_timer_thread_.name='V8 Timers';this.v8_thread_=this.model_.getOrCreateProcess(-32).getOrCreateThread(2);this.v8_thread_.name='V8';var lines=this.logData_.split('\n');for(var i=0;i<lines.length;i++){logreader.processLogLine(lines[i]);}
+this.root_stack_frame_.removeAllChildren();function addSlices(slices,thread){for(var i=0;i<slices.length;i++){var duration=slices[i].end-slices[i].start;var slice=new tr.model.Slice('v8',slices[i].name,ColorScheme.getColorIdForGeneralPurposeString(slices[i].name),slices[i].start,{},duration);thread.sliceGroup.pushSlice(slice);addSlices(slices[i].children,thread);}}
+addSlices(this.v8_stack_timeline_,this.v8_thread_);}};tr.importer.Importer.register(V8LogImporter);return{V8LogImporter:V8LogImporter};});'use strict';tr.exportTo('tr.e.importer.etw',function(){function Parser(importer){this.importer=importer;this.model=importer.model;}
+Parser.prototype={__proto__:Object.prototype};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.mandatoryBaseClass=Parser;tr.b.decorateExtensionRegistry(Parser,options);return{Parser:Parser};});'use strict';tr.exportTo('tr.e.importer.etw',function(){var Parser=tr.e.importer.etw.Parser;var guid='68FDD900-4A3E-11D1-84F4-0000F80464E3';var kEventTraceHeaderOpcode=0;function EventTraceParser(importer){Parser.call(this,importer);importer.registerEventHandler(guid,kEventTraceHeaderOpcode,EventTraceParser.prototype.decodeHeader.bind(this));}
+EventTraceParser.prototype={__proto__:Parser.prototype,decodeFields:function(header,decoder){if(header.version!=2)
+throw new Error('Incompatible EventTrace event version.');var bufferSize=decoder.decodeUInt32();var version=decoder.decodeUInt32();var providerVersion=decoder.decodeUInt32();var numberOfProcessors=decoder.decodeUInt32();var endTime=decoder.decodeUInt64ToString();var timerResolution=decoder.decodeUInt32();var maxFileSize=decoder.decodeUInt32();var logFileMode=decoder.decodeUInt32();var buffersWritten=decoder.decodeUInt32();var startBuffers=decoder.decodeUInt32();var pointerSize=decoder.decodeUInt32();var eventsLost=decoder.decodeUInt32();var cpuSpeed=decoder.decodeUInt32();var loggerName=decoder.decodeUInteger(header.is64);var logFileName=decoder.decodeUInteger(header.is64);var timeZoneInformation=decoder.decodeTimeZoneInformation();var padding=decoder.decodeUInt32();var bootTime=decoder.decodeUInt64ToString();var perfFreq=decoder.decodeUInt64ToString();var startTime=decoder.decodeUInt64ToString();var reservedFlags=decoder.decodeUInt32();var buffersLost=decoder.decodeUInt32();var sessionNameString=decoder.decodeW16String();var logFileNameString=decoder.decodeW16String();return{bufferSize:bufferSize,version:version,providerVersion:providerVersion,numberOfProcessors:numberOfProcessors,endTime:endTime,timerResolution:timerResolution,maxFileSize:maxFileSize,logFileMode:logFileMode,buffersWritten:buffersWritten,startBuffers:startBuffers,pointerSize:pointerSize,eventsLost:eventsLost,cpuSpeed:cpuSpeed,loggerName:loggerName,logFileName:logFileName,timeZoneInformation:timeZoneInformation,bootTime:bootTime,perfFreq:perfFreq,startTime:startTime,reservedFlags:reservedFlags,buffersLost:buffersLost,sessionNameString:sessionNameString,logFileNameString:logFileNameString};},decodeHeader:function(header,decoder){var fields=this.decodeFields(header,decoder);return true;}};Parser.register(EventTraceParser);return{EventTraceParser:EventTraceParser};});'use strict';tr.exportTo('tr.e.importer.etw',function(){var Parser=tr.e.importer.etw.Parser;var guid='3D6FA8D0-FE05-11D0-9DDA-00C04FD7BA7C';var kProcessStartOpcode=1;var kProcessEndOpcode=2;var kProcessDCStartOpcode=3;var kProcessDCEndOpcode=4;var kProcessDefunctOpcode=39;function ProcessParser(importer){Parser.call(this,importer);importer.registerEventHandler(guid,kProcessStartOpcode,ProcessParser.prototype.decodeStart.bind(this));importer.registerEventHandler(guid,kProcessEndOpcode,ProcessParser.prototype.decodeEnd.bind(this));importer.registerEventHandler(guid,kProcessDCStartOpcode,ProcessParser.prototype.decodeDCStart.bind(this));importer.registerEventHandler(guid,kProcessDCEndOpcode,ProcessParser.prototype.decodeDCEnd.bind(this));importer.registerEventHandler(guid,kProcessDefunctOpcode,ProcessParser.prototype.decodeDefunct.bind(this));}
+ProcessParser.prototype={__proto__:Parser.prototype,decodeFields:function(header,decoder){if(header.version>5)
+throw new Error('Incompatible Process event version.');var pageDirectoryBase;if(header.version==1)
+pageDirectoryBase=decoder.decodeUInteger(header.is64);var uniqueProcessKey;if(header.version>=2)
+uniqueProcessKey=decoder.decodeUInteger(header.is64);var processId=decoder.decodeUInt32();var parentId=decoder.decodeUInt32();var sessionId;var exitStatus;if(header.version>=1){sessionId=decoder.decodeUInt32();exitStatus=decoder.decodeInt32();}
+var directoryTableBase;if(header.version>=3)
+directoryTableBase=decoder.decodeUInteger(header.is64);var flags;if(header.version>=4)
+flags=decoder.decodeUInt32();var userSID=decoder.decodeSID(header.is64);var imageFileName;if(header.version>=1)
+imageFileName=decoder.decodeString();var commandLine;if(header.version>=2)
+commandLine=decoder.decodeW16String();var packageFullName;var applicationId;if(header.version>=4){packageFullName=decoder.decodeW16String();applicationId=decoder.decodeW16String();}
+var exitTime;if(header.version==5&&header.opcode==kProcessDefunctOpcode)
+exitTime=decoder.decodeUInt64ToString();return{pageDirectoryBase:pageDirectoryBase,uniqueProcessKey:uniqueProcessKey,processId:processId,parentId:parentId,sessionId:sessionId,exitStatus:exitStatus,directoryTableBase:directoryTableBase,flags:flags,userSID:userSID,imageFileName:imageFileName,commandLine:commandLine,packageFullName:packageFullName,applicationId:applicationId,exitTime:exitTime};},decodeStart:function(header,decoder){var fields=this.decodeFields(header,decoder);var process=this.model.getOrCreateProcess(fields.processId);if(process.hasOwnProperty('has_ended')){throw new Error('Process clash detected.');}
+process.name=fields.imageFileName;return true;},decodeEnd:function(header,decoder){var fields=this.decodeFields(header,decoder);var process=this.model.getOrCreateProcess(fields.processId);process.has_ended=true;return true;},decodeDCStart:function(header,decoder){var fields=this.decodeFields(header,decoder);var process=this.model.getOrCreateProcess(fields.processId);if(process.hasOwnProperty('has_ended'))
+throw new Error('Process clash detected.');process.name=fields.imageFileName;return true;},decodeDCEnd:function(header,decoder){var fields=this.decodeFields(header,decoder);var process=this.model.getOrCreateProcess(fields.processId);process.has_ended=true;return true;},decodeDefunct:function(header,decoder){var fields=this.decodeFields(header,decoder);return true;}};Parser.register(ProcessParser);return{ProcessParser:ProcessParser};});'use strict';tr.exportTo('tr.e.importer.etw',function(){var Parser=tr.e.importer.etw.Parser;var guid='3D6FA8D1-FE05-11D0-9DDA-00C04FD7BA7C';var kThreadStartOpcode=1;var kThreadEndOpcode=2;var kThreadDCStartOpcode=3;var kThreadDCEndOpcode=4;var kThreadCSwitchOpcode=36;function ThreadParser(importer){Parser.call(this,importer);importer.registerEventHandler(guid,kThreadStartOpcode,ThreadParser.prototype.decodeStart.bind(this));importer.registerEventHandler(guid,kThreadEndOpcode,ThreadParser.prototype.decodeEnd.bind(this));importer.registerEventHandler(guid,kThreadDCStartOpcode,ThreadParser.prototype.decodeDCStart.bind(this));importer.registerEventHandler(guid,kThreadDCEndOpcode,ThreadParser.prototype.decodeDCEnd.bind(this));importer.registerEventHandler(guid,kThreadCSwitchOpcode,ThreadParser.prototype.decodeCSwitch.bind(this));}
+ThreadParser.prototype={__proto__:Parser.prototype,decodeFields:function(header,decoder){if(header.version>3)
+throw new Error('Incompatible Thread event version.');var processId=decoder.decodeUInt32();var threadId=decoder.decodeUInt32();var stackBase;var stackLimit;var userStackBase;var userStackLimit;var affinity;var startAddr;var win32StartAddr;var tebBase;var subProcessTag;var basePriority;var pagePriority;var ioPriority;var threadFlags;var waitMode;if(header.version==1){if(header.opcode==kThreadStartOpcode||header.opcode==kThreadDCStartOpcode){stackBase=decoder.decodeUInteger(header.is64);stackLimit=decoder.decodeUInteger(header.is64);userStackBase=decoder.decodeUInteger(header.is64);userStackLimit=decoder.decodeUInteger(header.is64);startAddr=decoder.decodeUInteger(header.is64);win32StartAddr=decoder.decodeUInteger(header.is64);waitMode=decoder.decodeInt8();decoder.skip(3);}}else{stackBase=decoder.decodeUInteger(header.is64);stackLimit=decoder.decodeUInteger(header.is64);userStackBase=decoder.decodeUInteger(header.is64);userStackLimit=decoder.decodeUInteger(header.is64);if(header.version==2)
+startAddr=decoder.decodeUInteger(header.is64);else
+affinity=decoder.decodeUInteger(header.is64);win32StartAddr=decoder.decodeUInteger(header.is64);tebBase=decoder.decodeUInteger(header.is64);subProcessTag=decoder.decodeUInt32();if(header.version==3){basePriority=decoder.decodeUInt8();pagePriority=decoder.decodeUInt8();ioPriority=decoder.decodeUInt8();threadFlags=decoder.decodeUInt8();}}
+return{processId:processId,threadId:threadId,stackBase:stackBase,stackLimit:stackLimit,userStackBase:userStackBase,userStackLimit:userStackLimit,affinity:affinity,startAddr:startAddr,win32StartAddr:win32StartAddr,tebBase:tebBase,subProcessTag:subProcessTag,waitMode:waitMode,basePriority:basePriority,pagePriority:pagePriority,ioPriority:ioPriority,threadFlags:threadFlags};},decodeCSwitchFields:function(header,decoder){if(header.version!=2)
+throw new Error('Incompatible Thread event version.');var newThreadId=decoder.decodeUInt32();var oldThreadId=decoder.decodeUInt32();var newThreadPriority=decoder.decodeInt8();var oldThreadPriority=decoder.decodeInt8();var previousCState=decoder.decodeUInt8();var spareByte=decoder.decodeInt8();var oldThreadWaitReason=decoder.decodeInt8();var oldThreadWaitMode=decoder.decodeInt8();var oldThreadState=decoder.decodeInt8();var oldThreadWaitIdealProcessor=decoder.decodeInt8();var newThreadWaitTime=decoder.decodeUInt32();var reserved=decoder.decodeUInt32();return{newThreadId:newThreadId,oldThreadId:oldThreadId,newThreadPriority:newThreadPriority,oldThreadPriority:oldThreadPriority,previousCState:previousCState,spareByte:spareByte,oldThreadWaitReason:oldThreadWaitReason,oldThreadWaitMode:oldThreadWaitMode,oldThreadState:oldThreadState,oldThreadWaitIdealProcessor:oldThreadWaitIdealProcessor,newThreadWaitTime:newThreadWaitTime,reserved:reserved};},decodeStart:function(header,decoder){var fields=this.decodeFields(header,decoder);this.importer.createThreadIfNeeded(fields.processId,fields.threadId);return true;},decodeEnd:function(header,decoder){var fields=this.decodeFields(header,decoder);this.importer.removeThreadIfPresent(fields.threadId);return true;},decodeDCStart:function(header,decoder){var fields=this.decodeFields(header,decoder);this.importer.createThreadIfNeeded(fields.processId,fields.threadId);return true;},decodeDCEnd:function(header,decoder){var fields=this.decodeFields(header,decoder);this.importer.removeThreadIfPresent(fields.threadId);return true;},decodeCSwitch:function(header,decoder){var fields=this.decodeCSwitchFields(header,decoder);var cpu=this.importer.getOrCreateCpu(header.cpu);var new_thread=this.importer.getThreadFromWindowsTid(fields.newThreadId);var new_thread_name;if(new_thread&&new_thread.userFriendlyName){new_thread_name=new_thread.userFriendlyName;}else{var new_process_id=this.importer.getPidFromWindowsTid(fields.newThreadId);var new_process=this.model.getProcess(new_process_id);var new_process_name;if(new_process)
+new_process_name=new_process.name;else
+new_process_name='Unknown process';new_thread_name=new_process_name+' (tid '+fields.newThreadId+')';}
+cpu.switchActiveThread(header.timestamp,{},fields.newThreadId,new_thread_name,fields);return true;}};Parser.register(ThreadParser);return{ThreadParser:ThreadParser};});'use strict';tr.exportTo('tr.b',function(){function Base64(){}
+function b64ToUint6(nChr){if(nChr>64&&nChr<91)
+return nChr-65;if(nChr>96&&nChr<123)
+return nChr-71;if(nChr>47&&nChr<58)
+return nChr+4;if(nChr===43)
+return 62;if(nChr===47)
+return 63;return 0;}
+Base64.getDecodedBufferLength=function(input){return input.length*3+1>>2;}
+Base64.EncodeArrayBufferToString=function(input){var binary='';var bytes=new Uint8Array(input);var len=bytes.byteLength;for(var i=0;i<len;i++)
+binary+=String.fromCharCode(bytes[i]);return btoa(binary);}
+Base64.DecodeToTypedArray=function(input,output){var nInLen=input.length;var nOutLen=nInLen*3+1>>2;var nMod3=0;var nMod4=0;var nUint24=0;var nOutIdx=0;if(nOutLen>output.byteLength)
+throw new Error('Output buffer too small to decode.');for(var nInIdx=0;nInIdx<nInLen;nInIdx++){nMod4=nInIdx&3;nUint24|=b64ToUint6(input.charCodeAt(nInIdx))<<18-6*nMod4;if(nMod4===3||nInLen-nInIdx===1){for(nMod3=0;nMod3<3&&nOutIdx<nOutLen;nMod3++,nOutIdx++){output.setUint8(nOutIdx,nUint24>>>(16>>>nMod3&24)&255);}
+nUint24=0;}}
+return nOutIdx-1;}
+return{Base64:Base64};});'use strict';tr.exportTo('tr.e.importer.etw',function(){var kThreadGuid='3D6FA8D1-FE05-11D0-9DDA-00C04FD7BA7C';var kThreadDCStartOpcode=3;function Decoder(){this.payload_=new DataView(new ArrayBuffer(256));};Decoder.prototype={__proto__:Object.prototype,reset:function(base64_payload){var decoded_size=tr.b.Base64.getDecodedBufferLength(base64_payload);if(decoded_size>this.payload_.byteLength)
+this.payload_=new DataView(new ArrayBuffer(decoded_size));tr.b.Base64.DecodeToTypedArray(base64_payload,this.payload_);this.position_=0;},skip:function(length){this.position_+=length;},decodeUInt8:function(){var result=this.payload_.getUint8(this.position_,true);this.position_+=1;return result;},decodeUInt16:function(){var result=this.payload_.getUint16(this.position_,true);this.position_+=2;return result;},decodeUInt32:function(){var result=this.payload_.getUint32(this.position_,true);this.position_+=4;return result;},decodeUInt64ToString:function(){var low=this.decodeUInt32();var high=this.decodeUInt32();var low_str=('0000000'+low.toString(16)).substr(-8);var high_str=('0000000'+high.toString(16)).substr(-8);var result=high_str+low_str;return result;},decodeInt8:function(){var result=this.payload_.getInt8(this.position_,true);this.position_+=1;return result;},decodeInt16:function(){var result=this.payload_.getInt16(this.position_,true);this.position_+=2;return result;},decodeInt32:function(){var result=this.payload_.getInt32(this.position_,true);this.position_+=4;return result;},decodeInt64ToString:function(){return this.decodeUInt64ToString();},decodeUInteger:function(is64){if(is64)
+return this.decodeUInt64ToString();return this.decodeUInt32();},decodeString:function(){var str='';while(true){var c=this.decodeUInt8();if(!c)
+return str;str=str+String.fromCharCode(c);}},decodeW16String:function(){var str='';while(true){var c=this.decodeUInt16();if(!c)
+return str;str=str+String.fromCharCode(c);}},decodeFixedW16String:function(length){var old_position=this.position_;var str='';for(var i=0;i<length;i++){var c=this.decodeUInt16();if(!c)
+break;str=str+String.fromCharCode(c);}
+this.position_=old_position+2*length;return str;},decodeBytes:function(length){var bytes=[];for(var i=0;i<length;++i){var c=this.decodeUInt8();bytes.push(c);}
+return bytes;},decodeSID:function(is64){var pSid=this.decodeUInteger(is64);var attributes=this.decodeUInt32();if(is64)
+this.decodeUInt32();var revision=this.decodeUInt8();var subAuthorityCount=this.decodeUInt8();this.decodeUInt16();this.decodeUInt32();if(revision!=1)
+throw'Invalid SID revision: could not decode the SID structure.';var sid=this.decodeBytes(4*subAuthorityCount);return{pSid:pSid,attributes:attributes,sid:sid};},decodeSystemTime:function(){var wYear=this.decodeInt16();var wMonth=this.decodeInt16();var wDayOfWeek=this.decodeInt16();var wDay=this.decodeInt16();var wHour=this.decodeInt16();var wMinute=this.decodeInt16();var wSecond=this.decodeInt16();var wMilliseconds=this.decodeInt16();return{wYear:wYear,wMonth:wMonth,wDayOfWeek:wDayOfWeek,wDay:wDay,wHour:wHour,wMinute:wMinute,wSecond:wSecond,wMilliseconds:wMilliseconds};},decodeTimeZoneInformation:function(){var bias=this.decodeUInt32();var standardName=this.decodeFixedW16String(32);var standardDate=this.decodeSystemTime();var standardBias=this.decodeUInt32();var daylightName=this.decodeFixedW16String(32);var daylightDate=this.decodeSystemTime();var daylightBias=this.decodeUInt32();return{bias:bias,standardName:standardName,standardDate:standardDate,standardBias:standardBias,daylightName:daylightName,daylightDate:daylightDate,daylightBias:daylightBias};}};function EtwImporter(model,events){this.importPriority=3;this.model_=model;this.events_=events;this.handlers_={};this.decoder_=new Decoder();this.walltime_=undefined;this.ticks_=undefined;this.is64bit_=undefined;this.tidsToPid_={};var allTypeInfos=tr.e.importer.etw.Parser.getAllRegisteredTypeInfos();this.parsers_=allTypeInfos.map(function(typeInfo){return new typeInfo.constructor(this);},this);}
+EtwImporter.canImport=function(events){if(!events.hasOwnProperty('name')||!events.hasOwnProperty('content')||events.name!=='ETW'){return false;}
+return true;};EtwImporter.prototype={__proto__:tr.importer.Importer.prototype,get model(){return this.model_;},createThreadIfNeeded:function(pid,tid){this.tidsToPid_[tid]=pid;},removeThreadIfPresent:function(tid){this.tidsToPid_[tid]=undefined;},getPidFromWindowsTid:function(tid){if(tid==0)
+return 0;var pid=this.tidsToPid_[tid];if(pid==undefined){return 0;}
+return pid;},getThreadFromWindowsTid:function(tid){var pid=this.getPidFromWindowsTid(tid);var process=this.model_.getProcess(pid);if(!process)
+return undefined;return process.getThread(tid);},getOrCreateCpu:function(cpuNumber){var cpu=this.model_.kernel.getOrCreateCpu(cpuNumber);return cpu;},importEvents:function(isSecondaryImport){this.events_.content.forEach(this.parseInfo.bind(this));if(this.walltime_==undefined||this.ticks_==undefined)
+throw Error('Cannot find clock sync information in the system trace.');if(this.is64bit_==undefined)
+throw Error('Cannot determine pointer size of the system trace.');this.events_.content.forEach(this.parseEvent.bind(this));},importTimestamp:function(timestamp){var ts=parseInt(timestamp,16);return(ts-this.walltime_+this.ticks_)/1000.;},parseInfo:function(event){if(event.hasOwnProperty('guid')&&event.hasOwnProperty('walltime')&&event.hasOwnProperty('tick')&&event.guid==='ClockSync'){this.walltime_=parseInt(event.walltime,16);this.ticks_=parseInt(event.tick,16);}
+if(this.is64bit_==undefined&&event.hasOwnProperty('guid')&&event.hasOwnProperty('op')&&event.hasOwnProperty('ver')&&event.hasOwnProperty('payload')&&event.guid===kThreadGuid&&event.op==kThreadDCStartOpcode){var decoded_size=tr.b.Base64.getDecodedBufferLength(event.payload);if(event.ver==1){if(decoded_size>=52)
+this.is64bit_=true;else
+this.is64bit_=false;}else if(event.ver==2){if(decoded_size>=64)
+this.is64bit_=true;else
+this.is64bit_=false;}else if(event.ver==3){if(decoded_size>=60)
+this.is64bit_=true;else
+this.is64bit_=false;}}
+return true;},parseEvent:function(event){if(!event.hasOwnProperty('guid')||!event.hasOwnProperty('op')||!event.hasOwnProperty('ver')||!event.hasOwnProperty('cpu')||!event.hasOwnProperty('ts')||!event.hasOwnProperty('payload')){return false;}
+var timestamp=this.importTimestamp(event.ts);var header={guid:event.guid,opcode:event.op,version:event.ver,cpu:event.cpu,timestamp:timestamp,is64:this.is64bit_};var decoder=this.decoder_;decoder.reset(event.payload);var handler=this.getEventHandler(header.guid,header.opcode);if(!handler)
+return false;if(!handler(header,decoder)){this.model_.importWarning({type:'parse_error',message:'Malformed '+header.guid+' event ('+text+')'});return false;}
+return true;},registerEventHandler:function(guid,opcode,handler){if(this.handlers_[guid]==undefined)
+this.handlers_[guid]=[];this.handlers_[guid][opcode]=handler;},getEventHandler:function(guid,opcode){if(this.handlers_[guid]==undefined)
+return undefined;return this.handlers_[guid][opcode];}};tr.importer.Importer.register(EtwImporter);return{EtwImporter:EtwImporter};});'use strict';tr.exportTo('tr.e.importer',function(){function Trace2HTMLImporter(model,events){this.importPriority=0;}
+Trace2HTMLImporter.subtraces_=[];function _extractEventsFromHTML(text){Trace2HTMLImporter.subtraces_=[];var r=new tr.importer.SimpleLineReader(text);while(true){if(!r.advanceToLineMatching(new RegExp('^<\s*script id="viewer-data" '+'type="(application\/json|text\/plain)">$')))
+break;r.beginSavingLines();if(!r.advanceToLineMatching(/^<\/\s*script>$/))
+return failure;var raw_events=r.endSavingLinesAndGetResult();raw_events=raw_events.slice(1,raw_events.length-1);var data64=raw_events.join('\n');var buffer=new ArrayBuffer(tr.b.Base64.getDecodedBufferLength(data64));var len=tr.b.Base64.DecodeToTypedArray(data64,new DataView(buffer));Trace2HTMLImporter.subtraces_.push(buffer.slice(0,len));}}
+function _canImportFromHTML(text){if(/^<!DOCTYPE html>/.test(text)===false)
+return false;_extractEventsFromHTML(text);if(Trace2HTMLImporter.subtraces_.length===0)
+return false;return true;}
+Trace2HTMLImporter.canImport=function(events){return _canImportFromHTML(events);};Trace2HTMLImporter.prototype={__proto__:tr.importer.Importer.prototype,isTraceDataContainer:function(){return true;},extractSubtraces:function(){return Trace2HTMLImporter.subtraces_;},importEvents:function(){}};tr.importer.Importer.register(Trace2HTMLImporter);return{Trace2HTMLImporter:Trace2HTMLImporter};});'use strict';tr.exportTo('tr.e.net',function(){var AsyncSlice=tr.model.AsyncSlice;function NetAsyncSlice(){AsyncSlice.apply(this,arguments);this.isTitleComputed_=false;}
+NetAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get viewSubGroupTitle(){return'NetLog';},get title(){if(this.isTitleComputed_||!this.isTopLevel){return this.title_;}
+var getUrl=function(slice){if(slice.args!==undefined&&slice.args.params!==undefined&&slice.args.params.url!==undefined){return slice.args.params.url;}
+if(slice.subSlices===undefined||slice.subSlices.length===0)
+return undefined;for(var i=0;i<slice.subSlices.length;i++){var result=getUrl(slice.subSlices[i]);if(result!==undefined)
+return result;}
+return undefined;};var url=getUrl(this);if(url!==undefined&&url.length>0){this.title_=url;}else if(this.args!==undefined&&this.args.source_type!==undefined){this.title_=this.args.source_type;}
+this.isTitleComputed_=true;return this.title_;},set title(title){this.title_=title;}};AsyncSlice.register(NetAsyncSlice,{categoryParts:['netlog','disabled-by-default-netlog']});return{NetAsyncSlice:NetAsyncSlice};});'use strict';tr.exportTo('tr.e.chrome',function(){var KNOWN_PROPERTIES={children:1,name:1,address:1};function LayoutObject(snapshot,args){this.snapshot_=snapshot;this.id_=args.address;this.name_=args.name;this.childLayoutObjects_=[];this.otherProperties_={};if(args.children){args.children.forEach(function(child){this.childLayoutObjects_.push(new LayoutObject(snapshot,child));}.bind(this));}
+for(var property in args){if(!KNOWN_PROPERTIES[property])
+this.otherProperties_[property]=args[property];}}
+LayoutObject.prototype={get snapshot(){return this.snapshot_;},get id(){return this.id_;},get name(){return this.name_;},get hasChildLayoutObjects(){return this.childLayoutObjects_.length>0;},get childLayoutObjects(){return this.childLayoutObjects_;},traverseTree:function(cb,opt_this){cb.call(opt_this,this);if(!this.hasChildLayoutObjects)
+return;this.childLayoutObjects.forEach(function(child){child.traverseTree(cb,opt_this);});},get otherPropertyNames(){var names=[];for(var name in this.otherProperties_){names.push(name);}
+return names;},getProperty:function(name){return this.otherProperties_[name];},get previousSnapshotLayoutObject(){if(!this.snapshot.previousSnapshot)
+return undefined;return this.snapshot.previousSnapshot.getLayoutObjectById(this.id);},get nextSnapshotLayoutObject(){if(!this.snapshot.nextSnapshot)
+return undefined;return this.snapshot.nextSnapshot.getLayoutObjectById(this.id);}};return{LayoutObject:LayoutObject};});'use strict';tr.exportTo('tr.e.audits',function(){var MAIN_FRAMETIME_TYPE='main_frametime_type';var IMPL_FRAMETIME_TYPE='impl_frametime_type';var MAIN_RENDERING_STATS='BenchmarkInstrumentation::MainThreadRenderingStats';var IMPL_RENDERING_STATS='BenchmarkInstrumentation::ImplThreadRenderingStats';function getSlicesIntersectingRange(rangeOfInterest,slices){var slicesInFilterRange=[];for(var i=0;i<slices.length;i++){var slice=slices[i];if(rangeOfInterest.intersectsExplicitRange(slice.start,slice.end))
+slicesInFilterRange.push(slice);}
+return slicesInFilterRange;}
+function ChromeProcessHelper(modelHelper,process){this.modelHelper=modelHelper;this.process=process;}
+ChromeProcessHelper.prototype={get pid(){return this.process.pid;},getFrameEventsInRange:function(frametimeType,range){var titleToGet;if(frametimeType==MAIN_FRAMETIME_TYPE)
+titleToGet=MAIN_RENDERING_STATS;else
+titleToGet=IMPL_RENDERING_STATS;var frameEvents=[];this.process.iterateAllEvents(function(event){if(event.title!==titleToGet)
+return;if(range.intersectsExplicitRange(event.start,event.end))
+frameEvents.push(event);});frameEvents.sort(function(a,b){return a.start-b.start});return frameEvents;}};function getFrametimeDataFromEvents(frameEvents){var frametimeData=[];for(var i=1;i<frameEvents.length;i++){var diff=frameEvents[i].start-frameEvents[i-1].start;frametimeData.push({'x':frameEvents[i].start,'frametime':diff});}
+return frametimeData;}
+return{ChromeProcessHelper:ChromeProcessHelper,MAIN_FRAMETIME_TYPE:MAIN_FRAMETIME_TYPE,IMPL_FRAMETIME_TYPE:IMPL_FRAMETIME_TYPE,MAIN_RENDERING_STATS:MAIN_RENDERING_STATS,IMPL_RENDERING_STATS:IMPL_RENDERING_STATS,getSlicesIntersectingRange:getSlicesIntersectingRange,getFrametimeDataFromEvents:getFrametimeDataFromEvents};});'use strict';tr.exportTo('tr.e.audits',function(){function ChromeBrowserHelper(modelHelper,process){tr.e.audits.ChromeProcessHelper.call(this,modelHelper,process);this.mainThread_=process.findAtMostOneThreadNamed('CrBrowserMain');}
+ChromeBrowserHelper.isBrowserProcess=function(process){return!!process.findAtMostOneThreadNamed('CrBrowserMain');};ChromeBrowserHelper.prototype={__proto__:tr.e.audits.ChromeProcessHelper.prototype,get rendererHelpers(){return this.modelHelper.rendererHelpers;},getLoadingEventsInRange:function(rangeOfInterest){return this.getAllAsyncSlicesMatching(function(slice){return slice.title.indexOf('WebContentsImpl Loading')===0&&rangeOfInterest.intersectsExplicitRange(slice.start,slice.end);});},getCommitProvisionalLoadEventsInRange:function(rangeOfInterest){return this.getAllAsyncSlicesMatching(function(slice){return slice.title==='RenderFrameImpl::didCommitProvisionalLoad'&&rangeOfInterest.intersectsExplicitRange(slice.start,slice.end);});},get hasLatencyEvents(){var hasLatency=false;this.modelHelper.model.getAllThreads().some(function(thread){thread.iterateAllEvents(function(event){if(!event.isTopLevel)
+return;if(!(event instanceof tr.e.cc.InputLatencyAsyncSlice))
+return;hasLatency=true;});return hasLatency;});return hasLatency;},getLatencyEventsInRange:function(rangeOfInterest){return this.getAllAsyncSlicesMatching(function(slice){return(slice.title.indexOf('InputLatency')===0)&&rangeOfInterest.intersectsExplicitRange(slice.start,slice.end);});},getAllAsyncSlicesMatching:function(pred,opt_this){var events=[];this.iterAllThreads(function(thread){thread.iterateAllEvents(function(slice){if(pred.call(opt_this,slice))
+events.push(slice);});});return events;},getAllNetworkEventsInRange:function(rangeOfInterest){var networkEvents=[];this.modelHelper.model.getAllThreads().forEach(function(thread){thread.asyncSliceGroup.slices.forEach(function(slice){var match=false;if(slice.category=='net'||slice.category=='disabled-by-default-netlog'||slice.category=='netlog'){match=true;}
+if(!match)
+return;if(rangeOfInterest.intersectsExplicitRange(slice.start,slice.end))
+networkEvents.push(slice);});});return networkEvents;},iterAllThreads:function(func,opt_this){tr.b.iterItems(this.process.threads,function(tid,thread){func.call(opt_this,thread);});tr.b.iterItems(this.rendererHelpers,function(pid,rendererHelper){var rendererProcess=rendererHelper.process;tr.b.iterItems(rendererProcess.threads,function(tid,thread){func.call(opt_this,thread);});},this);}};return{ChromeBrowserHelper:ChromeBrowserHelper};});'use strict';tr.exportTo('tr.e.audits',function(){function ChromeGpuHelper(modelHelper,process){tr.e.audits.ChromeProcessHelper.call(this,modelHelper,process);this.mainThread_=process.findAtMostOneThreadNamed('CrGpuMain');};ChromeGpuHelper.isGpuProcess=function(process){if(process.findAtMostOneThreadNamed('CrBrowserMain')||process.findAtMostOneThreadNamed('CrRendererMain'))
+return false;return process.findAtMostOneThreadNamed('CrGpuMain');};ChromeGpuHelper.prototype={__proto__:tr.e.audits.ChromeProcessHelper.prototype,get mainThread(){return this.mainThread_;}};return{ChromeGpuHelper:ChromeGpuHelper};});'use strict';tr.exportTo('tr.e.audits',function(){function ChromeRendererHelper(modelHelper,process){tr.e.audits.ChromeProcessHelper.call(this,modelHelper,process);this.mainThread_=process.findAtMostOneThreadNamed('CrRendererMain');this.compositorThread_=process.findAtMostOneThreadNamed('Compositor');this.rasterWorkerThreads_=process.findAllThreadsMatching(function(t){if(t.name===undefined)
+return false;if(t.name.indexOf('CompositorTileWorker')===0)
+return true;if(t.name.indexOf('CompositorRasterWorker')===0)
+return true;return false;});};ChromeRendererHelper.isRenderProcess=function(process){if(!process.findAtMostOneThreadNamed('CrRendererMain'))
+return false;if(!process.findAtMostOneThreadNamed('Compositor'))
+return false;return true;};ChromeRendererHelper.prototype={__proto__:tr.e.audits.ChromeProcessHelper.prototype,get mainThread(){return this.mainThread_;},get compositorThread(){return this.compositorThread_;},get rasterWorkerThreads(){return this.rasterWorkerThreads_;}};return{ChromeRendererHelper:ChromeRendererHelper};});'use strict';tr.exportTo('tr.e.audits',function(){function findChromeBrowserProcess(model){var browserProcesses=[];model.getAllProcesses().forEach(function(process){if(!tr.e.audits.ChromeBrowserHelper.isBrowserProcess(process))
+return;browserProcesses.push(process);},this);if(browserProcesses.length===0)
+return undefined;if(browserProcesses.length>1)
+return undefined;return browserProcesses[0];}
+function findChromeRenderProcesses(model){var rendererProcesses=[];model.getAllProcesses().forEach(function(process){if(!tr.e.audits.ChromeRendererHelper.isRenderProcess(process))
+return;rendererProcesses.push(process);});return rendererProcesses;}
+function findChromeGpuProcess(model){var gpuProcesses=model.getAllProcesses().filter(tr.e.audits.ChromeGpuHelper.isGpuProcess);if(gpuProcesses.length!=1)
+return undefined;return gpuProcesses[0];}
+function ChromeModelHelper(model){this.model_=model;this.browserProcess_=findChromeBrowserProcess(model);if(this.browserProcess_){this.browserHelper_=new tr.e.audits.ChromeBrowserHelper(this,this.browserProcess_);}else{this.browserHelper_=undefined;}
+var gpuProcess=findChromeGpuProcess(model);if(gpuProcess){this.gpuHelper_=new tr.e.audits.ChromeGpuHelper(this,gpuProcess);}else{this.gpuHelper_=undefined;}
+var rendererProcesses_=findChromeRenderProcesses(model);this.rendererHelpers_={};rendererProcesses_.forEach(function(renderProcess){var rendererHelper=new tr.e.audits.ChromeRendererHelper(this,renderProcess);this.rendererHelpers_[rendererHelper.pid]=rendererHelper;},this);}
+ChromeModelHelper.supportsModel=function(model){if(findChromeBrowserProcess(model)!==undefined)
+return true;if(findChromeRenderProcesses(model).length)
+return true;return false;}
+ChromeModelHelper.prototype={get pid(){throw new Error('woah');},get process(){throw new Error('woah');},get model(){return this.model_;},get browserProcess(){return this.browserProcess_;},get browserHelper(){return this.browserHelper_;},get gpuHelper(){return this.gpuHelper_;},get rendererHelpers(){return this.rendererHelpers_;}};return{ChromeModelHelper:ChromeModelHelper};});'use strict';tr.exportTo('tr.e.cc',function(){var AsyncSlice=tr.model.AsyncSlice;var EventSet=tr.model.EventSet;var UI_COMP_NAME='INPUT_EVENT_LATENCY_UI_COMPONENT';var ORIGINAL_COMP_NAME='INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT';var BEGIN_COMP_NAME='INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT';var END_COMP_NAME='INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT';var MAIN_RENDERER_THREAD_NAME='CrRendererMain';var COMPOSITOR_THREAD_NAME='Compositor';var POSTTASK_FLOW_EVENT='disabled-by-default-toplevel.flow';var IPC_FLOW_EVENT='disabled-by-default-ipc.flow';var INPUT_EVENT_TYPE_NAMES={CHAR:'Char',CLICK:'GestureClick',CONTEXT_MENU:'ContextMenu',FLING_CANCEL:'GestureFlingCancel',FLING_START:'GestureFlingStart',KEY_DOWN:'KeyDown',KEY_DOWN_RAW:'RawKeyDown',KEY_UP:'KeyUp',LATENCY_SCROLL_UPDATE:'ScrollUpdate',MOUSE_DOWN:'MouseDown',MOUSE_ENTER:'MouseEnter',MOUSE_LEAVE:'MouseLeave',MOUSE_MOVE:'MouseMove',MOUSE_UP:'MouseUp',MOUSE_WHEEL:'MouseWheel',PINCH_BEGIN:'GesturePinchBegin',PINCH_END:'GesturePinchEnd',PINCH_UPDATE:'GesturePinchUpdate',SCROLL_BEGIN:'GestureScrollBegin',SCROLL_END:'GestureScrollEnd',SCROLL_UPDATE:'GestureScrollUpdate',SCROLL_UPDATE_RENDERER:'ScrollUpdate',SHOW_PRESS:'GestureShowPress',TAP:'GestureTap',TAP_CANCEL:'GestureTapCancel',TAP_DOWN:'GestureTapDown',TOUCH_CANCEL:'TouchCancel',TOUCH_END:'TouchEnd',TOUCH_MOVE:'TouchMove',TOUCH_START:'TouchStart',UNKNOWN:'UNKNOWN'};function InputLatencyAsyncSlice(){AsyncSlice.apply(this,arguments);this.associatedEvents_=new EventSet();this.typeName_=undefined;if(!this.isLegacyEvent)
+this.determineModernTypeName_();}
+InputLatencyAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get isLegacyEvent(){return this.title==='InputLatency';},get typeName(){if(!this.typeName_)
+this.determineLegacyTypeName_();return this.typeName_;},checkTypeName_:function(){if(!this.typeName_)
+throw'Unable to determine typeName';var found=false;for(var type_name in INPUT_EVENT_TYPE_NAMES){if(this.typeName===INPUT_EVENT_TYPE_NAMES[type_name]){found=true;break;}}
+if(!found)
+this.typeName_=INPUT_EVENT_TYPE_NAMES.UNKNOWN;},determineModernTypeName_:function(){var lastColonIndex=this.title.lastIndexOf(':');if(lastColonIndex<0)
+return;var characterAfterLastColonIndex=lastColonIndex+1;this.typeName_=this.title.slice(characterAfterLastColonIndex);this.checkTypeName_();},determineLegacyTypeName_:function(){this.iterateAllDescendents(function(subSlice){var subSliceIsAInputLatencyAsyncSlice=(subSlice instanceof InputLatencyAsyncSlice);if(!subSliceIsAInputLatencyAsyncSlice)
+return;if(!subSlice.typeName)
+return;if(this.typeName_&&subSlice.typeName_){var subSliceHasDifferentTypeName=(this.typeName_!==subSlice.typeName_);if(subSliceHasDifferentTypeName){throw'InputLatencyAsyncSlice.determineLegacyTypeName_() '+' found multiple typeNames';}}
+this.typeName_=subSlice.typeName_;},this);if(!this.typeName_)
+throw'InputLatencyAsyncSlice.determineLegacyTypeName_() failed';this.checkTypeName_();},getRendererHelper:function(sourceSlices){var traceModel=this.startThread.parent.model;if(!tr.e.audits.ChromeModelHelper.supportsModel(traceModel))
+return undefined;var mainThread=undefined;var compositorThread=undefined;for(var i in sourceSlices){if(sourceSlices[i].parentContainer.name===MAIN_RENDERER_THREAD_NAME)
+mainThread=sourceSlices[i].parentContainer;else if(sourceSlices[i].parentContainer.name===COMPOSITOR_THREAD_NAME)
+compositorThread=sourceSlices[i].parentContainer;if(mainThread&&compositorThread)
+break;}
+var modelHelper=new tr.e.audits.ChromeModelHelper(traceModel);var rendererHelpers=modelHelper.rendererHelpers;var pids=Object.keys(rendererHelpers);for(var i=0;i<pids.length;i++){var pid=pids[i];var rendererHelper=rendererHelpers[pid];if(rendererHelper.mainThread===mainThread||rendererHelper.compositorThread===compositorThread)
+return rendererHelper;}
+return undefined;},addEntireSliceHierarchy:function(slice){this.associatedEvents_.push(slice);slice.iterateAllSubsequentSlices(function(subsequentSlice){this.associatedEvents_.push(subsequentSlice);},this);},addDirectlyAssociatedEvents:function(flowEvents){var slices=[];flowEvents.forEach(function(flowEvent){this.associatedEvents_.push(flowEvent);var newSource=flowEvent.startSlice.mostTopLevelSlice;if(slices.indexOf(newSource)===-1)
+slices.push(newSource);},this);var lastFlowEvent=flowEvents[flowEvents.length-1];var lastSource=lastFlowEvent.endSlice.mostTopLevelSlice;if(slices.indexOf(lastSource)===-1)
+slices.push(lastSource);return slices;},addScrollUpdateEvents:function(rendererHelper){if(!rendererHelper||!rendererHelper.compositorThread)
+return;var compositorThread=rendererHelper.compositorThread;var gestureScrollUpdateStart=this.start;var gestureScrollUpdateEnd=this.end;var allCompositorAsyncSlices=compositorThread.asyncSliceGroup.slices;for(var i in allCompositorAsyncSlices){var slice=allCompositorAsyncSlices[i];if(slice.title!=='Latency::ScrollUpdate')
+continue;var parentId=slice.args.data.INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT.sequence_number;if(parentId===undefined){if(slice.start<gestureScrollUpdateStart||slice.start>=gestureScrollUpdateEnd)
+continue;}else{if(parseInt(parentId)!==parseInt(this.id))
+continue;}
+slice.associatedEvents.forEach(function(event){this.associatedEvents_.push(event);},this);break;}},belongToOtherInputs:function(slice,flowEvents){var fromOtherInputs=false;slice.iterateEntireHierarchy(function(subsequentSlice){if(fromOtherInputs)
+return;subsequentSlice.inFlowEvents.forEach(function(inflow){if(fromOtherInputs)
+return;if(inflow.category.indexOf('input')>-1){if(flowEvents.indexOf(inflow)===-1)
+fromOtherInputs=true;}},this);},this);return fromOtherInputs;},triggerOtherInputs:function(event,flowEvents){if(event.outFlowEvents===undefined||event.outFlowEvents.length===0)
+return false;var flow=event.outFlowEvents[0];if(flow.category!==POSTTASK_FLOW_EVENT||!flow.endSlice)
+return false;var endSlice=flow.endSlice;if(this.belongToOtherInputs(endSlice.mostTopLevelSlice,flowEvents))
+return true;return false;},followSubsequentSlices:function(event,queue,visited,flowEvents){var stopFollowing=false;var inputAck=false;event.iterateAllSubsequentSlices(function(slice){if(stopFollowing)
+return;if(slice.title==='TaskQueueManager::RunTask')
+return;if(slice.title==='ThreadProxy::ScheduledActionSendBeginMainFrame')
+return;if(slice.title==='Scheduler::ScheduleBeginImplFrameDeadline'){if(this.triggerOtherInputs(slice,flowEvents))
+return;}
+if(slice.title==='CompositorImpl::PostComposite'){if(this.triggerOtherInputs(slice,flowEvents))
+return;}
+if(slice.title==='InputRouterImpl::ProcessInputEventAck')
+inputAck=true;if(inputAck&&slice.title==='InputRouterImpl::FilterAndSendWebInputEvent')
+stopFollowing=true;this.followCurrentSlice(slice,queue,visited);},this);},followCurrentSlice:function(event,queue,visited){event.outFlowEvents.forEach(function(outflow){if((outflow.category===POSTTASK_FLOW_EVENT||outflow.category===IPC_FLOW_EVENT)&&outflow.endSlice){this.associatedEvents_.push(outflow);var nextEvent=outflow.endSlice.mostTopLevelSlice;if(!visited.contains(nextEvent)){visited.push(nextEvent);queue.push(nextEvent);}}},this);},backtraceFromDraw:function(beginImplFrame,visited){var pendingEventQueue=[];pendingEventQueue.push(beginImplFrame.mostTopLevelSlice);while(pendingEventQueue.length!==0){var event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);event.inFlowEvents.forEach(function(inflow){if(inflow.category===POSTTASK_FLOW_EVENT&&inflow.startSlice){var nextEvent=inflow.startSlice.mostTopLevelSlice;if(!visited.contains(nextEvent)){visited.push(nextEvent);pendingEventQueue.push(nextEvent);}}},this);}},sortRasterizerSlices:function(rasterWorkerThreads,sortedRasterizerSlices){rasterWorkerThreads.forEach(function(rasterizer){Array.prototype.push.apply(sortedRasterizerSlices,rasterizer.sliceGroup.slices);},this);sortedRasterizerSlices.sort(function(a,b){if(a.start!==b.start)
+return a.start-b.start;return a.guid-b.guid;});},addRasterizationEvents:function(prepareTiles,rendererHelper,visited,flowEvents,sortedRasterizerSlices){if(!prepareTiles.args.prepare_tiles_id)
+return;if(!rendererHelper||!rendererHelper.rasterWorkerThreads)
+return;var rasterWorkerThreads=rendererHelper.rasterWorkerThreads;var prepare_tile_id=prepareTiles.args.prepare_tiles_id;var pendingEventQueue=[];if(sortedRasterizerSlices.length===0)
+this.sortRasterizerSlices(rasterWorkerThreads,sortedRasterizerSlices);var numFinishedTasks=0;var RASTER_TASK_TITLE='RasterizerTaskImpl::RunOnWorkerThread';var IMAGEDECODE_TASK_TITLE='ImageDecodeTaskImpl::RunOnWorkerThread';var FINISHED_TASK_TITLE='TaskSetFinishedTaskImpl::RunOnWorkerThread';for(var i=0;i<sortedRasterizerSlices.length;i++){var task=sortedRasterizerSlices[i];if(task.title===RASTER_TASK_TITLE||task.title===IMAGEDECODE_TASK_TITLE){if(task.args.source_prepare_tiles_id===prepare_tile_id)
+this.addEntireSliceHierarchy(task.mostTopLevelSlice);}else if(task.title===FINISHED_TASK_TITLE){if(task.start>prepareTiles.start){pendingEventQueue.push(task.mostTopLevelSlice);if(++numFinishedTasks===3)
+break;}}}
+while(pendingEventQueue.length!=0){var event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);this.followSubsequentSlices(event,pendingEventQueue,visited,flowEvents);}},addOtherCausallyRelatedEvents:function(rendererHelper,sourceSlices,flowEvents,sortedRasterizerSlices){var pendingEventQueue=[];var visitedEvents=new EventSet();var beginImplFrame=undefined;var prepareTiles=undefined;var sortedRasterizerSlices=[];sourceSlices.forEach(function(sourceSlice){if(!visitedEvents.contains(sourceSlice)){visitedEvents.push(sourceSlice);pendingEventQueue.push(sourceSlice);}},this);while(pendingEventQueue.length!=0){var event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);this.followCurrentSlice(event,pendingEventQueue,visitedEvents);this.followSubsequentSlices(event,pendingEventQueue,visitedEvents,flowEvents);var COMPOSITOR_PREPARE_TILES='TileManager::PrepareTiles';prepareTiles=event.findDescendentSlice(COMPOSITOR_PREPARE_TILES);if(prepareTiles)
+this.addRasterizationEvents(prepareTiles,rendererHelper,visitedEvents,flowEvents,sortedRasterizerSlices);var COMPOSITOR_ON_BIFD='Scheduler::OnBeginImplFrameDeadline';beginImplFrame=event.findDescendentSlice(COMPOSITOR_ON_BIFD);if(beginImplFrame)
+this.backtraceFromDraw(beginImplFrame,visitedEvents);}
+var INPUT_GSU='InputLatency::GestureScrollUpdate';if(this.title===INPUT_GSU)
+this.addScrollUpdateEvents(rendererHelper);},get associatedEvents(){if(this.associatedEvents_.length!==0)
+return this.associatedEvents_;var modelIndices=this.startThread.parent.model.modelIndices;var flowEvents=modelIndices.getFlowEventsWithId(this.id);if(flowEvents.length===0)
+return this.associatedEvents_;var sourceSlices=this.addDirectlyAssociatedEvents(flowEvents);var rendererHelper=this.getRendererHelper(sourceSlices);this.addOtherCausallyRelatedEvents(rendererHelper,sourceSlices,flowEvents);return this.associatedEvents_;},get inputLatency(){if(!('data'in this.args))
+return undefined;var data=this.args.data;if(!(END_COMP_NAME in data))
+return undefined;var latency=0;var endTime=data[END_COMP_NAME].time;if(ORIGINAL_COMP_NAME in data){latency=endTime-data[ORIGINAL_COMP_NAME].time;}else if(UI_COMP_NAME in data){latency=endTime-data[UI_COMP_NAME].time;}else if(BEGIN_COMP_NAME in data){latency=endTime-data[BEGIN_COMP_NAME].time;}else{throw new Error('No valid begin latency component');}
+return latency;}};var eventTypeNames=['Char','ContextMenu','GestureClick','GestureFlingCancel','GestureFlingStart','GestureScrollBegin','GestureScrollEnd','GestureScrollUpdate','GestureShowPress','GestureTap','GestureTapCancel','GestureTapDown','GesturePinchBegin','GesturePinchEnd','GesturePinchUpdate','KeyDown','KeyUp','MouseDown','MouseEnter','MouseLeave','MouseMove','MouseUp','MouseWheel','RawKeyDown','ScrollUpdate','TouchCancel','TouchEnd','TouchMove','TouchStart'];var allTypeNames=['InputLatency'];eventTypeNames.forEach(function(eventTypeName){allTypeNames.push('InputLatency:'+eventTypeName);allTypeNames.push('InputLatency::'+eventTypeName);});AsyncSlice.register(InputLatencyAsyncSlice,{typeNames:allTypeNames,categoryParts:['latencyInfo']});return{InputLatencyAsyncSlice:InputLatencyAsyncSlice,INPUT_EVENT_TYPE_NAMES:INPUT_EVENT_TYPE_NAMES};});'use strict';tr.exportTo('tr.e.rail',function(){var ColorScheme=tr.b.ColorScheme;var COMFORT_IMPORTANCE=2;var ALL_RAIL_TYPE_NAMES=['rail_response','rail_animate','rail_idle','rail_load'];var DOES_RAIL_TYPE_NAME_EXIST={};ALL_RAIL_TYPE_NAMES.forEach(function(railTypeName){DOES_RAIL_TYPE_NAME_EXIST[railTypeName]=true;});var RAIL_ORDER=[];ALL_RAIL_TYPE_NAMES.forEach(function(railTypeName){RAIL_ORDER.push(railTypeName.toUpperCase());RAIL_ORDER.push(userFriendlyRailTypeName(railTypeName).toUpperCase());});function RAILInteractionRecord(parentModel,title,railTypeName,start,duration){if(!DOES_RAIL_TYPE_NAME_EXIST[railTypeName])
+throw new Error(railTypeName+' is not listed in ALL_RAIL_TYPE_NAMES');var colorId=ColorScheme.getColorIdForReservedName(railTypeName);this.railTypeName_=railTypeName;this.name='';tr.model.InteractionRecord.call(this,parentModel,title,colorId,start,duration);}
+RAILInteractionRecord.prototype={__proto__:tr.model.InteractionRecord.prototype,updateArgs:function(){var args={};var layoutSlices=this.associatedEvents.filter(function(event){return event.title==='FrameView::layout';});var timeInLayout=tr.b.Statistics.sum(layoutSlices,function(event){return event.duration;});args['layoutInfo']={'timeInLayout':timeInLayout};this.args=args;},get railTypeName(){return this.railTypeName_;},get railScore(){var comfort=this.normalizedUserComfort;var efficiency=this.normalizedEfficiency;return weightedAverage2(comfort,efficiency,COMFORT_IMPORTANCE);},get normalizedUserComfort(){throw new Error('Not implemented');},get rawCpuMs(){var cpuMs=0;this.associatedEvents.forEach(function(event){if(event.cpuSelfTime)
+cpuMs+=event.cpuSelfTime;});return cpuMs;},get normalizedCpuEfficiency(){var minCpuMs=this.duration*this.minCpuFraction;var maxCpuMs=this.duration*this.maxCpuFraction;var normalizedCpu=tr.b.normalize(this.rawCpuMs,minCpuMs,maxCpuMs);return 1-tr.b.clamp(normalizedCpu,0,1);},get minCpuFraction(){return 0.5;},get maxCpuFraction(){return 1.5;},get normalizedEfficiency(){return this.normalizedCpuEfficiency;}};function computeNormalizedComfort(value,opts){if(typeof value!=='number')
+throw new Error('value must be a number');opts.exponentialBase=opts.exponentialBase||10;if(opts.exponentialBase<=1)
+throw new Error('exponentialBase must be greater than 1');opts.minComfortLinear=opts.minComfortLinear||0.2;if(opts.minComfortLinear<=0||opts.minComfortLinear>=1)
+throw new Error('minComfortLinear must be between 0 and 1 exclusive');opts.maxComfortLinear=opts.maxComfortLinear||0.9;if(opts.maxComfortLinear<=0||opts.maxComfortLinear>=1)
+throw new Error('maxComfortLinear must be between 0 and 1 exclusive');opts.logarithmicScale=opts.logarithmicScale||100;if(opts.logarithmicScale<=0)
+throw new Error('logarithmicScale must be positive');if(opts.minValueExponential>=opts.minValueLinear)
+throw new Error('minValueExponential must be less than minValueLinear');if(opts.minValueLinear>=opts.minValueLogarithmic)
+throw new Error('minValueLinear must be less than minValueLogarithmic');if(opts.minValueLogarithmic>=opts.maxValue)
+throw new Error('minValueLogarithmic must be less than maxValue');['minValueLinear','minValueExponential','minValueLogarithmic','maxValue','exponentialBase','minComfortLinear','maxComfortLinear','logarithmicScale'].forEach(function(opt){if(typeof opts[opt]!=='number')
+throw new Error(opt+' must be a number');});if(value<opts.minValueExponential)
+return 0;if(value<opts.minValueLinear){function computeRawComfort(value){return Math.pow(opts.exponentialBase,value);}
+return computeNormalizedComfortInternal(value,opts.minValueExponential,opts.minValueLinear,0,opts.minComfortLinear,computeRawComfort);}
+if(value<opts.minValueLogarithmic){function computeRawComfort(value){return value;}
+return computeNormalizedComfortInternal(value,opts.minValueLinear,opts.minValueLogarithmic,opts.minComfortLinear,opts.maxComfortLinear,computeRawComfort);}
+if(value<opts.maxValue){function computeRawComfort(value){return Math.log1p(opts.logarithmicScale*value);}
+return computeNormalizedComfortInternal(value,opts.minValueLogarithmic,opts.maxValue,opts.maxComfortLinear,1,computeRawComfort);}
+return 1;}
+function computeNormalizedComfortInternal(value,minValue,maxValue,minScore,maxScore,computeRawComfort){var normalizedValue=tr.b.normalize(value,minValue,maxValue);var rawComfort=computeRawComfort(normalizedValue);var minComfort=computeRawComfort(0);var maxComfort=computeRawComfort(1);var normalizedComfort=tr.b.normalize(rawComfort,minComfort,maxComfort);normalizedComfort=tr.b.lerp(normalizedComfort,minScore,maxScore);return tr.b.clamp(normalizedComfort,minScore,maxScore);}
+function weightedAverage2(x,y,opt_apriori){var numerator=0;var denominator=0;var xWeight=(opt_apriori||1)*Math.exp(1-x);numerator+=xWeight*x;denominator+=xWeight;var yWeight=Math.exp(1-y);numerator+=yWeight*y;denominator+=yWeight;return numerator/denominator;}
+function userFriendlyRailTypeName(railTypeName){if(railTypeName.length<6||railTypeName.indexOf('rail_')!=0)
+return railTypeName;return railTypeName[5].toUpperCase()+railTypeName.slice(6);}
+function railCompare(name1,name2){var i1=RAIL_ORDER.indexOf(name1.toUpperCase());var i2=RAIL_ORDER.indexOf(name2.toUpperCase());if(i1==-1&&i2==-1)
+return name1.localeCompare(name2);if(i1==-1)
+return 1;if(i2==-1)
+return-1;return i1-i2;}
+return{RAILInteractionRecord:RAILInteractionRecord,computeNormalizedComfort:computeNormalizedComfort,weightedAverage2:weightedAverage2,userFriendlyRailTypeName:userFriendlyRailTypeName,railCompare:railCompare,ALL_RAIL_TYPE_NAMES:ALL_RAIL_TYPE_NAMES};});'use strict';tr.exportTo('tr.e.rail',function(){function IdleInteractionRecord(parentModel,start,duration){tr.e.rail.RAILInteractionRecord.call(this,parentModel,'Idle','rail_idle',start,duration);}
+IdleInteractionRecord.prototype={__proto__:tr.e.rail.RAILInteractionRecord.prototype,get normalizedUserComfort(){return 1;},get minCpuFraction(){return 0.1;},get maxCpuFraction(){return 1;}};return{IdleInteractionRecord:IdleInteractionRecord};});'use strict';tr.exportTo('tr.e.rail',function(){var COMFORT_LATENCY_REGIONS=[1000,5000,20000,60000];function LoadInteractionRecord(parentModel,start,duration){tr.e.rail.RAILInteractionRecord.call(this,parentModel,'Load','rail_load',start,duration);this.renderProcessId=undefined;this.routingId=undefined;this.parentRoutingId=undefined;}
+LoadInteractionRecord.prototype={__proto__:tr.e.rail.RAILInteractionRecord.prototype,get normalizedUserComfort(){return 1-tr.e.rail.computeNormalizedComfort(this.duration,{minValueExponential:COMFORT_LATENCY_REGIONS[0],minValueLinear:COMFORT_LATENCY_REGIONS[1],minValueLogarithmic:COMFORT_LATENCY_REGIONS[2],maxValue:COMFORT_LATENCY_REGIONS[3]});}};return{LoadInteractionRecord:LoadInteractionRecord};});'use strict';tr.exportTo('tr.e.rail',function(){var COMFORT_FPS_REGIONS=[60,40,30,10];var LONG_FRAME_MS=50;var COMFORT_JANK_REGIONS=[0.05,0.1,0.2,0.3];function AnimationInteractionRecord(parentModel,start,duration){tr.e.rail.RAILInteractionRecord.call(this,parentModel,'Animation','rail_animate',start,duration);this.frameEvents_=undefined;}
+AnimationInteractionRecord.prototype={__proto__:tr.e.rail.RAILInteractionRecord.prototype,get frameEvents(){if(this.frameEvents_)
+return this.frameEvents_;this.frameEvents_=new tr.model.EventSet();this.associatedEvents.forEach(function(event){if(event.title===tr.e.audits.IMPL_RENDERING_STATS)
+this.frameEvents_.push(event);},this);return this.frameEvents_;},get normalizedUserComfort(){return tr.e.rail.weightedAverage2(this.normalizedJankComfort,this.normalizedFPSComfort);},get normalizedFPSComfort(){var durationSeconds=this.duration/1000;var avgSpf=durationSeconds/this.frameEvents.length;return 1-tr.e.rail.computeNormalizedComfort(avgSpf,{minValueExponential:1/COMFORT_FPS_REGIONS[0],minValueLinear:1/COMFORT_FPS_REGIONS[1],minValueLogarithmic:1/COMFORT_FPS_REGIONS[2],maxValue:1/COMFORT_FPS_REGIONS[3]});},get normalizedJankComfort(){var frameTimestamps=this.frameEvents.toArray().map(function(event){return event.start;});var absolute=false;var discrepancy=tr.b.Statistics.timestampsDiscrepancy(frameTimestamps,absolute);return 1-tr.e.rail.computeNormalizedComfort(discrepancy,{minValueExponential:COMFORT_JANK_REGIONS[0],minValueLinear:COMFORT_JANK_REGIONS[1],minValueLogarithmic:COMFORT_JANK_REGIONS[2],maxValue:COMFORT_JANK_REGIONS[3]});}};return{AnimationInteractionRecord:AnimationInteractionRecord};});'use strict';tr.exportTo('tr.e.rail',function(){var COMFORT_LATENCY_REGIONS=[150,300,1000,5000];function ResponseInteractionRecord(parentModel,start,duration){tr.e.rail.RAILInteractionRecord.call(this,parentModel,'Response','rail_response',start,duration);}
+ResponseInteractionRecord.prototype={__proto__:tr.e.rail.RAILInteractionRecord.prototype,get normalizedUserComfort(){return 1-tr.e.rail.computeNormalizedComfort(this.duration,{minValueExponential:COMFORT_LATENCY_REGIONS[0],minValueLinear:COMFORT_LATENCY_REGIONS[1],minValueLogarithmic:COMFORT_LATENCY_REGIONS[2],maxValue:COMFORT_LATENCY_REGIONS[3]});}};return{ResponseInteractionRecord:ResponseInteractionRecord};});'use strict';tr.exportTo('tr.e.rail',function(){function ProtoIR(irType,name){this.irType=irType;this.names=new Set(name?[name]:undefined);this.start=Infinity;this.end=-Infinity;this.associatedEvents=new tr.model.EventSet();}
+ProtoIR.RESPONSE_TYPE='r';ProtoIR.ANIMATION_TYPE='a';ProtoIR.IGNORED_TYPE='ignored';ProtoIR.prototype={get isValid(){return this.end>this.start;},containsTypeNames:function(typeNames){for(var i=0;i<this.associatedEvents.length;++i){if(typeNames.indexOf(this.associatedEvents[i].typeName)>=0)
+return true;}
+return false;},containsSliceTitle:function(title){for(var i=0;i<this.associatedEvents.length;++i){if(title===this.associatedEvents[i].title)
+return true;}
+return false;},getIRConstructor:function(){switch(this.irType){case ProtoIR.RESPONSE_TYPE:return tr.e.rail.ResponseInteractionRecord;case ProtoIR.ANIMATION_TYPE:return tr.e.rail.AnimationInteractionRecord;}
+return undefined;},createInteractionRecord:function(model){if(!this.isValid){console.error('Invalid ProtoIR: '+this.debug()+' File a bug with this trace!');return undefined;}
+var constructor=this.getIRConstructor();if(constructor===undefined)
+return undefined;var ir=new constructor(model,this.start,this.end-this.start);var names=[];this.names.forEach(function(name){names.push(name);});ir.name=names.sort().join(',');ir.sourceEvents.addEventSet(this.associatedEvents);function pushAssociatedEvents(event){ir.associatedEvents.push(event);if(event.associatedEvents)
+ir.associatedEvents.addEventSet(event.associatedEvents);}
+this.associatedEvents.forEach(function(event){pushAssociatedEvents(event);if(event.subSlices)
+event.subSlices.forEach(pushAssociatedEvents);});return ir;},merge:function(other){other.names.forEach(function(name){this.names.add(name);}.bind(this));this.associatedEvents.addEventSet(other.associatedEvents);this.start=Math.min(this.start,other.start);this.end=Math.max(this.end,other.end);},pushEvent:function(event){this.start=Math.min(this.start,event.start);this.end=Math.max(this.end,event.end);this.associatedEvents.push(event);},containsTimestampInclusive:function(timestamp){return(this.start<=timestamp)&&(timestamp<=this.end);},intersects:function(other){return(other.start<this.end)&&(other.end>this.start);},isNear:function(event,threshold){return(this.end+threshold)>event.start;},debug:function(){var debugString=this.irType+'(';debugString+=parseInt(this.start)+' ';debugString+=parseInt(this.end);this.associatedEvents.forEach(function(event){debugString+=' '+event.typeName;});return debugString+')';}};return{ProtoIR:ProtoIR};});'use strict';tr.exportTo('tr.model',function(){function getAssociatedEvents(irs){var allAssociatedEvents=new tr.model.EventSet();irs.forEach(function(ir){ir.associatedEvents.forEach(function(event){if(event instanceof tr.model.FlowEvent)
+return;allAssociatedEvents.push(event);});});return allAssociatedEvents;}
+function getUnassociatedEvents(model,associatedEvents){var unassociatedEvents=new tr.model.EventSet();model.getAllProcesses().forEach(function(process){for(var tid in process.threads){var thread=process.threads[tid];thread.sliceGroup.iterateAllEvents(function(event){if(!associatedEvents.contains(event))
+unassociatedEvents.push(event);});}});return unassociatedEvents;}
+function getTotalCpuDuration(events){var cpuMs=0;events.forEach(function(event){if(event.cpuSelfTime)
+cpuMs+=event.cpuSelfTime;});return cpuMs;}
+function getIRCoverageFromModel(model){var associatedEvents=getAssociatedEvents(model.interactionRecords);if(!associatedEvents.length)
+return undefined;var unassociatedEvents=getUnassociatedEvents(model,associatedEvents);var associatedCpuMs=getTotalCpuDuration(associatedEvents);var unassociatedCpuMs=getTotalCpuDuration(unassociatedEvents);var totalEventCount=associatedEvents.length+unassociatedEvents.length;var totalCpuMs=associatedCpuMs+unassociatedCpuMs;return{associatedEventsCount:associatedEvents.length,unassociatedEventsCount:unassociatedEvents.length,associatedEventsCpuTimeMs:associatedCpuMs,unassociatedEventsCpuTimeMs:unassociatedCpuMs,coveredEventsCountRatio:associatedEvents.length/totalEventCount,coveredEventsCpuTimeRatio:associatedCpuMs/totalCpuMs};}
+return{getIRCoverageFromModel:getIRCoverageFromModel,getAssociatedEvents:getAssociatedEvents,getUnassociatedEvents:getUnassociatedEvents};});'use strict';tr.exportTo('tr.e.rail',function(){var INPUT_TYPE=tr.e.cc.INPUT_EVENT_TYPE_NAMES;var ProtoIR=tr.e.rail.ProtoIR;function compareEvents(x,y){if(x.start!==y.start)
+return x.start-y.start;if(x.end!==y.end)
+return x.end-y.end;if(x.guid&&y.guid)
+return x.guid-y.guid;return 0;}
+function causedFrame(event){for(var i=0;i<event.associatedEvents.length;++i){if(event.associatedEvents[i].title===tr.e.audits.IMPL_RENDERING_STATS)
+return true;}
+return false;}
+function forEventTypesIn(events,typeNames,cb,opt_this){events.forEach(function(event){if(typeNames.indexOf(event.typeName)>=0){cb.call(opt_this,event);}});}
+var RENDER_FRAME_IMPL_PREFIX='RenderFrameImpl::';var CREATE_CHILD_TITLE=RENDER_FRAME_IMPL_PREFIX+'createChildFrame';var START_LOAD_TITLE=RENDER_FRAME_IMPL_PREFIX+'didStartProvisionalLoad';var FAIL_LOAD_TITLE=RENDER_FRAME_IMPL_PREFIX+'didFailProvisionalLoad';function isRenderFrameImplEvent(event){return event.title.indexOf(RENDER_FRAME_IMPL_PREFIX)===0;}
+var INPUT_MERGE_THRESHOLD_MS=200;var ANIMATION_MERGE_THRESHOLD_MS=1;var MOUSE_WHEEL_THRESHOLD_MS=40;var MOUSE_MOVE_THRESHOLD_MS=40;var INSIGNIFICANT_MS=1;var KEYBOARD_TYPE_NAMES=[INPUT_TYPE.CHAR,INPUT_TYPE.KEY_DOWN_RAW,INPUT_TYPE.KEY_DOWN,INPUT_TYPE.KEY_UP];var MOUSE_RESPONSE_TYPE_NAMES=[INPUT_TYPE.CLICK,INPUT_TYPE.CONTEXT_MENU];var MOUSE_WHEEL_TYPE_NAMES=[INPUT_TYPE.MOUSE_WHEEL];var MOUSE_DRAG_TYPE_NAMES=[INPUT_TYPE.MOUSE_DOWN,INPUT_TYPE.MOUSE_MOVE,INPUT_TYPE.MOUSE_UP];var TAP_TYPE_NAMES=[INPUT_TYPE.TAP,INPUT_TYPE.TAP_CANCEL,INPUT_TYPE.TAP_DOWN];var PINCH_TYPE_NAMES=[INPUT_TYPE.PINCH_BEGIN,INPUT_TYPE.PINCH_END,INPUT_TYPE.PINCH_UPDATE];var FLING_TYPE_NAMES=[INPUT_TYPE.FLING_CANCEL,INPUT_TYPE.FLING_START];var TOUCH_TYPE_NAMES=[INPUT_TYPE.TOUCH_END,INPUT_TYPE.TOUCH_MOVE,INPUT_TYPE.TOUCH_START];var SCROLL_TYPE_NAMES=[INPUT_TYPE.SCROLL_BEGIN,INPUT_TYPE.SCROLL_END,INPUT_TYPE.SCROLL_UPDATE];var ALL_HANDLED_TYPE_NAMES=[].concat(KEYBOARD_TYPE_NAMES,MOUSE_RESPONSE_TYPE_NAMES,MOUSE_WHEEL_TYPE_NAMES,MOUSE_DRAG_TYPE_NAMES,PINCH_TYPE_NAMES,TAP_TYPE_NAMES,FLING_TYPE_NAMES,TOUCH_TYPE_NAMES,SCROLL_TYPE_NAMES);var RENDERER_FLING_TITLE='InputHandlerProxy::HandleGestureFling::started';var CSS_ANIMATION_TITLE='Animation';var LOAD_STARTUP_IR_NAME='Startup';var LOAD_SUCCEEDED_IR_NAME='Succeeded';var LOAD_FAILED_IR_NAME='Failed';var KEYBOARD_IR_NAME='Keyboard';var MOUSE_IR_NAME='Mouse';var MOUSEWHEEL_IR_NAME='MouseWheel';var TAP_IR_NAME='Tap';var PINCH_IR_NAME='Pinch';var FLING_IR_NAME='Fling';var TOUCH_IR_NAME='Touch';var SCROLL_IR_NAME='Scroll';var CSS_IR_NAME='CSS';function RAILIRFinder(model,modelHelper){this.model=model;this.modelHelper=modelHelper;};RAILIRFinder.supportsModelHelper=function(modelHelper){return modelHelper.browserHelper!==undefined;};RAILIRFinder.prototype={findAllInteractionRecords:function(){var rirs=[];rirs.push.apply(rirs,this.findLoadInteractionRecords());rirs.push.apply(rirs,this.findInputInteractionRecords());rirs.push.apply(rirs,this.findIdleInteractionRecords(rirs));this.collectUnassociatedEvents_(rirs);return rirs;},setIRNames_:function(name,irs){irs.forEach(function(ir){ir.name=name;});},collectUnassociatedEvents_:function(rirs){var vacuumIRs=[];rirs.forEach(function(ir){if(ir instanceof tr.e.rail.LoadInteractionRecord||ir instanceof tr.e.rail.IdleInteractionRecord)
+vacuumIRs.push(ir);});if(vacuumIRs.length===0)
+return;var allAssociatedEvents=tr.model.getAssociatedEvents(rirs);var unassociatedEvents=tr.model.getUnassociatedEvents(this.model,allAssociatedEvents);unassociatedEvents.forEach(function(event){if(!(event instanceof tr.model.ThreadSlice))
+return;if(!event.isTopLevel)
+return;for(var iri=0;iri<vacuumIRs.length;++iri){var ir=vacuumIRs[iri];if((event.start>=ir.start)&&(event.start<ir.end)){ir.associatedEvents.addEventSet(event.entireHierarchy);return;}}});},findIdleInteractionRecords:function(otherIRs){if(this.model.bounds.isEmpty)
+return;var emptyRanges=tr.b.findEmptyRangesBetweenRanges(tr.b.convertEventsToRanges(otherIRs),this.model.bounds);var irs=[];var model=this.model;emptyRanges.forEach(function(range){if(range.max<(range.min+INSIGNIFICANT_MS))
+return;irs.push(new tr.e.rail.IdleInteractionRecord(model,range.min,range.max-range.min));});return irs;},getAllFrameEvents:function(){var frameEvents=[];frameEvents.push.apply(frameEvents,this.modelHelper.browserHelper.getFrameEventsInRange(tr.e.audits.IMPL_FRAMETIME_TYPE,this.model.bounds));tr.b.iterItems(this.modelHelper.rendererHelpers,function(pid,renderer){frameEvents.push.apply(frameEvents,renderer.getFrameEventsInRange(tr.e.audits.IMPL_FRAMETIME_TYPE,this.model.bounds));},this);return frameEvents.sort(compareEvents);},getStartLoadEvents:function(){function isStartLoadSlice(slice){return slice.title===START_LOAD_TITLE;}
+return this.modelHelper.browserHelper.getAllAsyncSlicesMatching(isStartLoadSlice).sort(compareEvents);},getFailLoadEvents:function(){function isFailLoadSlice(slice){return slice.title===FAIL_LOAD_TITLE;}
+return this.modelHelper.browserHelper.getAllAsyncSlicesMatching(isFailLoadSlice).sort(compareEvents);},getStartupEvents:function(){function isStartupSlice(slice){return slice.title==='BrowserMainLoop::CreateThreads';}
+var events=this.modelHelper.browserHelper.getAllAsyncSlicesMatching(isStartupSlice);var deduper=new tr.model.EventSet();events.forEach(function(event){var sliceGroup=event.parentContainer.sliceGroup;var slice=sliceGroup&&sliceGroup.findFirstSlice();if(slice)
+deduper.push(slice);});return deduper.toArray();},findLoadInteractionRecords_:function(openingEvents,closingEvents){var lirs=[];var model=this.model;openingEvents.forEach(function(openingEvent){closingEvents.forEach(function(closingEvent){if(openingEvent.closingEvent)
+return;if(closingEvent.openingEvent)
+return;if(closingEvent.start<=openingEvent.start)
+return;if(openingEvent.parentContainer.parent.pid!==closingEvent.parentContainer.parent.pid)
+return;openingEvent.closingEvent=closingEvent;closingEvent.openingEvent=openingEvent;var lir=new tr.e.rail.LoadInteractionRecord(model,openingEvent.start,closingEvent.end-openingEvent.start);lir.associatedEvents.push(openingEvent);lir.associatedEvents.push(closingEvent);if(isRenderFrameImplEvent(openingEvent)){lir.renderProcessId=openingEvent.parentContainer.parent.pid;lir.routingId=openingEvent.args.id;lir.parentRoutingId=this.findLoadParentRoutingId_(lir);}
+lirs.push(lir);},this);},this);return lirs;},findLoadParentRoutingId_:function(lir){function isCreateChildEvent(event){return((event.title===CREATE_CHILD_TITLE)&&(event.parentContainer.parent.pid===lir.renderProcessId)&&(event.args.child===lir.routingId));}
+var parentRoutingId=undefined;this.modelHelper.browserHelper.getAllAsyncSlicesMatching(isCreateChildEvent).forEach(function(event){parentRoutingId=event.args.id;});return parentRoutingId;},findLoadInteractionRecords:function(){var startupEvents=this.getStartupEvents();var commitLoadEvents=this.modelHelper.browserHelper.getCommitProvisionalLoadEventsInRange(this.model.bounds);var frameEvents=this.getAllFrameEvents();var startLoadEvents=this.getStartLoadEvents();var failLoadEvents=this.getFailLoadEvents();var lirs=[];var startupLIRs=this.findLoadInteractionRecords_(startupEvents,frameEvents);this.setIRNames_(LOAD_STARTUP_IR_NAME,startupLIRs);lirs.push.apply(lirs,startupLIRs);var successfulLIRs=this.findLoadInteractionRecords_(commitLoadEvents,frameEvents);this.setIRNames_(LOAD_SUCCEEDED_IR_NAME,successfulLIRs);var renderLIRs=successfulLIRs;var failedLIRs=this.findLoadInteractionRecords_(startLoadEvents,failLoadEvents);this.setIRNames_(LOAD_FAILED_IR_NAME,failedLIRs);renderLIRs.push.apply(renderLIRs,failedLIRs);renderLIRs.forEach(function(lir){if(lir.parentRoutingId===undefined){lirs.push(lir);}},this);return lirs;},findInputInteractionRecords:function(){var sortedInputEvents=this.getSortedInputEvents();var protoIRs=this.findProtoIRs(sortedInputEvents);protoIRs=this.postProcessProtoIRs(protoIRs);this.checkAllInputEventsHandled(sortedInputEvents,protoIRs);var irs=[];var model=this.model;protoIRs.forEach(function(protoIR){var ir=protoIR.createInteractionRecord(model);if(ir)
+irs.push(ir);});return irs;},findProtoIRs:function(sortedInputEvents){var protoIRs=[];var handlers=[this.handleKeyboardEvents,this.handleMouseResponseEvents,this.handleMouseWheelEvents,this.handleMouseDragEvents,this.handleTapResponseEvents,this.handlePinchEvents,this.handleFlingEvents,this.handleTouchEvents,this.handleScrollEvents,this.handleCSSAnimations];handlers.forEach(function(handler){protoIRs.push.apply(protoIRs,handler.call(this,sortedInputEvents));},this);protoIRs.sort(compareEvents);return protoIRs;},getSortedInputEvents:function(){var inputEvents=[];var browserProcess=this.modelHelper.browserHelper.process;var mainThread=browserProcess.findAtMostOneThreadNamed('CrBrowserMain');mainThread.asyncSliceGroup.iterateAllEvents(function(slice){if(!slice.isTopLevel)
+return;if(!(slice instanceof tr.e.cc.InputLatencyAsyncSlice))
+return;if(isNaN(slice.start)||isNaN(slice.duration)||isNaN(slice.end))
+return;inputEvents.push(slice);},this);return inputEvents.sort(compareEvents);},handleKeyboardEvents:function(sortedInputEvents){var protoIRs=[];forEventTypesIn(sortedInputEvents,KEYBOARD_TYPE_NAMES,function(event){var pir=new ProtoIR(ProtoIR.RESPONSE_TYPE,KEYBOARD_IR_NAME);pir.pushEvent(event);protoIRs.push(pir);});return protoIRs;},handleMouseResponseEvents:function(sortedInputEvents){var protoIRs=[];forEventTypesIn(sortedInputEvents,MOUSE_RESPONSE_TYPE_NAMES,function(event){var pir=new ProtoIR(ProtoIR.RESPONSE_TYPE,MOUSE_IR_NAME);pir.pushEvent(event);protoIRs.push(pir);});return protoIRs;},handleMouseWheelEvents:function(sortedInputEvents){var protoIRs=[];var currentPIR=undefined;var prevEvent_=undefined;forEventTypesIn(sortedInputEvents,MOUSE_WHEEL_TYPE_NAMES,function(event){var prevEvent=prevEvent_;prevEvent_=event;if(currentPIR&&(prevEvent.start+MOUSE_WHEEL_THRESHOLD_MS)>=event.start){if(currentPIR.irType===ProtoIR.ANIMATION_TYPE){currentPIR.pushEvent(event);}else{currentPIR=new ProtoIR(ProtoIR.ANIMATION_TYPE,MOUSEWHEEL_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);}
+return;}
+currentPIR=new ProtoIR(ProtoIR.RESPONSE_TYPE,MOUSEWHEEL_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);});return protoIRs;},handleMouseDragEvents:function(sortedInputEvents){var protoIRs=[];var currentPIR=undefined;var mouseDownEvent=undefined;forEventTypesIn(sortedInputEvents,MOUSE_DRAG_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.MOUSE_DOWN:if(causedFrame(event)){var pir=new ProtoIR(ProtoIR.RESPONSE_TYPE,MOUSE_IR_NAME);pir.pushEvent(event);protoIRs.push(pir);}else{mouseDownEvent=event;}
+break;case INPUT_TYPE.MOUSE_MOVE:if(!causedFrame(event)){var pir=new ProtoIR(ProtoIR.IGNORED_TYPE);pir.pushEvent(event);protoIRs.push(pir);}else if(!currentPIR||!currentPIR.isNear(event,MOUSE_MOVE_THRESHOLD_MS)){currentPIR=new ProtoIR(ProtoIR.RESPONSE_TYPE,MOUSE_IR_NAME);currentPIR.pushEvent(event);if(mouseDownEvent){currentPIR.associatedEvents.push(mouseDownEvent);mouseDownEvent=undefined;}
+protoIRs.push(currentPIR);}else{if(currentPIR.irType===ProtoIR.ANIMATION_TYPE){currentPIR.pushEvent(event);}else{currentPIR=new ProtoIR(ProtoIR.ANIMATION_TYPE,MOUSE_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);}}
+break;case INPUT_TYPE.MOUSE_UP:if(!mouseDownEvent){var pir=new ProtoIR(causedFrame(event)?ProtoIR.RESPONSE_TYPE:ProtoIR.IGNORED_TYPE,MOUSE_IR_NAME);pir.pushEvent(event);protoIRs.push(pir);break;}
+if(currentPIR){currentPIR.pushEvent(event);}else{currentPIR=new ProtoIR(ProtoIR.RESPONSE_TYPE,MOUSE_IR_NAME);if(mouseDownEvent)
+currentPIR.associatedEvents.push(mouseDownEvent);currentPIR.pushEvent(event);protoIRs.push(currentPIR);}
+mouseDownEvent=undefined;currentPIR=undefined;break;}});if(mouseDownEvent){currentPIR=new ProtoIR(ProtoIR.IGNORED_TYPE);currentPIR.pushEvent(mouseDownEvent);protoIRs.push(currentPIR);}
+return protoIRs;},handleTapResponseEvents:function(sortedInputEvents){var protoIRs=[];var currentPIR=undefined;forEventTypesIn(sortedInputEvents,TAP_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.TAP_DOWN:currentPIR=new ProtoIR(ProtoIR.RESPONSE_TYPE,TAP_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);break;case INPUT_TYPE.TAP:if(currentPIR){currentPIR.pushEvent(event);}else{currentPIR=new ProtoIR(ProtoIR.RESPONSE_TYPE,TAP_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);}
+currentPIR=undefined;break;case INPUT_TYPE.TAP_CANCEL:if(!currentPIR){var pir=new ProtoIR(ProtoIR.IGNORED_TYPE);pir.pushEvent(event);protoIRs.push(pir);break;}
+if(currentPIR.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPIR.pushEvent(event);}else{currentPIR=new ProtoIR(ProtoIR.RESPONSE_TYPE,TAP_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);}
+currentPIR=undefined;break;}});return protoIRs;},handlePinchEvents:function(sortedInputEvents){var protoIRs=[];var currentPIR=undefined;var sawFirstUpdate=false;var modelBounds=this.model.bounds;forEventTypesIn(sortedInputEvents,PINCH_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.PINCH_BEGIN:if(currentPIR&&currentPIR.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPIR.pushEvent(event);break;}
+currentPIR=new ProtoIR(ProtoIR.RESPONSE_TYPE,PINCH_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);sawFirstUpdate=false;break;case INPUT_TYPE.PINCH_UPDATE:if(!currentPIR||((currentPIR.irType===ProtoIR.RESPONSE_TYPE)&&sawFirstUpdate)||!currentPIR.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPIR=new ProtoIR(ProtoIR.ANIMATION_TYPE,PINCH_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);}else{currentPIR.pushEvent(event);sawFirstUpdate=true;}
+break;case INPUT_TYPE.PINCH_END:if(currentPIR){currentPIR.pushEvent(event);}else{var pir=new ProtoIR(ProtoIR.IGNORED_TYPE);pir.pushEvent(event);protoIRs.push(pir);}
+currentPIR=undefined;break;}});return protoIRs;},handleFlingEvents:function(sortedInputEvents){var protoIRs=[];var currentPIR=undefined;function isRendererFling(event){return event.title===RENDERER_FLING_TITLE;}
+var browserHelper=this.modelHelper.browserHelper;var flingEvents=browserHelper.getAllAsyncSlicesMatching(isRendererFling);forEventTypesIn(sortedInputEvents,FLING_TYPE_NAMES,function(event){flingEvents.push(event);});flingEvents.sort(compareEvents);flingEvents.forEach(function(event){if(event.title===RENDERER_FLING_TITLE){if(currentPIR){currentPIR.pushEvent(event);}else{currentPIR=new ProtoIR(ProtoIR.ANIMATION_TYPE,FLING_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);}
+return;}
+switch(event.typeName){case INPUT_TYPE.FLING_START:if(currentPIR){console.error('Another FlingStart? File a bug with this trace!');currentPIR.pushEvent(event);}else{currentPIR=new ProtoIR(ProtoIR.ANIMATION_TYPE,FLING_IR_NAME);currentPIR.pushEvent(event);currentPIR.end=0;protoIRs.push(currentPIR);}
+break;case INPUT_TYPE.FLING_CANCEL:if(currentPIR){currentPIR.pushEvent(event);currentPIR.end=event.start;currentPIR=undefined;}else{var pir=new ProtoIR(ProtoIR.IGNORED_TYPE);pir.pushEvent(event);protoIRs.push(pir);}
+break;}});if(currentPIR&&!currentPIR.end)
+currentPIR.end=this.model.bounds.max;return protoIRs;},handleTouchEvents:function(sortedInputEvents){var protoIRs=[];var currentPIR=undefined;var sawFirstMove=false;forEventTypesIn(sortedInputEvents,TOUCH_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.TOUCH_START:if(currentPIR){currentPIR.pushEvent(event);}else{currentPIR=new ProtoIR(ProtoIR.RESPONSE_TYPE,TOUCH_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);sawFirstMove=false;}
+break;case INPUT_TYPE.TOUCH_MOVE:if(!currentPIR){currentPIR=new ProtoIR(ProtoIR.ANIMATION_TYPE,TOUCH_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);break;}
+if((sawFirstMove&&(currentPIR.irType===ProtoIR.RESPONSE_TYPE))||!currentPIR.isNear(event,INPUT_MERGE_THRESHOLD_MS)){var prevEnd=currentPIR.end;currentPIR=new ProtoIR(ProtoIR.ANIMATION_TYPE,TOUCH_IR_NAME);currentPIR.pushEvent(event);currentPIR.start=prevEnd;protoIRs.push(currentPIR);}else{currentPIR.pushEvent(event);sawFirstMove=true;}
+break;case INPUT_TYPE.TOUCH_END:if(!currentPIR){var pir=new ProtoIR(ProtoIR.IGNORED_TYPE);pir.pushEvent(event);protoIRs.push(pir);break;}
+if(currentPIR.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPIR.pushEvent(event);}else{var pir=new ProtoIR(ProtoIR.IGNORED_TYPE);pir.pushEvent(event);protoIRs.push(pir);}
+currentPIR=undefined;break;}});return protoIRs;},handleScrollEvents:function(sortedInputEvents){var protoIRs=[];var currentPIR=undefined;var sawFirstUpdate=false;forEventTypesIn(sortedInputEvents,SCROLL_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.SCROLL_BEGIN:currentPIR=new ProtoIR(ProtoIR.RESPONSE_TYPE,SCROLL_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);sawFirstUpdate=false;break;case INPUT_TYPE.SCROLL_UPDATE:if(currentPIR){if(currentPIR.isNear(event,INPUT_MERGE_THRESHOLD_MS)&&((currentPIR.irType===ProtoIR.ANIMATION_TYPE)||!sawFirstUpdate)){currentPIR.pushEvent(event);sawFirstUpdate=true;}else{currentPIR=new ProtoIR(ProtoIR.ANIMATION_TYPE,SCROLL_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);}}else{currentPIR=new ProtoIR(ProtoIR.ANIMATION_TYPE,SCROLL_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);}
+break;case INPUT_TYPE.SCROLL_END:if(!currentPIR){console.error('ScrollEnd without ScrollUpdate? '+'File a bug with this trace!');var pir=new ProtoIR(ProtoIR.IGNORED_TYPE);pir.pushEvent(event);protoIRs.push(pir);break;}
+currentPIR.pushEvent(event);break;}});return protoIRs;},handleCSSAnimations:function(sortedInputEvents){var animationEvents=this.modelHelper.browserHelper.getAllAsyncSlicesMatching(function(event){return((event.title===CSS_ANIMATION_TITLE)&&(event.duration>0));});var animationRanges=[];animationEvents.forEach(function(event){animationRanges.push({min:event.start,max:event.end,event:event});});function merge(ranges){var protoIR=new ProtoIR(ProtoIR.ANIMATION_TYPE,CSS_IR_NAME);ranges.forEach(function(range){protoIR.pushEvent(range.event);});return protoIR;}
+return tr.b.mergeRanges(animationRanges,ANIMATION_MERGE_THRESHOLD_MS,merge);},postProcessProtoIRs:function(protoIRs){protoIRs=this.mergeIntersectingResponses(protoIRs);protoIRs=this.mergeIntersectingAnimations(protoIRs);protoIRs=this.fixResponseAnimationStarts(protoIRs);protoIRs=this.fixTapResponseTouchAnimations(protoIRs);return protoIRs;},mergeIntersectingResponses:function(protoIRs){var newPIRs=[];while(protoIRs.length){var pir=protoIRs.shift();newPIRs.push(pir);if(pir.irType!==ProtoIR.RESPONSE_TYPE)
+continue;for(var i=0;i<protoIRs.length;++i){var otherPIR=protoIRs[i];if(otherPIR.irType!==pir.irType)
+continue;if(!otherPIR.intersects(pir))
+continue;var typeNames=pir.associatedEvents.map(function(event){return event.typeName;});if(otherPIR.containsTypeNames(typeNames))
+continue;pir.merge(otherPIR);protoIRs.splice(i,1);--i;}}
+return newPIRs;},mergeIntersectingAnimations:function(protoIRs){var newPIRs=[];while(protoIRs.length){var pir=protoIRs.shift();newPIRs.push(pir);if(pir.irType!==ProtoIR.ANIMATION_TYPE)
+continue;var isCSS=pir.containsSliceTitle(CSS_ANIMATION_TITLE);var isFling=pir.containsTypeNames([INPUT_TYPE.FLING_START]);for(var i=0;i<protoIRs.length;++i){var otherPIR=protoIRs[i];if(otherPIR.irType!==pir.irType)
+continue;if(isCSS!=otherPIR.containsSliceTitle(CSS_ANIMATION_TITLE))
+continue;if(!otherPIR.intersects(pir))
+continue;if(isFling!=otherPIR.containsTypeNames([INPUT_TYPE.FLING_START]))
+continue;pir.merge(otherPIR);protoIRs.splice(i,1);--i;}}
+return newPIRs;},fixResponseAnimationStarts:function(protoIRs){protoIRs.forEach(function(apir){if(apir.irType!==ProtoIR.ANIMATION_TYPE)
+return;protoIRs.forEach(function(rpir){if(rpir.irType!==ProtoIR.RESPONSE_TYPE)
+return;if(!apir.containsTimestampInclusive(rpir.end))
+return;if(apir.containsTimestampInclusive(rpir.start))
+return;apir.start=rpir.end;});});return protoIRs;},fixTapResponseTouchAnimations:function(protoIRs){function isTapResponse(pir){return(pir.irType===ProtoIR.RESPONSE_TYPE)&&pir.containsTypeNames([INPUT_TYPE.TAP]);}
+function isTouchAnimation(pir){return(pir.irType===ProtoIR.ANIMATION_TYPE)&&pir.containsTypeNames([INPUT_TYPE.TOUCH_MOVE])&&!pir.containsTypeNames([INPUT_TYPE.SCROLL_UPDATE,INPUT_TYPE.PINCH_UPDATE]);}
+var newPIRs=[];while(protoIRs.length){var pir=protoIRs.shift();newPIRs.push(pir);var pirIsTapResponse=isTapResponse(pir);var pirIsTouchAnimation=isTouchAnimation(pir);if(!pirIsTapResponse&&!pirIsTouchAnimation)
+continue;for(var i=0;i<protoIRs.length;++i){var otherPIR=protoIRs[i];if(!otherPIR.intersects(pir))
+continue;if(pirIsTapResponse&&!isTouchAnimation(otherPIR))
+continue;if(pirIsTouchAnimation&&!isTapResponse(otherPIR))
+continue;pir.irType=ProtoIR.RESPONSE_TYPE;pir.merge(otherPIR);protoIRs.splice(i,1);--i;}}
+return newPIRs;},checkAllInputEventsHandled:function(sortedInputEvents,protoIRs){var handledEvents=[];protoIRs.forEach(function(protoIR){protoIR.associatedEvents.forEach(function(event){if(handledEvents.indexOf(event)>=0){console.error('double-handled event',event.typeName,parseInt(event.start),parseInt(event.end),protoIR);return;}
+handledEvents.push(event);});});sortedInputEvents.forEach(function(event){if(handledEvents.indexOf(event)<0){console.error('UNHANDLED INPUT EVENT!',event.typeName,parseInt(event.start),parseInt(event.end));}});}};function createCustomizeModelLinesFromModel(model){var modelLines=[];modelLines.push('      audits.addEvent(model.browserMain,');modelLines.push('          {title: \'model start\', start: 0, end: 1});');var typeNames={};for(var typeName in tr.e.cc.INPUT_EVENT_TYPE_NAMES){typeNames[tr.e.cc.INPUT_EVENT_TYPE_NAMES[typeName]]=typeName;}
+var modelEvents=new tr.model.EventSet();model.interactionRecords.forEach(function(ir,index){modelEvents.addEventSet(ir.sourceEvents);});modelEvents=modelEvents.toArray();modelEvents.sort(compareEvents);modelEvents.forEach(function(event){var startAndEnd='start: '+parseInt(event.start)+', '+'end: '+parseInt(event.end)+'});';if(event instanceof tr.e.cc.InputLatencyAsyncSlice){modelLines.push('      audits.addInputEvent(model, INPUT_TYPE.'+
+typeNames[event.typeName]+',');}else if(event.title==='RenderFrameImpl::didCommitProvisionalLoad'){modelLines.push('      audits.addCommitLoadEvent(model,');}else if(event.title==='InputHandlerProxy::HandleGestureFling::started'){modelLines.push('      audits.addFlingAnimationEvent(model,');}else if(event.title===tr.e.audits.IMPL_RENDERING_STATS){modelLines.push('      audits.addFrameEvent(model,');}else if(event.title===CSS_ANIMATION_TITLE){modelLines.push('      audits.addEvent(model.rendererMain, {');modelLines.push('        title: \'Animation\', '+startAndEnd);return;}else{throw('You must extend createCustomizeModelLinesFromModel()'+'to support this event:\n'+event.title+'\n');}
+modelLines.push('          {'+startAndEnd);});modelLines.push('      audits.addEvent(model.browserMain,');modelLines.push('          {'+'title: \'model end\', '+'start: '+(parseInt(model.bounds.max)-1)+', '+'end: '+parseInt(model.bounds.max)+'});');return modelLines;}
+function createExpectedIRLinesFromModel(model){var expectedLines=[];var irCount=model.interactionRecords.length;model.interactionRecords.forEach(function(ir,index){var irString='      {';irString+='title: \''+ir.title+'\', ';irString+='start: '+parseInt(ir.start)+', ';irString+='end: '+parseInt(ir.end)+', ';irString+='eventCount: '+ir.sourceEvents.length;irString+='}';if(index<(irCount-1))
+irString+=',';expectedLines.push(irString);});return expectedLines;}
+function createIRFinderTestCaseStringFromModel(model){var filename=window.location.hash.substr(1);var testName=filename.substr(filename.lastIndexOf('/')+1);testName=testName.substr(0,testName.indexOf('.'));try{var testLines=[];testLines.push('  /*');testLines.push('    This test was generated from');testLines.push('    '+filename+'');testLines.push('   */');testLines.push('  test(\''+testName+'\', function() {');testLines.push('    var verifier = new IRVerifier();');testLines.push('    verifier.customizeModelCallback = function(model) {');testLines.push.apply(testLines,createCustomizeModelLinesFromModel(model));testLines.push('    };');testLines.push('    verifier.expectedIRs = [');testLines.push.apply(testLines,createExpectedIRLinesFromModel(model));testLines.push('    ];');testLines.push('    verifier.verify();');testLines.push('  });');return testLines.join('\n');}catch(error){return error;}}
+return{RAILIRFinder:RAILIRFinder,createIRFinderTestCaseStringFromModel:createIRFinderTestCaseStringFromModel};});'use strict';tr.exportTo('tr.e.audits',function(){var Auditor=tr.c.Auditor;function ChromeAuditor(model){Auditor.call(this,model);if(tr.e.audits.ChromeModelHelper.supportsModel(this.model)){var modelHelper=new tr.e.audits.ChromeModelHelper(this.model);if(modelHelper.browserHelper===undefined)
+this.modelHelper=undefined;else
+this.modelHelper=modelHelper;}else{this.modelHelper=undefined;}};ChromeAuditor.prototype={__proto__:Auditor.prototype,runAnnotate:function(){if(!this.modelHelper)
+return;this.model.getAllProcesses().forEach(function(process){if(process.labels!==undefined&&process.labels.length==1&&process.labels[0]=='chrome://tracing')
+process.important=false;});},runAudit:function(){if(!this.modelHelper)
+return;if(!tr.e.rail.RAILIRFinder.supportsModelHelper(this.modelHelper))
+return;var rirf=new tr.e.rail.RAILIRFinder(this.model,this.modelHelper);var rirs=undefined;try{rirs=rirf.findAllInteractionRecords();}catch(error){this.model.importWarning({type:'RAILIRFinder',message:error,showToUser:true});return;}
+rirs.forEach(function(ir){this.model.addInteractionRecord(ir);},this);}};Auditor.register(ChromeAuditor);return{ChromeAuditor:ChromeAuditor};});'use strict';tr.exportTo('tr.b',function(){function Settings(){return Settings;};if(tr.b.unittest&&tr.b.unittest.TestRunner){tr.b.unittest.TestRunner.addEventListener('tr-unittest-will-run',function(){if(tr.isHeadless)
+Settings.setAlternativeStorageInstance(new HeadlessStorage());else
+Settings.setAlternativeStorageInstance(global.sessionStorage);});}
+function SessionSettings(){return SessionSettings;}
+function AddStaticStorageFunctionsToClass_(input_class,storage){input_class.storage_=storage;input_class.get=function(key,opt_default,opt_namespace){key=input_class.namespace_(key,opt_namespace);var rawVal=input_class.storage_.getItem(key);if(rawVal===null||rawVal===undefined)
+return opt_default;try{return JSON.parse(rawVal).value;}catch(e){input_class.storage_.removeItem(key);return opt_default;}};input_class.set=function(key,value,opt_namespace){if(value===undefined)
+throw new Error('Settings.set: value must not be undefined');var v=JSON.stringify({value:value});input_class.storage_.setItem(input_class.namespace_(key,opt_namespace),v);};input_class.keys=function(opt_namespace){var result=[];opt_namespace=opt_namespace||'';for(var i=0;i<input_class.storage_.length;i++){var key=input_class.storage_.key(i);if(input_class.isnamespaced_(key,opt_namespace))
+result.push(input_class.unnamespace_(key,opt_namespace));}
+return result;};input_class.isnamespaced_=function(key,opt_namespace){return key.indexOf(input_class.normalize_(opt_namespace))==0;};input_class.namespace_=function(key,opt_namespace){return input_class.normalize_(opt_namespace)+key;};input_class.unnamespace_=function(key,opt_namespace){return key.replace(input_class.normalize_(opt_namespace),'');};input_class.normalize_=function(opt_namespace){return input_class.NAMESPACE+(opt_namespace?opt_namespace+'.':'');};input_class.setAlternativeStorageInstance=function(instance){input_class.storage_=instance;};input_class.getAlternativeStorageInstance=function(){if(!tr.isHeadless&&input_class.storage_===localStorage)
+return undefined;return input_class.storage_;};input_class.NAMESPACE='trace-viewer';};function HeadlessStorage(){this.length=0;this.hasItem_={};this.items_={};this.itemsAsArray_=undefined;}
+HeadlessStorage.prototype={key:function(index){return this.itemsAsArray[index];},get itemsAsArray(){if(this.itemsAsArray_!==undefined)
+return this.itemsAsArray_;var itemsAsArray=[];for(var k in this.items_)
+itemsAsArray.push(k);this.itemsAsArray_=itemsAsArray;return this.itemsAsArray_;},getItem:function(key){if(!this.hasItem_[key])
+return null;return this.items_[key];},removeItem:function(key){if(!this.hasItem_[key])
+return;var value=this.items_[key];delete this.hasItem_[key];delete this.items_[key];this.length--;this.itemsAsArray_=undefined;return value;},setItem:function(key,value){if(this.hasItem_[key]){this.items_[key]=value;return;}
+this.items_[key]=value;this.hasItem_[key]=true;this.length++;this.itemsAsArray_=undefined;return value;}};if(tr.isHeadless){AddStaticStorageFunctionsToClass_(Settings,new HeadlessStorage());AddStaticStorageFunctionsToClass_(SessionSettings,new HeadlessStorage());}else{AddStaticStorageFunctionsToClass_(Settings,localStorage);AddStaticStorageFunctionsToClass_(SessionSettings,sessionStorage);}
+return{Settings:Settings,SessionSettings:SessionSettings};});'use strict';tr.exportTo('tr.c',function(){function ScriptingObject(){}
+ScriptingObject.prototype={onModelChanged:function(model){}};return{ScriptingObject:ScriptingObject};});'use strict';tr.exportTo('tr.c',function(){function ScriptingController(brushingStateController){this.brushingStateController_=brushingStateController;this.scriptObjectNames_=[];this.scriptObjectValues_=[];this.brushingStateController.addEventListener('model-changed',this.onModelChanged_.bind(this));var typeInfos=ScriptingObjectRegistry.getAllRegisteredTypeInfos();typeInfos.forEach(function(typeInfo){this.addScriptObject(typeInfo.metadata.name,typeInfo.constructor);global[typeInfo.metadata.name]=typeInfo.constructor;},this);}
+function ScriptingObjectRegistry(){}
+var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(ScriptingObjectRegistry,options);ScriptingController.prototype={get brushingStateController(){return this.brushingStateController_;},onModelChanged_:function(){this.scriptObjectValues_.forEach(function(v){if(v.onModelChanged)
+v.onModelChanged(this.brushingStateController.model);},this);},addScriptObject:function(name,value){this.scriptObjectNames_.push(name);this.scriptObjectValues_.push(value);},executeCommand:function(command){var f=new Function(this.scriptObjectNames_,'return eval('+command+')');return f.apply(null,this.scriptObjectValues_);}};return{ScriptingController:ScriptingController,ScriptingObjectRegistry:ScriptingObjectRegistry};});'use strict';Polymer('tr-ui-a-tab-view',{ready:function(){this.$.tshh.style.display='none';this.tabs_=[];this.selectedTab_=undefined;for(var i=0;i<this.children.length;i++)
+this.processAddedChild_(this.children[i]);this.childrenObserver_=new MutationObserver(this.childrenUpdated_.bind(this));this.childrenObserver_.observe(this,{childList:'true'});},get tabStripHeadingText(){return this.$.tsh.textContent;},set tabStripHeadingText(tabStripHeadingText){this.$.tsh.textContent=tabStripHeadingText;if(!!tabStripHeadingText)
+this.$.tshh.style.display='';else
+this.$.tshh.style.display='none';},get selectedTab(){this.childrenUpdated_(this.childrenObserver_.takeRecords(),this.childrenObserver_);if(this.selectedTab_)
+return this.selectedTab_.content;return undefined;},set selectedTab(content){this.childrenUpdated_(this.childrenObserver_.takeRecords(),this.childrenObserver_);if(content===undefined||content===null){this.changeSelectedTabById_(undefined);return;}
+var contentTabId=undefined;for(var i=0;i<this.tabs_.length;i++)
+if(this.tabs_[i].content===content){contentTabId=this.tabs_[i].id;break;}
+if(contentTabId===undefined)
+return;this.changeSelectedTabById_(contentTabId);},get tabsHidden(){var ts=this.shadowRoot.querySelector('tab-strip');return ts.hasAttribute('tabs-hidden');},set tabsHidden(tabsHidden){tabsHidden=!!tabsHidden;var ts=this.shadowRoot.querySelector('tab-strip');if(tabsHidden)
+ts.setAttribute('tabs-hidden',true);else
+ts.removeAttribute('tabs-hidden');},get tabs(){return this.tabs_.map(function(tabObject){return tabObject.content;});},processAddedChild_:function(child){var observerAttributeSelected=new MutationObserver(this.childAttributesChanged_.bind(this));var observerAttributeTabLabel=new MutationObserver(this.childAttributesChanged_.bind(this));var tabObject={id:this.tabs_.length,content:child,label:child.getAttribute('tab-label'),observers:{forAttributeSelected:observerAttributeSelected,forAttributeTabLabel:observerAttributeTabLabel}};this.tabs_.push(tabObject);if(child.hasAttribute('selected')){if(this.selectedTab_)
+child.removeAttribute('selected');else
+this.setSelectedTabById_(tabObject.id);}
+var previousSelected=child.selected;var tabView=this;Object.defineProperty(child,'selected',{configurable:true,set:function(value){if(value){tabView.changeSelectedTabById_(tabObject.id);return;}
+var wasSelected=tabView.selectedTab_===tabObject;if(wasSelected)
+tabView.changeSelectedTabById_(undefined);},get:function(){return this.hasAttribute('selected');}});if(previousSelected)
+child.selected=previousSelected;observerAttributeSelected.observe(child,{attributeFilter:['selected']});observerAttributeTabLabel.observe(child,{attributeFilter:['tab-label']});},processRemovedChild_:function(child){for(var i=0;i<this.tabs_.length;i++){this.tabs_[i].id=i;if(this.tabs_[i].content===child){this.tabs_[i].observers.forAttributeSelected.disconnect();this.tabs_[i].observers.forAttributeTabLabel.disconnect();if(this.tabs_[i]===this.selectedTab_){this.clearSelectedTab_();this.fire('selected-tab-change');}
+child.removeAttribute('selected');delete child.selected;this.tabs_.splice(i,1);i--;}}},childAttributesChanged_:function(mutations,observer){var tabObject=undefined;for(var i=0;i<this.tabs_.length;i++){var observers=this.tabs_[i].observers;if(observers.forAttributeSelected===observer||observers.forAttributeTabLabel===observer){tabObject=this.tabs_[i];break;}}
+if(!tabObject)
+return;for(var i=0;i<mutations.length;i++){var node=tabObject.content;if(mutations[i].attributeName==='tab-label')
+tabObject.label=node.getAttribute('tab-label');if(mutations[i].attributeName==='selected'){var nodeIsSelected=node.hasAttribute('selected');if(nodeIsSelected)
+this.changeSelectedTabById_(tabObject.id);else
+this.changeSelectedTabById_(undefined);}}},childrenUpdated_:function(mutations,observer){mutations.forEach(function(mutation){for(var i=0;i<mutation.removedNodes.length;i++)
+this.processRemovedChild_(mutation.removedNodes[i]);for(var i=0;i<mutation.addedNodes.length;i++)
+this.processAddedChild_(mutation.addedNodes[i]);},this);},tabButtonSelectHandler_:function(event,detail,sender){this.changeSelectedTabById_(sender.getAttribute('button-id'));},changeSelectedTabById_:function(id){var newTab=id!==undefined?this.tabs_[id]:undefined;var changed=this.selectedTab_!==newTab;this.saveCurrentTabScrollPosition_();this.clearSelectedTab_();if(id!==undefined){this.setSelectedTabById_(id);this.restoreCurrentTabScrollPosition_();}
+if(changed)
+this.fire('selected-tab-change');},setSelectedTabById_:function(id){this.selectedTab_=this.tabs_[id];this.selectedTab_.observers.forAttributeSelected.disconnect();this.selectedTab_.content.setAttribute('selected','selected');this.selectedTab_.observers.forAttributeSelected.observe(this.selectedTab_.content,{attributeFilter:['selected']});},saveTabStates:function(){this.saveCurrentTabScrollPosition_();},saveCurrentTabScrollPosition_:function(){if(this.selectedTab_){this.selectedTab_.content._savedScrollTop=this.$['content-container'].scrollTop;this.selectedTab_.content._savedScrollLeft=this.$['content-container'].scrollLeft;}},restoreCurrentTabScrollPosition_:function(){if(this.selectedTab_){this.$['content-container'].scrollTop=this.selectedTab_.content._savedScrollTop||0;this.$['content-container'].scrollLeft=this.selectedTab_.content._savedScrollLeft||0;}},clearSelectedTab_:function(){if(this.selectedTab_){this.selectedTab_.observers.forAttributeSelected.disconnect();this.selectedTab_.content.removeAttribute('selected');this.selectedTab_.observers.forAttributeSelected.observe(this.selectedTab_.content,{attributeFilter:['selected']});this.selectedTab_=undefined;}}});'use strict';Polymer('tr-ui-a-sub-view',{set tabLabel(label){return this.setAttribute('tab-label',label);},get tabLabel(){return this.getAttribute('tab-label');},get requiresTallView(){return false;},get relatedEventsToHighlight(){return undefined;},set selection(selection){throw new Error('Not implemented!');},get selection(){throw new Error('Not implemented!');}});'use strict';tr.exportTo('tr.ui.b',function(){var EventSet=tr.model.EventSet;var SelectionState=tr.model.SelectionState;function BrushingState(){this.guid_=tr.b.GUID.allocate();this.selection_=new EventSet();this.findMatches_=new EventSet();this.analysisViewRelatedEvents_=new EventSet();this.analysisLinkHoveredEvents_=new EventSet();this.appliedToModel_=undefined;this.viewSpecificBrushingStates_={};}
+BrushingState.prototype={get guid(){return this.guid_;},clone:function(){var that=new BrushingState();that.selection_=this.selection_;that.findMatches_=this.findMatches_;that.analysisViewRelatedEvents_=this.analysisViewRelatedEvents_;that.analysisLinkHoveredEvents_=this.analysisLinkHoveredEvents_;that.viewSpecificBrushingStates_=this.viewSpecificBrushingStates_;return that;},equals:function(that){if(!this.selection_.equals(that.selection_))
+return false;if(!this.findMatches_.equals(that.findMatches_))
+return false;if(!this.analysisViewRelatedEvents_.equals(that.analysisViewRelatedEvents_)){return false;}
+if(!this.analysisLinkHoveredEvents_.equals(that.analysisLinkHoveredEvents_)){return false;}
+return true;},get selectionOfInterest(){if(this.selection_.length)
+return this.selection_;if(this.highlight_.length)
+return this.highlight_;if(this.analysisViewRelatedEvents_.length)
+return this.analysisViewRelatedEvents_;if(this.analysisLinkHoveredEvents_.length)
+return this.analysisLinkHoveredEvents_;return this.selection_;},get selection(){return this.selection_;},set selection(selection){if(this.appliedToModel_)
+throw new Error('Cannot mutate this state right now');if(selection===undefined)
+selection=new EventSet();this.selection_=selection;},get findMatches(){return this.findMatches_;},set findMatches(findMatches){if(this.appliedToModel_)
+throw new Error('Cannot mutate this state right now');if(findMatches===undefined)
+findMatches=new EventSet();this.findMatches_=findMatches;},get analysisViewRelatedEvents(){return this.analysisViewRelatedEvents_;},set analysisViewRelatedEvents(analysisViewRelatedEvents){if(this.appliedToModel_)
+throw new Error('Cannot mutate this state right now');if(analysisViewRelatedEvents===undefined)
+analysisViewRelatedEvents=new EventSet();this.analysisViewRelatedEvents_=analysisViewRelatedEvents;},get analysisLinkHoveredEvents(){return this.analysisLinkHoveredEvents_;},set analysisLinkHoveredEvents(analysisLinkHoveredEvents){if(this.appliedToModel_)
+throw new Error('Cannot mutate this state right now');if(analysisLinkHoveredEvents===undefined)
+analysisLinkHoveredEvents=new EventSet();this.analysisLinkHoveredEvents_=analysisLinkHoveredEvents;},get isAppliedToModel(){return this.appliedToModel_!==undefined;},get viewSpecificBrushingStates(){return this.viewSpecificBrushingStates_;},set viewSpecificBrushingStates(viewSpecificBrushingStates){this.viewSpecificBrushingStates_=viewSpecificBrushingStates;},get causesDimming_(){return this.findMatches_.length>0||this.analysisViewRelatedEvents_.length>0;},get brightenedEvents_(){var brightenedEvents=new EventSet();brightenedEvents.addEventSet(this.selection_);brightenedEvents.addEventSet(this.analysisLinkHoveredEvents_);return brightenedEvents;},applyToModelSelectionState:function(model){this.appliedToModel_=model;if(!this.causesDimming_){this.brightenedEvents_.forEach(function(e){var score;score=0;if(this.selection_.contains(e))
+score++;if(this.analysisLinkHoveredEvents_.contains(e))
+score++;e.selectionState=SelectionState.getFromBrighteningLevel(score);},this);return;}
+var brightenedEvents=this.brightenedEvents_;model.iterateAllEvents(function(e){var score;if(brightenedEvents.contains(e)){score=0;if(this.selection_.contains(e))
+score++;if(this.analysisLinkHoveredEvents_.contains(e))
+score++;e.selectionState=SelectionState.getFromBrighteningLevel(score);}else{score=0;if(this.findMatches_.contains(e))
+score++;if(this.analysisViewRelatedEvents_.contains(e))
+score++;e.selectionState=SelectionState.getFromDimmingLevel(score);}}.bind(this));},transferModelOwnershipToClone:function(that){if(!this.appliedToModel_)
+throw new Error('Not applied');that.appliedToModel_=this.appliedToModel_;this.appliedToModel_=undefined;},unapplyFromModelSelectionState:function(){if(!this.appliedToModel_)
+throw new Error('Not applied');var model=this.appliedToModel_;this.appliedToModel_=undefined;if(!this.causesDimming_){this.brightenedEvents_.forEach(function(e){e.selectionState=SelectionState.NONE;});return;}
+model.iterateAllEvents(function(e){e.selectionState=SelectionState.NONE;});}};return{BrushingState:BrushingState};});'use strict';tr.exportTo('tr.ui.b',function(){function Animation(){}
+Animation.prototype={canTakeOverFor:function(existingAnimation){throw new Error('Not implemented');},takeOverFor:function(existingAnimation,newStartTimestamp,target){throw new Error('Not implemented');},start:function(timestamp,target){throw new Error('Not implemented');},didStopEarly:function(timestamp,target,willBeTakenOverByAnotherAnimation){},tick:function(timestamp,target){throw new Error('Not implemented');}};return{Animation:Animation};});'use strict';tr.exportTo('tr.ui.b',function(){function AnimationController(){tr.b.EventTarget.call(this);this.target_=undefined;this.activeAnimation_=undefined;this.tickScheduled_=false;}
+AnimationController.prototype={__proto__:tr.b.EventTarget.prototype,get target(){return this.target_;},set target(target){if(this.activeAnimation_)
+throw new Error('Cannot change target while animation is running.');if(target.cloneAnimationState===undefined||typeof target.cloneAnimationState!=='function')
+throw new Error('target must have a cloneAnimationState function');this.target_=target;},get activeAnimation(){return this.activeAnimation_;},get hasActiveAnimation(){return!!this.activeAnimation_;},queueAnimation:function(animation,opt_now){if(this.target_===undefined)
+throw new Error('Cannot queue animations without a target');var now;if(opt_now!==undefined)
+now=opt_now;else
+now=window.performance.now();if(this.activeAnimation_){var done=this.activeAnimation_.tick(now,this.target_);if(done)
+this.activeAnimation_=undefined;}
+if(this.activeAnimation_){if(animation.canTakeOverFor(this.activeAnimation_)){this.activeAnimation_.didStopEarly(now,this.target_,true);animation.takeOverFor(this.activeAnimation_,now,this.target_);}else{this.activeAnimation_.didStopEarly(now,this.target_,false);}}
+this.activeAnimation_=animation;this.activeAnimation_.start(now,this.target_);if(this.tickScheduled_)
+return;this.tickScheduled_=true;tr.b.requestAnimationFrame(this.tickActiveAnimation_,this);},cancelActiveAnimation:function(opt_now){if(!this.activeAnimation_)
+return;var now;if(opt_now!==undefined)
+now=opt_now;else
+now=window.performance.now();this.activeAnimation_.didStopEarly(now,this.target_,false);this.activeAnimation_=undefined;},tickActiveAnimation_:function(frameBeginTime){this.tickScheduled_=false;if(!this.activeAnimation_)
+return;if(this.target_===undefined){this.activeAnimation_.didStopEarly(frameBeginTime,this.target_,false);return;}
+var oldTargetState=this.target_.cloneAnimationState();var done=this.activeAnimation_.tick(frameBeginTime,this.target_);if(done)
+this.activeAnimation_=undefined;if(this.activeAnimation_){this.tickScheduled_=true;tr.b.requestAnimationFrame(this.tickActiveAnimation_,this);}
+if(oldTargetState){var e=new tr.b.Event('didtick');e.oldTargetState=oldTargetState;this.dispatchEvent(e,false,false);}}};return{AnimationController:AnimationController};});'use strict';tr.exportTo('tr.ui.b',function(){function createSpan(opt_dictionary){var ownerDocument=document;if(opt_dictionary&&opt_dictionary.ownerDocument)
+ownerDocument=opt_dictionary.ownerDocument;var spanEl=ownerDocument.createElement('span');if(opt_dictionary){if(opt_dictionary.className)
+spanEl.className=opt_dictionary.className;if(opt_dictionary.textContent)
+spanEl.textContent=opt_dictionary.textContent;if(opt_dictionary.tooltip)
+spanEl.title=opt_dictionary.tooltip;if(opt_dictionary.parent)
+opt_dictionary.parent.appendChild(spanEl);if(opt_dictionary.bold)
+spanEl.style.fontWeight='bold';if(opt_dictionary.italic)
+spanEl.style.fontStyle='italic';if(opt_dictionary.marginLeft)
+spanEl.style.marginLeft=opt_dictionary.marginLeft;if(opt_dictionary.marginRight)
+spanEl.style.marginRight=opt_dictionary.marginRight;if(opt_dictionary.backgroundColor)
+spanEl.style.backgroundColor=opt_dictionary.backgroundColor;if(opt_dictionary.color)
+spanEl.style.color=opt_dictionary.color;}
+return spanEl;};function createDiv(opt_dictionary){var divEl=document.createElement('div');if(opt_dictionary){if(opt_dictionary.className)
+divEl.className=opt_dictionary.className;if(opt_dictionary.parent)
+opt_dictionary.parent.appendChild(divEl);if(opt_dictionary.textContent)
+divEl.textContent=opt_dictionary.textContent;if(opt_dictionary.maxWidth)
+divEl.style.maxWidth=opt_dictionary.maxWidth;}
+return divEl;};function createScopedStyle(styleContent){var styleEl=document.createElement('style');styleEl.scoped=true;styleEl.innerHTML=styleContent;return styleEl;}
+function valuesEqual(a,b){if(a instanceof Array&&b instanceof Array)
+return a.length===b.length&&JSON.stringify(a)===JSON.stringify(b);return a===b;}
+function createSelector(targetEl,targetElProperty,settingsKey,defaultValue,items,opt_namespace){var defaultValueIndex;for(var i=0;i<items.length;i++){var item=items[i];if(valuesEqual(item.value,defaultValue)){defaultValueIndex=i;break;}}
+if(defaultValueIndex===undefined)
+throw new Error('defaultValue must be in the items list');var selectorEl=document.createElement('select');selectorEl.addEventListener('change',onChange);for(var i=0;i<items.length;i++){var item=items[i];var optionEl=document.createElement('option');optionEl.textContent=item.label;optionEl.targetPropertyValue=item.value;optionEl.item=item;selectorEl.appendChild(optionEl);}
+function onChange(e){var value=selectorEl.selectedOptions[0].targetPropertyValue;tr.b.Settings.set(settingsKey,value,opt_namespace);targetEl[targetElProperty]=value;}
+var oldSetter=targetEl.__lookupSetter__('selectedIndex');selectorEl.__defineGetter__('selectedValue',function(v){return selectorEl.children[selectorEl.selectedIndex].targetPropertyValue;});selectorEl.__defineGetter__('selectedItem',function(v){return selectorEl.children[selectorEl.selectedIndex].item;});selectorEl.__defineSetter__('selectedValue',function(v){for(var i=0;i<selectorEl.children.length;i++){var value=selectorEl.children[i].targetPropertyValue;if(valuesEqual(value,v)){var changed=selectorEl.selectedIndex!=i;if(changed){selectorEl.selectedIndex=i;onChange();}
+return;}}
+throw new Error('Not a valid value');});var initialValue=tr.b.Settings.get(settingsKey,defaultValue,opt_namespace);var didSet=false;for(var i=0;i<selectorEl.children.length;i++){if(valuesEqual(selectorEl.children[i].targetPropertyValue,initialValue)){didSet=true;targetEl[targetElProperty]=initialValue;selectorEl.selectedIndex=i;break;}}
+if(!didSet){selectorEl.selectedIndex=defaultValueIndex;targetEl[targetElProperty]=defaultValue;}
+return selectorEl;}
+function createEditCategorySpan(optionGroupEl,targetEl){var spanEl=createSpan({className:'edit-categories'});spanEl.textContent='Edit categories';spanEl.classList.add('labeled-option');spanEl.addEventListener('click',function(){targetEl.onClickEditCategories();});return spanEl;}
+function createOptionGroup(targetEl,targetElProperty,settingsKey,defaultValue,items){function onChange(){var value=[];if(this.value.length)
+value=this.value.split(',');tr.b.Settings.set(settingsKey,value);targetEl[targetElProperty]=value;}
+var optionGroupEl=createSpan({className:'labeled-option-group'});var initialValue=tr.b.Settings.get(settingsKey,defaultValue);for(var i=0;i<items.length;++i){var item=items[i];var id='category-preset-'+item.label.replace(/ /g,'-');var radioEl=document.createElement('input');radioEl.type='radio';radioEl.setAttribute('id',id);radioEl.setAttribute('name','category-presets-group');radioEl.setAttribute('value',item.value);radioEl.addEventListener('change',onChange.bind(radioEl,targetEl,targetElProperty,settingsKey));if(valuesEqual(initialValue,item.value))
+radioEl.checked=true;var labelEl=document.createElement('label');labelEl.textContent=item.label;labelEl.setAttribute('for',id);var spanEl=createSpan({className:'labeled-option'});spanEl.appendChild(radioEl);spanEl.appendChild(labelEl);spanEl.__defineSetter__('checked',function(opt_bool){var changed=radioEl.checked!==(!!opt_bool);if(!changed)
+return;radioEl.checked=!!opt_bool;onChange();});spanEl.__defineGetter__('checked',function(){return radioEl.checked;});optionGroupEl.appendChild(spanEl);}
+optionGroupEl.appendChild(createEditCategorySpan(optionGroupEl,targetEl));if(!initialValue.length)
+optionGroupEl.classList.add('categories-expanded');targetEl[targetElProperty]=initialValue;return optionGroupEl;}
+var nextCheckboxId=1;function createCheckBox(targetEl,targetElProperty,settingsKey,defaultValue,label,opt_changeCb){var buttonEl=document.createElement('input');buttonEl.type='checkbox';var initialValue=tr.b.Settings.get(settingsKey,defaultValue);buttonEl.checked=!!initialValue;if(targetEl)
+targetEl[targetElProperty]=initialValue;function onChange(){tr.b.Settings.set(settingsKey,buttonEl.checked);if(targetEl)
+targetEl[targetElProperty]=buttonEl.checked;if(opt_changeCb)
+opt_changeCb.call();}
+buttonEl.addEventListener('change',onChange);var id='#checkbox-'+nextCheckboxId++;var spanEl=createSpan({className:'labeled-checkbox'});buttonEl.setAttribute('id',id);var labelEl=document.createElement('label');labelEl.textContent=label;labelEl.setAttribute('for',id);spanEl.appendChild(buttonEl);spanEl.appendChild(labelEl);spanEl.__defineSetter__('checked',function(opt_bool){var changed=buttonEl.checked!==(!!opt_bool);if(!changed)
+return;buttonEl.checked=!!opt_bool;onChange();});spanEl.__defineGetter__('checked',function(){return buttonEl.checked;});return spanEl;}
+function isElementAttachedToDocument(el){var cur=el;while(cur.parentNode)
+cur=cur.parentNode;return(cur===el.ownerDocument||cur.nodeName==='#document-fragment');}
+function asHTMLOrTextNode(value,opt_ownerDocument){if(value instanceof Node)
+return value;var ownerDocument=opt_ownerDocument||document;return ownerDocument.createTextNode(value);}
+return{createSpan:createSpan,createDiv:createDiv,createScopedStyle:createScopedStyle,createSelector:createSelector,createOptionGroup:createOptionGroup,createCheckBox:createCheckBox,isElementAttachedToDocument:isElementAttachedToDocument,asHTMLOrTextNode:asHTMLOrTextNode};});'use strict';tr.exportTo('tr.ui.b',function(){var ColorScheme=tr.b.ColorScheme;var colors=ColorScheme.colors;var colorsAsStrings=ColorScheme.colorsAsStrings;var numColorsPerVariant=ColorScheme.properties.numColorsPerVariant;var SelectionState=tr.model.SelectionState;var EventPresenter={getSelectableItemColorAsString:function(item){var colorId=item.colorId+this.getColorIdOffset_(item);return colorsAsStrings[colorId];},getColorIdOffset_:function(event){return event.selectionState;},getTextColor:function(event){if(event.selectionState===SelectionState.DIMMED)
+return'rgb(60,60,60)';return'rgb(0,0,0)';},getSliceColorId:function(slice){return slice.colorId+this.getColorIdOffset_(slice);},getSliceAlpha:function(slice,async){var alpha=1;if(async)
+alpha*=0.3;return alpha;},getInstantSliceColor:function(instant){var colorId=instant.colorId+this.getColorIdOffset_(instant);return colors[colorId].toStringWithAlphaOverride(1.0);},getObjectInstanceColor:function(instance){var colorId=instance.colorId+this.getColorIdOffset_(instance);return colors[colorId].toStringWithAlphaOverride(0.25);},getObjectSnapshotColor:function(snapshot){var colorId=snapshot.objectInstance.colorId+this.getColorIdOffset_(snapshot);return colors[colorId];},getCounterSeriesColor:function(colorId,selectionState,opt_alphaMultiplier){var event={selectionState:selectionState};var c=colors[colorId+this.getColorIdOffset_(event)];return c.toStringWithAlphaOverride(opt_alphaMultiplier!==undefined?opt_alphaMultiplier:1.0);},getBarSnapshotColor:function(snapshot,offset){var colorId=(snapshot.objectInstance.colorId+offset)%numColorsPerVariant;colorId+=this.getColorIdOffset_(snapshot);return colors[colorId].toStringWithAlphaOverride(1.0);}};return{EventPresenter:EventPresenter};});'use strict';tr.exportTo('tr.ui.b',function(){var elidedTitleCacheDict={};var elidedTitleCache=new ElidedTitleCache();function ElidedTitleCache(){this.textWidthMap={};}
+ElidedTitleCache.prototype={get:function(ctx,pixWidth,title,width,sliceDuration){var elidedDict=elidedTitleCacheDict[title];if(!elidedDict){elidedDict={};elidedTitleCacheDict[title]=elidedDict;}
+var elidedDictForPixWidth=elidedDict[pixWidth];if(!elidedDictForPixWidth){elidedDict[pixWidth]={};elidedDictForPixWidth=elidedDict[pixWidth];}
+var stringWidthPair=elidedDictForPixWidth[sliceDuration];if(stringWidthPair===undefined){var newtitle=title;var elided=false;while(this.labelWidthWorld(ctx,newtitle,pixWidth)>sliceDuration){if(newtitle.length*0.75<1)
+break;newtitle=newtitle.substring(0,newtitle.length*0.75);elided=true;}
+if(elided&&newtitle.length>3)
+newtitle=newtitle.substring(0,newtitle.length-3)+'...';stringWidthPair=new ElidedStringWidthPair(newtitle,this.labelWidth(ctx,newtitle));elidedDictForPixWidth[sliceDuration]=stringWidthPair;}
+return stringWidthPair;},quickMeasureText_:function(ctx,text){var w=this.textWidthMap[text];if(!w){w=ctx.measureText(text).width;this.textWidthMap[text]=w;}
+return w;},labelWidth:function(ctx,title){return this.quickMeasureText_(ctx,title)+2;},labelWidthWorld:function(ctx,title,pixWidth){return this.labelWidth(ctx,title)*pixWidth;}};function ElidedStringWidthPair(string,width){this.string=string;this.width=width;}
+return{ElidedTitleCache:ElidedTitleCache};});'use strict';tr.exportTo('tr.ui.b',function(){var elidedTitleCache=new tr.ui.b.ElidedTitleCache();var ColorScheme=tr.b.ColorScheme;var colorsAsStrings=ColorScheme.colorsAsStrings;var EventPresenter=tr.ui.b.EventPresenter;var blackColorId=ColorScheme.getColorIdForReservedName('black');var THIN_SLICE_HEIGHT=4;var SLICE_WAITING_WIDTH_DRAW_THRESHOLD=3;var SLICE_ACTIVE_WIDTH_DRAW_THRESHOLD=1;var SHOULD_ELIDE_TEXT=true;function drawLine(ctx,x1,y1,x2,y2){ctx.moveTo(x1,y1);ctx.lineTo(x2,y2);}
+function drawTriangle(ctx,x1,y1,x2,y2,x3,y3){ctx.beginPath();ctx.moveTo(x1,y1);ctx.lineTo(x2,y2);ctx.lineTo(x3,y3);ctx.closePath();}
+function drawArrow(ctx,x1,y1,x2,y2,arrowLength,arrowWidth){var dx=x2-x1;var dy=y2-y1;var len=Math.sqrt(dx*dx+dy*dy);var perc=(len-arrowLength)/len;var bx=x1+perc*dx;var by=y1+perc*dy;var ux=dx/len;var uy=dy/len;var ax=uy*arrowWidth;var ay=-ux*arrowWidth;ctx.beginPath();drawLine(ctx,x1,y1,x2,y2);ctx.stroke();drawTriangle(ctx,bx+ax,by+ay,x2,y2,bx-ax,by-ay);ctx.fill();}
+function drawSlices(ctx,dt,viewLWorld,viewRWorld,viewHeight,slices,async){var pixelRatio=window.devicePixelRatio||1;var pixWidth=dt.xViewVectorToWorld(1);var height=viewHeight*pixelRatio;var darkRectHeight=THIN_SLICE_HEIGHT*pixelRatio;if(height<darkRectHeight)
+darkRectHeight=0;var lightRectHeight=height-darkRectHeight;ctx.save();dt.applyTransformToCanvas(ctx);var rect=new tr.ui.b.FastRectRenderer(ctx,2*pixWidth,2*pixWidth,colorsAsStrings);rect.setYandH(0,height);var lowSlice=tr.b.findLowIndexInSortedArray(slices,function(slice){return slice.start+slice.duration;},viewLWorld);var hadTopLevel=false;for(var i=lowSlice;i<slices.length;++i){var slice=slices[i];var x=slice.start;if(x>viewRWorld)
+break;var w=pixWidth;if(slice.duration>0){w=Math.max(slice.duration,0.000001);if(w<pixWidth)
+w=pixWidth;}
+var colorId=EventPresenter.getSliceColorId(slice);var alpha=EventPresenter.getSliceAlpha(slice,async);var lightAlpha=alpha*0.70;if(async&&slice.isTopLevel){rect.setYandH(3,height-3);hadTopLevel=true;}else{rect.setYandH(0,height);}
+if(!slice.cpuDuration){rect.fillRect(x,w,colorId,alpha);continue;}
+var activeWidth=w*(slice.cpuDuration/slice.duration);var waitingWidth=w-activeWidth;if(activeWidth<SLICE_ACTIVE_WIDTH_DRAW_THRESHOLD*pixWidth){activeWidth=0;waitingWidth=w;}
+if(waitingWidth<SLICE_WAITING_WIDTH_DRAW_THRESHOLD*pixWidth){activeWidth=w;waitingWidth=0;}
+if(activeWidth>0){rect.fillRect(x,activeWidth,colorId,alpha);}
+if(waitingWidth>0){rect.setYandH(0,lightRectHeight);rect.fillRect(x+activeWidth-pixWidth,waitingWidth+pixWidth,colorId,lightAlpha);rect.setYandH(lightRectHeight,darkRectHeight);rect.fillRect(x+activeWidth-pixWidth,waitingWidth+pixWidth,colorId,alpha);rect.setYandH(0,height);}}
+rect.flush();if(async&&hadTopLevel){rect.setYandH(2,1);for(var i=lowSlice;i<slices.length;++i){var slice=slices[i];var x=slice.start;if(x>viewRWorld)
+break;if(!slice.isTopLevel)
+continue;var w=pixWidth;if(slice.duration>0){w=Math.max(slice.duration,0.000001);if(w<pixWidth)
+w=pixWidth;}
+rect.fillRect(x,w,blackColorId,0.7);}
+rect.flush();}
+ctx.restore();}
+function drawInstantSlicesAsLines(ctx,dt,viewLWorld,viewRWorld,viewHeight,slices,lineWidthInPixels){var pixelRatio=window.devicePixelRatio||1;var height=viewHeight*pixelRatio;var pixWidth=dt.xViewVectorToWorld(1);ctx.save();ctx.lineWidth=pixWidth*lineWidthInPixels*pixelRatio;dt.applyTransformToCanvas(ctx);ctx.beginPath();var lowSlice=tr.b.findLowIndexInSortedArray(slices,function(slice){return slice.start;},viewLWorld);for(var i=lowSlice;i<slices.length;++i){var slice=slices[i];var x=slice.start;if(x>viewRWorld)
+break;ctx.strokeStyle=EventPresenter.getInstantSliceColor(slice);ctx.beginPath();ctx.moveTo(x,0);ctx.lineTo(x,height);ctx.stroke();}
+ctx.restore();}
+function drawLabels(ctx,dt,viewLWorld,viewRWorld,slices,async,fontSize,yOffset){var pixelRatio=window.devicePixelRatio||1;var pixWidth=dt.xViewVectorToWorld(1);ctx.save();ctx.textAlign='center';ctx.textBaseline='top';ctx.font=(fontSize*pixelRatio)+'px sans-serif';if(async)
+ctx.font='italic '+ctx.font;var cY=yOffset*pixelRatio;var lowSlice=tr.b.findLowIndexInSortedArray(slices,function(slice){return slice.start+slice.duration;},viewLWorld);var quickDiscardThresshold=pixWidth*20;for(var i=lowSlice;i<slices.length;++i){var slice=slices[i];if(slice.start>viewRWorld)
+break;if(slice.duration<=quickDiscardThresshold)
+continue;var title=slice.title+
+(slice.didNotFinish?' (Did Not Finish)':'');var drawnTitle=title;var drawnWidth=elidedTitleCache.labelWidth(ctx,drawnTitle);var fullLabelWidth=elidedTitleCache.labelWidthWorld(ctx,drawnTitle,pixWidth);if(SHOULD_ELIDE_TEXT&&fullLabelWidth>slice.duration){var elidedValues=elidedTitleCache.get(ctx,pixWidth,drawnTitle,drawnWidth,slice.duration);drawnTitle=elidedValues.string;drawnWidth=elidedValues.width;}
+if(drawnWidth*pixWidth<slice.duration){ctx.fillStyle=EventPresenter.getTextColor(slice);var cX=dt.xWorldToView(slice.start+0.5*slice.duration);ctx.fillText(drawnTitle,cX,cY,drawnWidth);}}
+ctx.restore();}
+return{drawSlices:drawSlices,drawInstantSlicesAsLines:drawInstantSlicesAsLines,drawLabels:drawLabels,drawLine:drawLine,drawTriangle:drawTriangle,drawArrow:drawArrow,elidedTitleCache_:elidedTitleCache,THIN_SLICE_HEIGHT:THIN_SLICE_HEIGHT};});'use strict';tr.exportTo('tr.ui',function(){function SnapIndicator(y,height){this.y=y;this.height=height;}
+function TimelineInterestRange(vp){this.viewport_=vp;this.range_=new tr.b.Range();this.leftSelected_=false;this.rightSelected_=false;this.leftSnapIndicator_=undefined;this.rightSnapIndicator_=undefined;}
+TimelineInterestRange.prototype={get isEmpty(){return this.range_.isEmpty;},reset:function(){this.range_.reset();this.leftSelected_=false;this.rightSelected_=false;this.leftSnapIndicator_=undefined;this.rightSnapIndicator_=undefined;this.viewport_.dispatchChangeEvent();},get min(){return this.range_.min;},set min(min){this.range_.min=min;this.viewport_.dispatchChangeEvent();},get max(){return this.range_.max;},set max(max){this.range_.max=max;this.viewport_.dispatchChangeEvent();},set:function(range){this.range_.reset();this.range_.addRange(range);this.viewport_.dispatchChangeEvent();},setMinAndMax:function(min,max){this.range_.min=min;this.range_.max=max;this.viewport_.dispatchChangeEvent();},get range(){return this.range_.range;},asRangeObject:function(){var range=new tr.b.Range();range.addRange(this.range_);return range;},get leftSelected(){return this.leftSelected_;},set leftSelected(leftSelected){if(this.leftSelected_==leftSelected)
+return;this.leftSelected_=leftSelected;this.viewport_.dispatchChangeEvent();},get rightSelected(){return this.rightSelected_;},set rightSelected(rightSelected){if(this.rightSelected_==rightSelected)
+return;this.rightSelected_=rightSelected;this.viewport_.dispatchChangeEvent();},get leftSnapIndicator(){return this.leftSnapIndicator_;},set leftSnapIndicator(leftSnapIndicator){this.leftSnapIndicator_=leftSnapIndicator;this.viewport_.dispatchChangeEvent();},get rightSnapIndicator(){return this.rightSnapIndicator_;},set rightSnapIndicator(rightSnapIndicator){this.rightSnapIndicator_=rightSnapIndicator;this.viewport_.dispatchChangeEvent();},draw:function(ctx,viewLWorld,viewRWorld){if(this.range_.isEmpty)
+return;var dt=this.viewport_.currentDisplayTransform;var markerLWorld=this.min;var markerRWorld=this.max;var markerLView=Math.round(dt.xWorldToView(markerLWorld));var markerRView=Math.round(dt.xWorldToView(markerRWorld));ctx.fillStyle='rgba(0, 0, 0, 0.2)';if(markerLWorld>viewLWorld){ctx.fillRect(dt.xWorldToView(viewLWorld),0,markerLView,ctx.canvas.height);}
+if(markerRWorld<viewRWorld){ctx.fillRect(markerRView,0,dt.xWorldToView(viewRWorld),ctx.canvas.height);}
+var pixelRatio=window.devicePixelRatio||1;ctx.lineWidth=Math.round(pixelRatio);if(this.range_.range>0){this.drawLine_(ctx,viewLWorld,viewRWorld,ctx.canvas.height,this.min,this.leftSelected_);this.drawLine_(ctx,viewLWorld,viewRWorld,ctx.canvas.height,this.max,this.rightSelected_);}else{this.drawLine_(ctx,viewLWorld,viewRWorld,ctx.canvas.height,this.min,this.leftSelected_||this.rightSelected_);}
+ctx.lineWidth=1;},drawLine_:function(ctx,viewLWorld,viewRWorld,height,ts,selected){if(ts<viewLWorld||ts>=viewRWorld)
+return;var dt=this.viewport_.currentDisplayTransform;var viewX=Math.round(dt.xWorldToView(ts));ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);ctx.beginPath();tr.ui.b.drawLine(ctx,viewX,0,viewX,height);if(selected)
+ctx.strokeStyle='rgb(255, 0, 0)';else
+ctx.strokeStyle='rgb(0, 0, 0)';ctx.stroke();ctx.restore();},drawIndicators:function(ctx,viewLWorld,viewRWorld){if(this.leftSnapIndicator_){this.drawIndicator_(ctx,viewLWorld,viewRWorld,this.range_.min,this.leftSnapIndicator_,this.leftSelected_);}
+if(this.rightSnapIndicator_){this.drawIndicator_(ctx,viewLWorld,viewRWorld,this.range_.max,this.rightSnapIndicator_,this.rightSelected_);}},drawIndicator_:function(ctx,viewLWorld,viewRWorld,xWorld,si,selected){var dt=this.viewport_.currentDisplayTransform;var viewX=Math.round(dt.xWorldToView(xWorld));ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);var pixelRatio=window.devicePixelRatio||1;var viewY=si.y*devicePixelRatio;var viewHeight=si.height*devicePixelRatio;var arrowSize=4*pixelRatio;if(selected)
+ctx.fillStyle='rgb(255, 0, 0)';else
+ctx.fillStyle='rgb(0, 0, 0)';tr.ui.b.drawTriangle(ctx,viewX-arrowSize*0.75,viewY,viewX+arrowSize*0.75,viewY,viewX,viewY+arrowSize);ctx.fill();tr.ui.b.drawTriangle(ctx,viewX-arrowSize*0.75,viewY+viewHeight,viewX+arrowSize*0.75,viewY+viewHeight,viewX,viewY+viewHeight-arrowSize);ctx.fill();ctx.restore();}};return{SnapIndicator:SnapIndicator,TimelineInterestRange:TimelineInterestRange};});'use strict';tr.exportTo('tr.ui',function(){function TimelineDisplayTransform(opt_that){if(opt_that){this.set(opt_that);return;}
+this.scaleX=1;this.panX=0;this.panY=0;}
+TimelineDisplayTransform.prototype={set:function(that){this.scaleX=that.scaleX;this.panX=that.panX;this.panY=that.panY;},clone:function(){return new TimelineDisplayTransform(this);},equals:function(that){var eq=true;if(that===undefined||that===null)
+return false;eq&=this.panX===that.panX;eq&=this.panY===that.panY;eq&=this.scaleX===that.scaleX;return!!eq;},almostEquals:function(that){var eq=true;if(that===undefined||that===null)
+return false;eq&=Math.abs(this.panX-that.panX)<0.001;eq&=Math.abs(this.panY-that.panY)<0.001;eq&=Math.abs(this.scaleX-that.scaleX)<0.001;return!!eq;},incrementPanXInViewUnits:function(xDeltaView){this.panX+=this.xViewVectorToWorld(xDeltaView);},xPanWorldPosToViewPos:function(worldX,viewX,viewWidth){if(typeof viewX=='string'){if(viewX==='left'){viewX=0;}else if(viewX==='center'){viewX=viewWidth/2;}else if(viewX==='right'){viewX=viewWidth-1;}else{throw new Error('viewX must be left|center|right or number.');}}
+this.panX=(viewX/this.scaleX)-worldX;},xPanWorldBoundsIntoView:function(worldMin,worldMax,viewWidth){if(this.xWorldToView(worldMin)<0)
+this.xPanWorldPosToViewPos(worldMin,'left',viewWidth);else if(this.xWorldToView(worldMax)>viewWidth)
+this.xPanWorldPosToViewPos(worldMax,'right',viewWidth);},xSetWorldBounds:function(worldMin,worldMax,viewWidth){var worldWidth=worldMax-worldMin;var scaleX=viewWidth/worldWidth;var panX=-worldMin;this.setPanAndScale(panX,scaleX);},setPanAndScale:function(p,s){this.scaleX=s;this.panX=p;},xWorldToView:function(x){return(x+this.panX)*this.scaleX;},xWorldVectorToView:function(x){return x*this.scaleX;},xViewToWorld:function(x){return(x/this.scaleX)-this.panX;},xViewVectorToWorld:function(x){return x/this.scaleX;},applyTransformToCanvas:function(ctx){ctx.transform(this.scaleX,0,0,1,this.panX*this.scaleX,0);}};return{TimelineDisplayTransform:TimelineDisplayTransform};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ContainerToTrackMap(){this.stableIdToTrackMap_={};}
+ContainerToTrackMap.prototype={addContainer:function(container,track){if(!track)
+throw new Error('Must provide a track.');this.stableIdToTrackMap_[container.stableId]=track;},clear:function(){this.stableIdToTrackMap_={};},getTrackByStableId:function(stableId){return this.stableIdToTrackMap_[stableId];}};return{ContainerToTrackMap:ContainerToTrackMap};});'use strict';tr.exportTo('tr.ui.tracks',function(){function EventToTrackMap(){}
+EventToTrackMap.prototype={addEvent:function(event,track){if(!track)
+throw new Error('Must provide a track.');this[event.guid]=track;}};return{EventToTrackMap:EventToTrackMap};});'use strict';tr.exportTo('tr.ui',function(){var TimelineDisplayTransform=tr.ui.TimelineDisplayTransform;var TimelineInterestRange=tr.ui.TimelineInterestRange;function TimelineViewport(parentEl){this.parentEl_=parentEl;this.modelTrackContainer_=undefined;this.currentDisplayTransform_=new TimelineDisplayTransform();this.initAnimationController_();this.showFlowEvents_=false;this.highlightVSync_=false;this.highDetails_=false;this.gridTimebase_=0;this.gridStep_=1000/60;this.gridEnabled_=false;this.hasCalledSetupFunction_=false;this.onResize_=this.onResize_.bind(this);this.onModelTrackControllerScroll_=this.onModelTrackControllerScroll_.bind(this);this.checkForAttachInterval_=setInterval(this.checkForAttach_.bind(this),250);this.majorMarkPositions=[];this.interestRange_=new TimelineInterestRange(this);this.eventToTrackMap_=new tr.ui.tracks.EventToTrackMap();this.containerToTrackMap=new tr.ui.tracks.ContainerToTrackMap();}
+TimelineViewport.prototype={__proto__:tr.b.EventTarget.prototype,setWhenPossible:function(fn){this.pendingSetFunction_=fn;},get isAttachedToDocumentOrInTestMode(){if(this.parentEl_===undefined)
+return;return tr.ui.b.isElementAttachedToDocument(this.parentEl_);},onResize_:function(){this.dispatchChangeEvent();},checkForAttach_:function(){if(!this.isAttachedToDocumentOrInTestMode||this.clientWidth==0)
+return;if(!this.iframe_){this.iframe_=document.createElement('iframe');this.iframe_.style.cssText='position:absolute;width:100%;height:0;border:0;visibility:hidden;';this.parentEl_.appendChild(this.iframe_);this.iframe_.contentWindow.addEventListener('resize',this.onResize_);}
+var curSize=this.parentEl_.clientWidth+'x'+
+this.parentEl_.clientHeight;if(this.pendingSetFunction_){this.lastSize_=curSize;try{this.pendingSetFunction_();}catch(ex){console.log('While running setWhenPossible:',ex.message?ex.message+'\n'+ex.stack:ex.stack);}
+this.pendingSetFunction_=undefined;}
+window.clearInterval(this.checkForAttachInterval_);this.checkForAttachInterval_=undefined;},dispatchChangeEvent:function(){tr.b.dispatchSimpleEvent(this,'change');},detach:function(){if(this.checkForAttachInterval_){window.clearInterval(this.checkForAttachInterval_);this.checkForAttachInterval_=undefined;}
+if(this.iframe_){this.iframe_.removeEventListener('resize',this.onResize_);this.parentEl_.removeChild(this.iframe_);}},initAnimationController_:function(){this.dtAnimationController_=new tr.ui.b.AnimationController();this.dtAnimationController_.addEventListener('didtick',function(e){this.onCurentDisplayTransformChange_(e.oldTargetState);}.bind(this));var that=this;this.dtAnimationController_.target={get panX(){return that.currentDisplayTransform_.panX;},set panX(panX){that.currentDisplayTransform_.panX=panX;},get panY(){return that.currentDisplayTransform_.panY;},set panY(panY){that.currentDisplayTransform_.panY=panY;},get scaleX(){return that.currentDisplayTransform_.scaleX;},set scaleX(scaleX){that.currentDisplayTransform_.scaleX=scaleX;},cloneAnimationState:function(){return that.currentDisplayTransform_.clone();},xPanWorldPosToViewPos:function(xWorld,xView){that.currentDisplayTransform_.xPanWorldPosToViewPos(xWorld,xView,that.modelTrackContainer_.canvas.clientWidth);}};},get currentDisplayTransform(){return this.currentDisplayTransform_;},setDisplayTransformImmediately:function(displayTransform){this.dtAnimationController_.cancelActiveAnimation();var oldDisplayTransform=this.dtAnimationController_.target.cloneAnimationState();this.currentDisplayTransform_.set(displayTransform);this.onCurentDisplayTransformChange_(oldDisplayTransform);},queueDisplayTransformAnimation:function(animation){if(!(animation instanceof tr.ui.b.Animation))
+throw new Error('animation must be instanceof tr.ui.b.Animation');this.dtAnimationController_.queueAnimation(animation);},onCurentDisplayTransformChange_:function(oldDisplayTransform){if(this.modelTrackContainer_){this.currentDisplayTransform.panY=tr.b.clamp(this.currentDisplayTransform.panY,0,this.modelTrackContainer_.scrollHeight-
+this.modelTrackContainer_.clientHeight);}
+var changed=!this.currentDisplayTransform.equals(oldDisplayTransform);var yChanged=this.currentDisplayTransform.panY!==oldDisplayTransform.panY;if(yChanged)
+this.modelTrackContainer_.scrollTop=this.currentDisplayTransform.panY;if(changed)
+this.dispatchChangeEvent();},onModelTrackControllerScroll_:function(e){if(this.dtAnimationController_.activeAnimation&&this.dtAnimationController_.activeAnimation.affectsPanY)
+this.dtAnimationController_.cancelActiveAnimation();var panY=this.modelTrackContainer_.scrollTop;this.currentDisplayTransform_.panY=panY;},get modelTrackContainer(){return this.modelTrackContainer_;},set modelTrackContainer(m){if(this.modelTrackContainer_)
+this.modelTrackContainer_.removeEventListener('scroll',this.onModelTrackControllerScroll_);this.modelTrackContainer_=m;this.modelTrackContainer_.addEventListener('scroll',this.onModelTrackControllerScroll_);},get showFlowEvents(){return this.showFlowEvents_;},set showFlowEvents(showFlowEvents){this.showFlowEvents_=showFlowEvents;this.dispatchChangeEvent();},get highlightVSync(){return this.highlightVSync_;},set highlightVSync(highlightVSync){this.highlightVSync_=highlightVSync;this.dispatchChangeEvent();},get highDetails(){return this.highDetails_;},set highDetails(highDetails){this.highDetails_=highDetails;this.dispatchChangeEvent();},get gridEnabled(){return this.gridEnabled_;},set gridEnabled(enabled){if(this.gridEnabled_==enabled)
+return;this.gridEnabled_=enabled&&true;this.dispatchChangeEvent();},get gridTimebase(){return this.gridTimebase_;},set gridTimebase(timebase){if(this.gridTimebase_==timebase)
+return;this.gridTimebase_=timebase;this.dispatchChangeEvent();},get gridStep(){return this.gridStep_;},get interestRange(){return this.interestRange_;},drawMajorMarkLines:function(ctx){ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);ctx.beginPath();for(var idx in this.majorMarkPositions){var x=Math.floor(this.majorMarkPositions[idx]);tr.ui.b.drawLine(ctx,x,0,x,ctx.canvas.height);}
+ctx.strokeStyle='#ddd';ctx.stroke();ctx.restore();},drawGridLines:function(ctx,viewLWorld,viewRWorld){if(!this.gridEnabled)
+return;var dt=this.currentDisplayTransform;var x=this.gridTimebase;ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);ctx.beginPath();while(x<viewRWorld){if(x>=viewLWorld){var vx=Math.floor(dt.xWorldToView(x));tr.ui.b.drawLine(ctx,vx,0,vx,ctx.canvas.height);}
+x+=this.gridStep;}
+ctx.strokeStyle='rgba(255, 0, 0, 0.25)';ctx.stroke();ctx.restore();},getShiftedSelection:function(selection,offset){var newSelection=new tr.model.EventSet();for(var i=0;i<selection.length;i++){var event=selection[i];if(event instanceof tr.model.FlowEvent){if(offset>0){newSelection.push(event.endSlice);}else if(offset<0){newSelection.push(event.startSlice);}else{}
+continue;}
+var track=this.trackForEvent(event);track.addEventNearToProvidedEventToSelection(event,offset,newSelection);}
+if(newSelection.length==0)
+return undefined;return newSelection;},rebuildEventToTrackMap:function(){this.eventToTrackMap_=new tr.ui.tracks.EventToTrackMap();this.modelTrackContainer_.addEventsToTrackMap(this.eventToTrackMap_);},rebuildContainerToTrackMap:function(){this.containerToTrackMap.clear();this.modelTrackContainer_.addContainersToTrackMap(this.containerToTrackMap);},trackForEvent:function(event){return this.eventToTrackMap_[event.guid];}};return{TimelineViewport:TimelineViewport};});'use strict';tr.exportTo('tr.ui.b',function(){var Location=tr.model.Location;function UIState(location,scaleX){this.location_=location;this.scaleX_=scaleX;};UIState.fromUserFriendlyString=function(model,viewport,stateString){var navByFinderPattern=/^(-?\d+(\.\d+)?)@(.+)x(\d+(\.\d+)?)$/g;var match=navByFinderPattern.exec(stateString);if(!match)
+return;var timestamp=parseFloat(match[1]);var stableId=match[3];var scaleX=parseFloat(match[4]);if(scaleX<=0)
+throw new Error('Invalid ScaleX value in UI State string.');if(!viewport.containerToTrackMap.getTrackByStableId(stableId))
+throw new Error('Invalid StableID given in UI State String.');var loc=tr.model.Location.fromStableIdAndTimestamp(viewport,stableId,timestamp);return new UIState(loc,scaleX);}
+UIState.prototype={get location(){return this.location_;},get scaleX(){return this.scaleX_;},toUserFriendlyString:function(viewport){var timestamp=this.location_.xWorld;var stableId=this.location_.getContainingTrack(viewport).eventContainer.stableId;var scaleX=this.scaleX_;return timestamp.toFixed(5)+'@'+stableId+'x'+scaleX.toFixed(5);},toDict:function(){return{location:this.location_.toDict(),scaleX:this.scaleX_};}};return{UIState:UIState};});'use strict';tr.exportTo('tr.c',function(){var BrushingState=tr.ui.b.BrushingState;var EventSet=tr.model.EventSet;var SelectionState=tr.model.SelectionState;var Viewport=tr.ui.TimelineViewport;function BrushingStateController(timelineView){tr.b.EventTarget.call(this);this.timelineView_=timelineView;this.currentBrushingState_=new BrushingState();this.onPopState_=this.onPopState_.bind(this);this.historyEnabled_=false;this.selections_={};}
+BrushingStateController.prototype={__proto__:tr.b.EventTarget.prototype,dispatchChangeEvent_:function(){var e=new tr.b.Event('change',false,false);this.dispatchEvent(e);},get model(){if(!this.timelineView_)
+return undefined;return this.timelineView_.model;},get trackView(){if(!this.timelineView_)
+return undefined;return this.timelineView_.trackView;},get viewport(){if(!this.timelineView_)
+return undefined;if(!this.timelineView_.trackView)
+return undefined;return this.timelineView_.trackView.viewport;},get historyEnabled(){return this.historyEnabled_;},set historyEnabled(historyEnabled){this.historyEnabled_=!!historyEnabled;if(historyEnabled)
+window.addEventListener('popstate',this.onPopState_);else
+window.removeEventListener('popstate',this.onPopState_);},modelWillChange:function(){if(this.currentBrushingState_.isAppliedToModel)
+this.currentBrushingState_.unapplyFromModelSelectionState();},modelDidChange:function(){this.selections_={};this.currentBrushingState_=new BrushingState();this.currentBrushingState_.applyToModelSelectionState(this.model);var e=new tr.b.Event('model-changed',false,false);this.dispatchEvent(e);this.dispatchChangeEvent_();},onUserInitiatedSelectionChange_:function(){var selection=this.selection;if(this.historyEnabled){this.selections_[selection.guid]=selection;var state={selection_guid:selection.guid};window.history.pushState(state,document.title);}},onPopState_:function(e){if(e.state===null)
+return;var selection=this.selections_[e.state.selection_guid];if(selection){var newState=this.currentBrushingState_.clone();newState.selection=selection;this.currentBrushingState=newState;}
+e.stopPropagation();},get selection(){return this.currentBrushingState_.selection;},get findMatches(){return this.currentBrushingState_.findMatches;},get selectionOfInterest(){return this.currentBrushingState_.selectionOfInterest;},get currentBrushingState(){return this.currentBrushingState_;},set currentBrushingState(newBrushingState){if(newBrushingState.isAppliedToModel)
+throw new Error('Cannot apply this state, it is applied');var hasValueChanged=!this.currentBrushingState_.equals(newBrushingState);if(newBrushingState!==this.currentBrushingState_&&!hasValueChanged){if(this.currentBrushingState_.isAppliedToModel){this.currentBrushingState_.transferModelOwnershipToClone(newBrushingState);}
+this.currentBrushingState_=newBrushingState;return;}
+if(this.currentBrushingState_.isAppliedToModel)
+this.currentBrushingState_.unapplyFromModelSelectionState();this.currentBrushingState_=newBrushingState;if(this.model)
+this.currentBrushingState_.applyToModelSelectionState(this.model);this.dispatchChangeEvent_();},addAllEventsMatchingFilterToSelectionAsTask:function(filter,selection){var timelineView=this.timelineView_.trackView;if(!timelineView)
+return new tr.b.Task();return timelineView.addAllEventsMatchingFilterToSelectionAsTask(filter,selection);},findTextChangedTo:function(allPossibleMatches){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.findMatches=allPossibleMatches;this.currentBrushingState=newBrushingState;},findFocusChangedTo:function(currentFocus){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=currentFocus;this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},findTextCleared:function(){if(this.xNavStringMarker_!==undefined){this.model.removeAnnotation(this.xNavStringMarker_);this.xNavStringMarker_=undefined;}
+if(this.guideLineAnnotation_!==undefined){this.model.removeAnnotation(this.guideLineAnnotation_);this.guideLineAnnotation_=undefined;}
+var newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=new EventSet();newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},uiStateFromString:function(string){return tr.ui.b.UIState.fromUserFriendlyString(this.model,this.viewport,string);},navToPosition:function(uiState,showNavLine){this.trackView.navToPosition(uiState,showNavLine);},changeSelectionFromTimeline:function(selection){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=selection;newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},showScriptControlSelection:function(selection){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=selection;newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;},changeSelectionFromRequestSelectionChangeEvent:function(selection){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=selection;newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},changeAnalysisViewRelatedEvents:function(eventSet){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.analysisViewRelatedEvents=eventSet;this.currentBrushingState=newBrushingState;},changeAnalysisLinkHoveredEvents:function(eventSet){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.analysisLinkHoveredEvents=eventSet;this.currentBrushingState=newBrushingState;},getViewSpecificBrushingState:function(viewId){return this.currentBrushingState.viewSpecificBrushingStates[viewId];},changeViewSpecificBrushingState:function(viewId,newState){var oldStates=this.currentBrushingState_.viewSpecificBrushingStates;var newStates={};for(var id in oldStates)
+newStates[id]=oldStates[id];if(newState===undefined)
+delete newStates[viewId];else
+newStates[viewId]=newState;var newBrushingState=this.currentBrushingState_.clone();newBrushingState.viewSpecificBrushingStates=newStates;this.currentBrushingState=newBrushingState;}};BrushingStateController.getControllerForElement=function(element){if(tr.isHeadless)
+throw new Error('Unsupported');var currentElement=element;while(currentElement){if(currentElement.brushingStateController)
+return currentElement.brushingStateController;if(currentElement.parentElement){currentElement=currentElement.parentElement;continue;}
+var currentNode=currentElement;while(currentNode.parentNode)
+currentNode=currentNode.parentNode;currentElement=currentNode.host;}
+return undefined;};return{BrushingStateController:BrushingStateController};});'use strict';Polymer('tr-ui-a-analysis-link',{ready:function(){this.selection_=undefined;},attached:function(){this.controller_=tr.c.BrushingStateController.getControllerForElement(this);},detached:function(){this.clearHighlight_();this.controller_=undefined;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;this.textContent=selection.userFriendlyName;},setSelectionAndContent:function(selection,opt_textContent){this.selection_=selection;if(opt_textContent)
+this.textContent=opt_textContent;},getCurrentSelection_:function(){if(typeof this.selection_==='function')
+return this.selection_();return this.selection_;},setHighlight_:function(opt_eventSet){if(this.controller_)
+this.controller_.changeAnalysisLinkHoveredEvents(opt_eventSet);},clearHighlight_:function(opt_eventSet){this.setHighlight_();},onClicked_:function(){if(!this.selection_)
+return;var event=new tr.model.RequestSelectionChangeEvent();event.selection=this.getCurrentSelection_();this.dispatchEvent(event);},onMouseEnter_:function(){this.setHighlight_(this.getCurrentSelection_());},onMouseLeave_:function(){this.clearHighlight_();}});'use strict';tr.exportTo('tr.ui.b',function(){var TableFormat={};TableFormat.SelectionMode={NONE:0,ROW:1,CELL:2};TableFormat.HighlightStyle={DEFAULT:0,NONE:1,LIGHT:2,DARK:3};return{TableFormat:TableFormat};});'use strict';(function(){var RIGHT_ARROW=String.fromCharCode(0x25b6);var UNSORTED_ARROW=String.fromCharCode(0x25BF);var ASCENDING_ARROW=String.fromCharCode(0x25B4);var DESCENDING_ARROW=String.fromCharCode(0x25BE);var BASIC_INDENTATION=8;var SelectionMode=tr.ui.b.TableFormat.SelectionMode;var HighlightStyle=tr.ui.b.TableFormat.HighlightStyle;Polymer('tr-ui-b-table',{created:function(){this.selectionMode_=SelectionMode.NONE;this.rowHighlightStyle_=HighlightStyle.DEFAULT;this.cellHighlightStyle_=HighlightStyle.DEFAULT;this.selectedTableRowInfo_=undefined;this.selectedColumnIndex_=undefined;this.tableColumns_=[];this.tableRows_=[];this.tableRowsInfo_=new WeakMap();this.tableFooterRows_=[];this.tableFooterRowsInfo_=new WeakMap();this.sortColumnIndex_=undefined;this.sortDescending_=false;this.columnsWithExpandButtons_=[];this.headerCells_=[];this.showHeader_=true;this.emptyValue_=undefined;this.subRowsPropertyName_='subRows';this.customizeTableRowCallback_=undefined;},ready:function(){this.$.body.addEventListener('keydown',this.onKeyDown_.bind(this),true);},clear:function(){this.selectionMode_=SelectionMode.NONE;this.rowHighlightStyle_=HighlightStyle.DEFAULT;this.cellHighlightStyle_=HighlightStyle.DEFAULT;this.selectedTableRowInfo_=undefined;this.selectedColumnIndex_=undefined;this.textContent='';this.tableColumns_=[];this.tableRows_=[];this.tableRowsInfo_=new WeakMap();this.tableFooterRows_=[];this.tableFooterRowsInfo_=new WeakMap();this.sortColumnIndex_=undefined;this.sortDescending_=false;this.columnsWithExpandButtons_=[];this.headerCells_=[];this.subRowsPropertyName_='subRows';},get showHeader(){return this.showHeader_;},set showHeader(showHeader){this.showHeader_=showHeader;this.scheduleRebuildHeaders_();},set subRowsPropertyName(name){this.subRowsPropertyName_=name;},set customizeTableRowCallback(cb){this.customizeTableRowCallback_=cb;this.scheduleRebuildBody_();},get emptyValue(){return this.emptyValue_;},set emptyValue(emptyValue){var previousEmptyValue=this.emptyValue_;this.emptyValue_=emptyValue;if(this.tableRows_.length===0&&emptyValue!==previousEmptyValue)
+this.scheduleRebuildBody_();},set tableColumns(columns){var columnsWithExpandButtons=[];for(var i=0;i<columns.length;i++){if(columns[i].showExpandButtons)
+columnsWithExpandButtons.push(i);}
+if(columnsWithExpandButtons.length===0){columnsWithExpandButtons=[0];}
+for(var i=0;i<columns.length;i++){var colInfo=columns[i];if(colInfo.width===undefined)
+continue;var hasExpandButton=columnsWithExpandButtons.indexOf(i)!==-1;var w=colInfo.width;if(w){if(/\d+px/.test(w)){continue;}else if(/\d+%/.test(w)){if(hasExpandButton){throw new Error('Columns cannot be %-sized and host '+' an expand button');}}else{throw new Error('Unrecognized width string');}}}
+this.tableColumns_=columns;this.headerCells_=[];this.columnsWithExpandButtons_=columnsWithExpandButtons;this.sortColumnIndex=undefined;this.scheduleRebuildHeaders_();this.tableRows=this.tableRows_;},get tableColumns(){return this.tableColumns_;},set tableRows(rows){this.selectedTableRowInfo_=undefined;this.selectedColumnIndex_=undefined;this.maybeUpdateSelectedRow_();this.tableRows_=rows;this.tableRowsInfo_=new WeakMap();this.scheduleRebuildBody_();},get tableRows(){return this.tableRows_;},set footerRows(rows){this.tableFooterRows_=rows;this.tableFooterRowsInfo_=new WeakMap();this.scheduleRebuildFooter_();},get footerRows(){return this.tableFooterRows_;},set sortColumnIndex(number){if(number===this.sortColumnIndex_)
+return;if(number===undefined){this.sortColumnIndex_=undefined;this.updateHeaderArrows_();this.dispatchSortingChangedEvent_();return;}
+if(this.tableColumns_.length<=number)
+throw new Error('Column number '+number+' is out of bounds.');if(!this.tableColumns_[number].cmp)
+throw new Error('Column '+number+' does not have a comparator.');this.sortColumnIndex_=number;this.updateHeaderArrows_();this.scheduleRebuildBody_();this.dispatchSortingChangedEvent_();},get sortColumnIndex(){return this.sortColumnIndex_;},set sortDescending(value){var newValue=!!value;if(newValue!==this.sortDescending_){this.sortDescending_=newValue;this.updateHeaderArrows_();this.scheduleRebuildBody_();this.dispatchSortingChangedEvent_();}},get sortDescending(){return this.sortDescending_;},updateHeaderArrows_:function(){for(var i=0;i<this.headerCells_.length;i++){if(!this.tableColumns_[i].cmp){this.headerCells_[i].sideContent='';continue;}
+if(i!==this.sortColumnIndex_){this.headerCells_[i].sideContent=UNSORTED_ARROW;continue;}
+this.headerCells_[i].sideContent=this.sortDescending_?DESCENDING_ARROW:ASCENDING_ARROW;}},sortRows_:function(rows){rows.sort(function(rowA,rowB){if(this.sortDescending_)
+return this.tableColumns_[this.sortColumnIndex_].cmp(rowB.userRow,rowA.userRow);return this.tableColumns_[this.sortColumnIndex_].cmp(rowA.userRow,rowB.userRow);}.bind(this));for(var i=0;i<rows.length;i++){if(rows[i].isExpanded)
+this.sortRows_(rows[i][this.subRowsPropertyName_]);}},generateHeaderColumns_:function(){this.headerCells_=[];this.$.head.textContent='';if(!this.showHeader_)
+return;var tr=this.appendNewElement_(this.$.head,'tr');for(var i=0;i<this.tableColumns_.length;i++){var td=this.appendNewElement_(tr,'td');var headerCell=document.createElement('tr-ui-b-table-header-cell');if(this.showHeader)
+headerCell.cellTitle=this.tableColumns_[i].title;else
+headerCell.cellTitle='';if(this.tableColumns_[i].cmp){td.classList.add('sensitive');headerCell.tapCallback=this.createSortCallback_(i);if(this.sortColumnIndex_===i)
+headerCell.sideContent=this.sortDescending_?DESCENDING_ARROW:ASCENDING_ARROW;else
+headerCell.sideContent=UNSORTED_ARROW;}
+td.appendChild(headerCell);this.headerCells_.push(headerCell);}},applySizes_:function(){if(this.tableRows_.length===0&&!this.showHeader)
+return;var rowToRemoveSizing;var rowToSize;if(this.showHeader){rowToSize=this.$.head.children[0];rowToRemoveSizing=this.$.body.children[0];}else{rowToSize=this.$.body.children[0];rowToRemoveSizing=this.$.head.children[0];}
+for(var i=0;i<this.tableColumns_.length;i++){if(rowToRemoveSizing&&rowToRemoveSizing.children[i]){var tdToRemoveSizing=rowToRemoveSizing.children[i];tdToRemoveSizing.style.minWidth='';tdToRemoveSizing.style.width='';}
+var td=rowToSize.children[i];var delta;if(this.columnsWithExpandButtons_.indexOf(i)!==-1){td.style.paddingLeft=BASIC_INDENTATION+'px';delta=BASIC_INDENTATION+'px';}else{delta=undefined;}
+function calc(base,delta){if(delta)
+return'calc('+base+' - '+delta+')';else
+return base;}
+var w=this.tableColumns_[i].width;if(w){if(/\d+px/.test(w)){td.style.minWidth=calc(w,delta);}else if(/\d+%/.test(w)){td.style.width=w;}else{throw new Error('Unrecognized width string: '+w);}}}},createSortCallback_:function(columnNumber){return function(){var previousIndex=this.sortColumnIndex;this.sortColumnIndex=columnNumber;if(previousIndex!==columnNumber)
+this.sortDescending=false;else
+this.sortDescending=!this.sortDescending;}.bind(this);},generateTableRowNodes_:function(tableSection,userRows,rowInfoMap,indentation,lastAddedRow,parentRowInfo){if(this.sortColumnIndex_!==undefined&&tableSection===this.$.body){userRows=userRows.slice();userRows.sort(function(rowA,rowB){var c=this.tableColumns_[this.sortColumnIndex_].cmp(rowA,rowB);if(this.sortDescending_)
+c=-c;return c;}.bind(this));}
+for(var i=0;i<userRows.length;i++){var userRow=userRows[i];var rowInfo=this.getOrCreateRowInfoFor_(rowInfoMap,userRow,parentRowInfo);var htmlNode=this.getHTMLNodeForRowInfo_(tableSection,rowInfo,rowInfoMap,indentation);if(lastAddedRow===undefined){tableSection.insertBefore(htmlNode,tableSection.firstChild);}else{var nextSiblingOfLastAdded=lastAddedRow.nextSibling;tableSection.insertBefore(htmlNode,nextSiblingOfLastAdded);}
+this.updateTabIndexForTableRowNode_(htmlNode);lastAddedRow=htmlNode;if(!rowInfo.isExpanded)
+continue;lastAddedRow=this.generateTableRowNodes_(tableSection,userRow[this.subRowsPropertyName_],rowInfoMap,indentation+1,lastAddedRow,rowInfo);}
+return lastAddedRow;},getOrCreateRowInfoFor_:function(rowInfoMap,userRow,parentRowInfo){if(rowInfoMap.has(userRow))
+return rowInfoMap.get(userRow);var rowInfo={userRow:userRow,htmlNode:undefined,isExpanded:userRow.isExpanded||false,parentRowInfo:parentRowInfo};rowInfoMap.set(userRow,rowInfo);return rowInfo;},customizeTableRow_:function(userRow,trElement){if(!this.customizeTableRowCallback_)
+return;this.customizeTableRowCallback_(userRow,trElement);},getHTMLNodeForRowInfo_:function(tableSection,rowInfo,rowInfoMap,indentation){if(rowInfo.htmlNode){this.customizeTableRow_(rowInfo.userRow,rowInfo.htmlNode);return rowInfo.htmlNode;}
+var INDENT_SPACE=indentation*16;var INDENT_SPACE_NO_BUTTON=indentation*16+BASIC_INDENTATION;var trElement=this.ownerDocument.createElement('tr');rowInfo.htmlNode=trElement;rowInfo.indentation=indentation;trElement.rowInfo=rowInfo;this.customizeTableRow_(rowInfo.userRow,trElement);for(var i=0;i<this.tableColumns_.length;){var td=this.appendNewElement_(trElement,'td');td.columnIndex=i;var column=this.tableColumns_[i];var value=column.value(rowInfo.userRow);var colSpan=column.colSpan?column.colSpan:1;td.style.colSpan=colSpan;if(column.textAlign){td.style.textAlign=column.textAlign;}
+if(this.doesColumnIndexSupportSelection(i))
+td.classList.add('supports-selection');if(this.columnsWithExpandButtons_.indexOf(i)!=-1){if(rowInfo.userRow[this.subRowsPropertyName_]&&rowInfo.userRow[this.subRowsPropertyName_].length>0){td.style.paddingLeft=INDENT_SPACE+'px';var expandButton=this.appendNewElement_(td,'expand-button');expandButton.textContent=RIGHT_ARROW;if(rowInfo.isExpanded)
+expandButton.classList.add('button-expanded');}else{td.style.paddingLeft=INDENT_SPACE_NO_BUTTON+'px';}}
+if(value!==undefined)
+td.appendChild(tr.ui.b.asHTMLOrTextNode(value,this.ownerDocument));i+=colSpan;}
+var needsClickListener=false;if(this.columnsWithExpandButtons_.length)
+needsClickListener=true;else if(tableSection==this.$.body)
+needsClickListener=true;if(needsClickListener){trElement.addEventListener('click',function(e){e.stopPropagation();if(e.target.tagName=='EXPAND-BUTTON'){this.setExpandedForUserRow_(tableSection,rowInfoMap,rowInfo.userRow,!rowInfo.isExpanded);return;}
+function getTD(cur){if(cur===trElement)
+throw new Error('woah');if(cur.parentElement===trElement)
+return cur;return getTD(cur.parentElement);}
+if(this.selectionMode_!==SelectionMode.NONE){var isAlreadySelected=false;var tdThatWasClicked=getTD(e.target);switch(this.selectionMode_){case SelectionMode.ROW:isAlreadySelected=this.selectedTableRowInfo_===rowInfo;break;case SelectionMode.CELL:isAlreadySelected=this.selectedTableRowInfo_===rowInfo;isAlreadySelected&=(this.selectedColumnIndex_===tdThatWasClicked.columnIndex);break;default:throw new Error('Invalid selection mode '+
+this.selectionMode_);}
+if(isAlreadySelected){if(rowInfo.userRow[this.subRowsPropertyName_]&&rowInfo.userRow[this.subRowsPropertyName_].length){this.setExpandedForUserRow_(tableSection,rowInfoMap,rowInfo.userRow,!rowInfo.isExpanded);}}else{this.didTableRowInfoGetClicked_(rowInfo,tdThatWasClicked.columnIndex);}}else{if(rowInfo.userRow[this.subRowsPropertyName_]&&rowInfo.userRow[this.subRowsPropertyName_].length){this.setExpandedForUserRow_(tableSection,rowInfoMap,rowInfo.userRow,!rowInfo.isExpanded);}}}.bind(this));}
+return rowInfo.htmlNode;},removeSubNodes_:function(tableSection,rowInfo,rowInfoMap){if(rowInfo.userRow[this.subRowsPropertyName_]===undefined)
+return;for(var i=0;i<rowInfo.userRow[this.subRowsPropertyName_].length;i++){var subRow=rowInfo.userRow[this.subRowsPropertyName_][i];var subRowInfo=rowInfoMap.get(subRow);if(!subRowInfo)
+continue;var subNode=subRowInfo.htmlNode;if(subNode&&subNode.parentNode===tableSection){tableSection.removeChild(subNode);this.removeSubNodes_(tableSection,subRowInfo,rowInfoMap);}}},scheduleRebuildHeaders_:function(){this.headerDirty_=true;this.scheduleRebuild_();},scheduleRebuildBody_:function(){this.bodyDirty_=true;this.scheduleRebuild_();},scheduleRebuildFooter_:function(){this.footerDirty_=true;this.scheduleRebuild_();},scheduleRebuild_:function(){if(this.rebuildPending_)
+return;this.rebuildPending_=true;setTimeout(function(){this.rebuildPending_=false;this.rebuild();}.bind(this),0);},rebuildIfNeeded_:function(){this.rebuild();},rebuild:function(){var wasBodyOrHeaderDirty=this.headerDirty_||this.bodyDirty_;if(this.headerDirty_){this.generateHeaderColumns_();this.headerDirty_=false;}
+if(this.bodyDirty_){this.$.body.textContent='';this.generateTableRowNodes_(this.$.body,this.tableRows_,this.tableRowsInfo_,0,undefined,undefined);if(this.tableRows_.length===0&&this.emptyValue_!==undefined){var trElement=this.ownerDocument.createElement('tr');this.$.body.appendChild(trElement);trElement.classList.add('empty-row');var td=this.ownerDocument.createElement('td');trElement.appendChild(td);td.colSpan=this.tableColumns_.length;var emptyValue=this.emptyValue_;td.appendChild(tr.ui.b.asHTMLOrTextNode(emptyValue,this.ownerDocument));}
+this.bodyDirty_=false;}
+if(wasBodyOrHeaderDirty)
+this.applySizes_();if(this.footerDirty_){this.$.foot.textContent='';this.generateTableRowNodes_(this.$.foot,this.tableFooterRows_,this.tableFooterRowsInfo_,0,undefined,undefined);if(this.tableFooterRowsInfo_.length){this.$.body.classList.add('has-footer');}else{this.$.body.classList.remove('has-footer');}
+this.footerDirty_=false;}},appendNewElement_:function(parent,tagName){var element=parent.ownerDocument.createElement(tagName);parent.appendChild(element);return element;},getExpandedForTableRow:function(userRow){this.rebuildIfNeeded_();var rowInfo=this.tableRowsInfo_.get(userRow);if(rowInfo===undefined)
+throw new Error('Row has not been seen, must expand its parents');return rowInfo.isExpanded;},setExpandedForTableRow:function(userRow,expanded){this.rebuildIfNeeded_();var rowInfo=this.tableRowsInfo_.get(userRow);if(rowInfo===undefined)
+throw new Error('Row has not been seen, must expand its parents');return this.setExpandedForUserRow_(this.$.body,this.tableRowsInfo_,userRow,expanded);},setExpandedForUserRow_:function(tableSection,rowInfoMap,userRow,expanded){this.rebuildIfNeeded_();var rowInfo=rowInfoMap.get(userRow);if(rowInfo===undefined)
+throw new Error('Row has not been seen, must expand its parents');rowInfo.isExpanded=!!expanded;if(rowInfo.htmlNode===undefined)
+return;if(rowInfo.htmlNode.parentElement!==tableSection)
+return;var expandButton=rowInfo.htmlNode.querySelector('expand-button');if(rowInfo.isExpanded){expandButton.classList.add('button-expanded');var lastAddedRow=rowInfo.htmlNode;if(rowInfo.userRow[this.subRowsPropertyName_]){this.generateTableRowNodes_(tableSection,rowInfo.userRow[this.subRowsPropertyName_],rowInfoMap,rowInfo.indentation+1,lastAddedRow,rowInfo);}}else{expandButton.classList.remove('button-expanded');this.removeSubNodes_(tableSection,rowInfo,rowInfoMap);}
+this.maybeUpdateSelectedRow_();},get selectionMode(){return this.selectionMode_;},set selectionMode(selectionMode){if(!tr.b.dictionaryContainsValue(SelectionMode,selectionMode))
+throw new Error('Invalid selection mode '+selectionMode);this.rebuildIfNeeded_();this.selectionMode_=selectionMode;this.didSelectionStateChange_();},get rowHighlightStyle(){return this.rowHighlightStyle_;},set rowHighlightStyle(rowHighlightStyle){if(!tr.b.dictionaryContainsValue(HighlightStyle,rowHighlightStyle))
+throw new Error('Invalid row highlight style '+rowHighlightStyle);this.rebuildIfNeeded_();this.rowHighlightStyle_=rowHighlightStyle;this.didSelectionStateChange_();},get resolvedRowHighlightStyle(){if(this.rowHighlightStyle_!==HighlightStyle.DEFAULT)
+return this.rowHighlightStyle_;switch(this.selectionMode_){case SelectionMode.NONE:return HighlightStyle.NONE;case SelectionMode.ROW:return HighlightStyle.DARK;case SelectionMode.CELL:return HighlightStyle.LIGHT;default:throw new Error('Invalid selection mode '+selectionMode);}},get cellHighlightStyle(){return this.cellHighlightStyle_;},set cellHighlightStyle(cellHighlightStyle){if(!tr.b.dictionaryContainsValue(HighlightStyle,cellHighlightStyle))
+throw new Error('Invalid cell highlight style '+cellHighlightStyle);this.rebuildIfNeeded_();this.cellHighlightStyle_=cellHighlightStyle;this.didSelectionStateChange_();},get resolvedCellHighlightStyle(){if(this.cellHighlightStyle_!==HighlightStyle.DEFAULT)
+return this.cellHighlightStyle_;switch(this.selectionMode_){case SelectionMode.NONE:case SelectionMode.ROW:return HighlightStyle.NONE;case SelectionMode.CELL:return HighlightStyle.DARK;default:throw new Error('Invalid selection mode '+selectionMode);}},setHighlightStyle_:function(highlightAttribute,resolvedHighlightStyle){switch(resolvedHighlightStyle){case HighlightStyle.NONE:this.$.body.removeAttribute(highlightAttribute);break;case HighlightStyle.LIGHT:this.$.body.setAttribute(highlightAttribute,'light');break;case HighlightStyle.DARK:this.$.body.setAttribute(highlightAttribute,'dark');break;default:throw new Error('Invalid resolved highlight style '+
+resolvedHighlightStyle);}},didSelectionStateChange_:function(){this.setHighlightStyle_('row-highlight-style',this.resolvedRowHighlightStyle);this.setHighlightStyle_('cell-highlight-style',this.resolvedCellHighlightStyle);for(var i=0;i<this.$.body.children.length;i++)
+this.updateTabIndexForTableRowNode_(this.$.body.children[i]);this.maybeUpdateSelectedRow_();},maybeUpdateSelectedRow_:function(){if(this.selectedTableRowInfo_===undefined)
+return;if(this.selectionMode_===SelectionMode.NONE){this.removeSelectedState_();this.selectedTableRowInfo_=undefined;return;}
+function isVisible(rowInfo){if(!rowInfo.htmlNode)
+return false;return!!rowInfo.htmlNode.parentElement;}
+if(isVisible(this.selectedTableRowInfo_)){this.updateSelectedState_();return;}
+this.removeSelectedState_();var curRowInfo=this.selectedTableRowInfo_;while(curRowInfo&&!isVisible(curRowInfo))
+curRowInfo=curRowInfo.parentRowInfo;this.selectedTableRowInfo_=curRowInfo;if(this.selectedTableRowInfo_)
+this.updateSelectedState_();},didTableRowInfoGetClicked_:function(rowInfo,columnIndex){switch(this.selectionMode_){case SelectionMode.NONE:return;case SelectionMode.CELL:if(!this.doesColumnIndexSupportSelection(columnIndex))
+return;case SelectionMode.ROW:if(this.selectedTableRowInfo_!==rowInfo)
+this.selectedTableRow=rowInfo.userRow;if(this.selectedColumnIndex!==columnIndex)
+this.selectedColumnIndex=columnIndex;}},get selectedTableRow(){if(!this.selectedTableRowInfo_)
+return undefined;return this.selectedTableRowInfo_.userRow;},set selectedTableRow(userRow){this.rebuildIfNeeded_();if(this.selectionMode_===SelectionMode.NONE)
+throw new Error('Selection is off.');var rowInfo;if(userRow===undefined){rowInfo=undefined;}else{rowInfo=this.tableRowsInfo_.get(userRow);if(!rowInfo)
+throw new Error('Row has not been seen, must expand its parents.');}
+var e=this.prepareToChangeSelection_();this.selectedTableRowInfo_=rowInfo;if(this.selectedTableRowInfo_===undefined){this.selectedColumnIndex_=undefined;this.removeSelectedState_();}else{switch(this.selectionMode_){case SelectionMode.ROW:this.selectedColumnIndex_=undefined;break;case SelectionMode.CELL:if(this.selectedColumnIndex_===undefined){var i=this.getFirstSelectableColumnIndex_();if(i==-1)
+throw new Error('Cannot find a selectable column.');this.selectedColumnIndex_=i;}
+break;default:throw new Error('Invalid selection mode '+this.selectionMode_);}
+this.updateSelectedState_();}
+this.dispatchEvent(e);},updateTabIndexForTableRowNode_:function(row){if(this.selectionMode_===SelectionMode.ROW)
+row.tabIndex=0;else
+row.removeAttribute('tabIndex');var enableCellTab=this.selectionMode_===SelectionMode.CELL;for(var i=0;i<this.tableColumns_.length;i++){var cell=row.children[i];if(enableCellTab&&this.doesColumnIndexSupportSelection(i))
+cell.tabIndex=0;else
+cell.removeAttribute('tabIndex');}},prepareToChangeSelection_:function(){var e=new tr.b.Event('selection-changed');var previousSelectedRowInfo=this.selectedTableRowInfo_;if(previousSelectedRowInfo)
+e.previousSelectedTableRow=previousSelectedRowInfo.userRow;else
+e.previousSelectedTableRow=undefined;this.removeSelectedState_();return e;},removeSelectedState_:function(){this.setSelectedState_(false);},updateSelectedState_:function(){this.setSelectedState_(true);},setSelectedState_:function(select){if(this.selectedTableRowInfo_===undefined)
+return;var rowNode=this.selectedTableRowInfo_.htmlNode;if(select)
+rowNode.setAttribute('selected',true);else
+rowNode.removeAttribute('selected');var cellNode=rowNode.children[this.selectedColumnIndex_];if(!cellNode)
+return;if(select)
+cellNode.setAttribute('selected',true);else
+cellNode.removeAttribute('selected');},doesColumnIndexSupportSelection:function(columnIndex){var columnInfo=this.tableColumns_[columnIndex];var scs=columnInfo.supportsCellSelection;if(scs===false)
+return false;return true;},getFirstSelectableColumnIndex_:function(){for(var i=0;i<this.tableColumns_.length;i++){if(this.doesColumnIndexSupportSelection(i))
+return i;}
+return-1;},getSelectableNodeGivenTableRowNode_:function(htmlNode){switch(this.selectionMode_){case SelectionMode.ROW:return htmlNode;case SelectionMode.CELL:return htmlNode.children[this.selectedColumnIndex_];default:throw new Error('Invalid selection mode '+this.selectionMode_);}},get selectedColumnIndex(){if(this.selectionMode_!==SelectionMode.CELL)
+return undefined;return this.selectedColumnIndex_;},set selectedColumnIndex(selectedColumnIndex){this.rebuildIfNeeded_();if(this.selectionMode_===SelectionMode.NONE)
+throw new Error('Selection is off.');if(selectedColumnIndex<0||selectedColumnIndex>=this.tableColumns_.length)
+throw new Error('Invalid index');if(!this.doesColumnIndexSupportSelection(selectedColumnIndex))
+throw new Error('Selection is not supported on this column');var e=this.prepareToChangeSelection_();this.selectedColumnIndex_=selectedColumnIndex;if(this.selectedColumnIndex_===undefined)
+this.selectedTableRowInfo_=undefined;this.updateSelectedState_();this.dispatchEvent(e);},onKeyDown_:function(e){if(this.selectionMode_===SelectionMode.NONE)
+return;if(this.selectedTableRowInfo_===undefined)
+return;var code_to_command_names={37:'ARROW_LEFT',38:'ARROW_UP',39:'ARROW_RIGHT',40:'ARROW_DOWN'};var cmdName=code_to_command_names[e.keyCode];if(cmdName===undefined)
+return;e.stopPropagation();e.preventDefault();this.performKeyCommand_(cmdName);},performKeyCommand_:function(cmdName){this.rebuildIfNeeded_();var rowInfo=this.selectedTableRowInfo_;var htmlNode=rowInfo.htmlNode;if(cmdName==='ARROW_UP'){var prev=htmlNode.previousElementSibling;if(prev){tr.ui.b.scrollIntoViewIfNeeded(prev);this.selectedTableRow=prev.rowInfo.userRow;this.focusSelected_();return;}
+return;}
+if(cmdName==='ARROW_DOWN'){var next=htmlNode.nextElementSibling;if(next){tr.ui.b.scrollIntoViewIfNeeded(next);this.selectedTableRow=next.rowInfo.userRow;this.focusSelected_();return;}
+return;}
+if(cmdName==='ARROW_RIGHT'){switch(this.selectionMode_){case SelectionMode.ROW:if(rowInfo.userRow[this.subRowsPropertyName_]===undefined)
+return;if(rowInfo.userRow[this.subRowsPropertyName_].length===0)
+return;if(!rowInfo.isExpanded)
+this.setExpandedForTableRow(rowInfo.userRow,true);this.selectedTableRow=rowInfo.userRow[this.subRowsPropertyName_][0];this.focusSelected_();return;case SelectionMode.CELL:var newIndex=this.selectedColumnIndex_+1;if(newIndex>=this.tableColumns_.length)
+return;if(!this.doesColumnIndexSupportSelection(newIndex))
+return;this.selectedColumnIndex=newIndex;this.focusSelected_();return;default:throw new Error('Invalid selection mode '+this.selectionMode_);}}
+if(cmdName==='ARROW_LEFT'){switch(this.selectionMode_){case SelectionMode.ROW:if(rowInfo.isExpanded){this.setExpandedForTableRow(rowInfo.userRow,false);this.focusSelected_();return;}
+var parentRowInfo=rowInfo.parentRowInfo;if(parentRowInfo){this.selectedTableRow=parentRowInfo.userRow;this.focusSelected_();return;}
+return;case SelectionMode.CELL:var newIndex=this.selectedColumnIndex_-1;if(newIndex<0)
+return;if(!this.doesColumnIndexSupportSelection(newIndex))
+return;this.selectedColumnIndex=newIndex;this.focusSelected_();return;default:throw new Error('Invalid selection mode '+this.selectionMode_);}}
+throw new Error('Unrecognized command '+cmdName);},focusSelected_:function(){if(!this.selectedTableRowInfo_)
+return;var node=this.getSelectableNodeGivenTableRowNode_(this.selectedTableRowInfo_.htmlNode);node.focus();},dispatchSortingChangedEvent_:function(){var e=new tr.b.Event('sort-column-changed');e.sortColumnIndex=this.sortColumnIndex_;e.sortDescending=this.sortDescending_;this.dispatchEvent(e);}});})();'use strict';Polymer('tr-ui-b-table-header-cell',{created:function(){this.tapCallback_=undefined;this.cellTitle_='';},set cellTitle(value){this.cellTitle_=value;var titleNode=tr.ui.b.asHTMLOrTextNode(this.cellTitle_,this.ownerDocument);this.$.title.innerText='';this.$.title.appendChild(titleNode);},get cellTitle(){return this.cellTitle_;},clearSideContent:function(){this.$.side.textContent='';},set sideContent(content){this.$.side.textContent=content;},get sideContent(){return this.$.side.textContent;},set tapCallback(callback){this.style.cursor='pointer';this.tapCallback_=callback;},get tapCallback(){return this.tapCallback_;},onTap_:function(){if(this.tapCallback_)
+this.tapCallback_();}});'use strict';tr.exportTo('tr.ui.b',function(){Object.observe(Polymer.elements,clearPolymerElementCaches);var elementsByName=undefined;var elementsThatExtend=undefined;var elementSubclasses=undefined;function clearPolymerElementCaches(){elementsByName={};elementsThatExtend=undefined;elementSubclasses={};}
+function buildElementMapsIfNeeded(){if(elementsThatExtend!==undefined&&elementsByName!==undefined)
+return;elementsByName={};elementsThatExtend={};Polymer.elements.forEach(function(element){if(elementsByName[element.name])
+throw new Error('Something is strange: dupe polymer element names');elementsByName[element.name]=element;if(element.extends){if(elementsThatExtend[element.extends]===undefined)
+elementsThatExtend[element.extends]=[];elementsThatExtend[element.extends].push(element.name);}});}
+function getPolymerElementNamed(tagName){buildElementMapsIfNeeded();return elementsByName[tagName];}
+function getPolymerElementsThatSubclass(tagName){if(Polymer.waitingFor().length){throw new Error('There are unresolved polymer elements. '+'Wait until Polymer.whenReady');}
+buildElementMapsIfNeeded();var element=getPolymerElementNamed(tagName);if(!element)
+throw new Error(tagName+' is not a polymer element');if(elementSubclasses===undefined)
+elementSubclasses={};if(elementSubclasses[tagName]===undefined){var immediateSubElements=elementsThatExtend[element.name];var allSubElements=[];if(immediateSubElements!==undefined&&immediateSubElements.length){immediateSubElements.forEach(function(subElement){allSubElements.push(subElement);allSubElements.push.apply(allSubElements,getPolymerElementsThatSubclass(subElement));});}
+elementSubclasses[tagName]=allSubElements;}
+return elementSubclasses[tagName];}
+return{getPolymerElementNamed:getPolymerElementNamed,getPolymerElementsThatSubclass:getPolymerElementsThatSubclass};});'use strict';tr.exportTo('tr.ui.units',function(){function createScalarSpan(value,opt_config){if(value===undefined)
+return'';var config=opt_config||{};var ownerDocument=config.ownerDocument||document;var span=ownerDocument.createElement('tr-ui-u-scalar-span');span.value=value;return span;}
+tr.b.u.Units.addEventListener('display-mode-changed',function(e){var subclassNames=tr.ui.b.getPolymerElementsThatSubclass('tr-ui-u-scalar-span');var isSubclass={};subclassNames.forEach(function(n){isSubclass[n.toUpperCase()]=true;});var m=tr.b.findDeepElementsMatchingPredicate(document.body,function(el){return isSubclass[el.tagName];});m.forEach(function(el){el.updateContent_();});});return{createScalarSpan:createScalarSpan};});'use strict';Polymer('tr-ui-u-scalar-span',{ready:function(){this.value_=undefined;this.unit_=undefined;this.warning_=undefined;this.percentage_=undefined;this.isDelta_=false;},set contentTextDecoration(deco){this.$.content.style.textDecoration=deco;},get value(){return this.value_;},set value(value){if(value instanceof tr.b.u.Scalar){this.value_=value.value;this.unit_=value.unit;}else{this.value_=value;}
+this.updateContent_();},get unit(){return this.unit_;},set unit(unit){this.unit_=unit;this.updateContent_();},setValueAndUnit:function(value,unit){this.value_=value;this.unit_=unit;this.updateContent_();},get percentage(){return this.percentage_;},set percentage(percentage){this.percentage_=percentage;this.updateSparkline_();},get rightAlign(){return this.$.content.classList.contains('right-align');},set rightAlign(rightAlign){if(rightAlign)
+this.$.content.classList.add('right-align');else
+this.$.content.classList.remove('right-align');},get isDelta(){return this.isDelta_;},set isDelta(isDelta){this.isDelta_=isDelta;this.updateContent_();},updateSparkline_:function(){if(this.percentage_===undefined){this.$.sparkline.style.display='none';this.$.sparkline.style.width='0';}else{this.$.sparkline.style.display='block';this.$.sparkline.style.width=(this.percentage_*100)+'%';}},updateContent_:function(){if(this.unit_===undefined){this.$.content.textContent='';return;}
+var content=this.unit_.format(this.value);if(this.isDelta_){if(this.value>0){content='+'+content;}else if(this.value===0){var PLUS_MINUS_SIGN=String.fromCharCode(177);content=PLUS_MINUS_SIGN+content;}}
+this.$.content.textContent=content;},get warning(){return this.warning_;},set warning(warning){this.warning_=warning;var warningEl=this.$.warning;if(this.warning_){warningEl.title=warning;warningEl.style.display='';}else{warningEl.title='';warningEl.style.display='none';}}});'use strict';tr.exportTo('tr.ui.units',function(){function createTimeDurationSpan(duration,opt_config){if(duration===undefined)
+return'';var config=opt_config||{};var ownerDocument=config.ownerDocument||document;var span=ownerDocument.createElement('tr-ui-u-time-duration-span');span.setValueAndUnit(duration,tr.b.u.Units.timeDurationInMs);if(config.total)
+span.percentage=duration/config.total;span.duration=duration;if(config.rightAlign)
+span.rightAlign=true;return span;}
+return{createTimeDurationSpan:createTimeDurationSpan};});'use strict';Polymer('tr-ui-u-time-duration-span',{get duration(){return this.value;},set duration(duration){if(duration instanceof tr.b.u.TimeDuration){this.value=duration;return;}
+this.setValueAndUnit(duration,tr.b.u.Units.timeDurationInMs);}});'use strict';tr.exportTo('tr.ui.units',function(){function createTimeStampSpan(timestamp,opt_config){if(timestamp===undefined)
+return'';var config=opt_config||{};var ownerDocument=config.ownerDocument||document;var span=ownerDocument.createElement('tr-ui-u-time-stamp-span');span.timestamp=timestamp;return span;}
+return{createTimeStampSpan:createTimeStampSpan};});'use strict';Polymer('tr-ui-u-time-stamp-span',{get timestamp(){return this.value;},set timestamp(timestamp){if(timestamp instanceof tr.b.u.TimeStamp){this.value=timestamp;return;}
+this.setValueAndUnit(timestamp,tr.b.u.Units.timeStampInMs);}});'use strict';function isTable(object){if(!(object instanceof Array)||(object.length<2))return false;for(var colName in object[0]){if(typeof colName!=='string')return false;}
+for(var i=0;i<object.length;++i){if(!(object[i]instanceof Object))return false;for(var colName in object[i]){if(i&&(object[0][colName]===undefined))return false;var cellType=typeof object[i][colName];if(cellType!=='string'&&cellType!='number')return false;}
+if(i){for(var colName in object[0]){if(object[i][colName]===undefined)return false;}}}
+return true;}
+Polymer('tr-ui-a-generic-object-view',{ready:function(){this.object_=undefined;},get object(){return this.object_;},set object(object){this.object_=object;this.updateContents_();},updateContents_:function(){this.$.content.textContent='';this.appendElementsForType_('',this.object_,0,0,5,'');},appendElementsForType_:function(label,object,indent,depth,maxDepth,suffix){if(depth>maxDepth){this.appendSimpleText_(label,indent,'<recursion limit reached>',suffix);return;}
+if(object===undefined){this.appendSimpleText_(label,indent,'undefined',suffix);return;}
+if(object===null){this.appendSimpleText_(label,indent,'null',suffix);return;}
+if(!(object instanceof Object)){var type=typeof object;if(type=='string'){var objectReplaced=false;if((object[0]=='{'&&object[object.length-1]=='}')||(object[0]=='['&&object[object.length-1]==']')){try{object=JSON.parse(object);objectReplaced=true;}catch(e){}}
+if(!objectReplaced){if(object.indexOf('\n')!==-1){var lines=object.split('\n');lines.forEach(function(line,i){var text,ioff,ll,ss;if(i==0){text='"'+line;ioff=0;ll=label;ss='';}else if(i<lines.length-1){text=line;ioff=1;ll='';ss='';}else{text=line+'"';ioff=1;ll='';ss=suffix;}
+var el=this.appendSimpleText_(ll,indent+ioff*label.length+ioff,text,ss);el.style.whiteSpace='pre';return el;},this);return;}else{this.appendSimpleText_(label,indent,'"'+object+'"',suffix);return;}}
+else{}}else{return this.appendSimpleText_(label,indent,object,suffix);}}
+if(object instanceof tr.model.ObjectSnapshot){var link=document.createElement('tr-ui-a-analysis-link');link.selection=new tr.model.EventSet(object);this.appendElementWithLabel_(label,indent,link,suffix);return;}
+if(object instanceof tr.model.ObjectInstance){var link=document.createElement('tr-ui-a-analysis-link');link.selection=new tr.model.EventSet(object);this.appendElementWithLabel_(label,indent,link,suffix);return;}
+if(object instanceof tr.b.Rect){this.appendSimpleText_(label,indent,object.toString(),suffix);return;}
+if(object instanceof tr.b.u.Scalar){var el=this.ownerDocument.createElement('tr-ui-u-scalar-span');el.value=object;this.appendElementWithLabel_(label,indent,el,suffix);return;}
+if(object instanceof Array){this.appendElementsForArray_(label,object,indent,depth,maxDepth,suffix);return;}
+this.appendElementsForObject_(label,object,indent,depth,maxDepth,suffix);},appendElementsForArray_:function(label,object,indent,depth,maxDepth,suffix){if(object.length==0){this.appendSimpleText_(label,indent,'[]',suffix);return;}
+if(isTable(object)){var table=document.createElement('tr-ui-b-table');var columns=[];tr.b.iterItems(object[0],function(colName){columns.push({title:colName,value:function(row){return row[colName];}});});table.tableColumns=columns;table.tableRows=object;this.appendElementWithLabel_(label,indent,table,suffix);table.rebuild();return;}
+this.appendElementsForType_(label+'[',object[0],indent,depth+1,maxDepth,object.length>1?',':']'+suffix);for(var i=1;i<object.length;i++){this.appendElementsForType_('',object[i],indent+label.length+1,depth+1,maxDepth,i<object.length-1?',':']'+suffix);}
+return;},appendElementsForObject_:function(label,object,indent,depth,maxDepth,suffix){var keys=tr.b.dictionaryKeys(object);if(keys.length==0){this.appendSimpleText_(label,indent,'{}',suffix);return;}
+this.appendElementsForType_(label+'{'+keys[0]+': ',object[keys[0]],indent,depth,maxDepth,keys.length>1?',':'}'+suffix);for(var i=1;i<keys.length;i++){this.appendElementsForType_(keys[i]+': ',object[keys[i]],indent+label.length+1,depth+1,maxDepth,i<keys.length-1?',':'}'+suffix);}},appendElementWithLabel_:function(label,indent,dataElement,suffix){var row=document.createElement('div');var indentSpan=document.createElement('span');indentSpan.style.whiteSpace='pre';for(var i=0;i<indent;i++)
+indentSpan.textContent+=' ';row.appendChild(indentSpan);var labelSpan=document.createElement('span');labelSpan.textContent=label;row.appendChild(labelSpan);row.appendChild(dataElement);var suffixSpan=document.createElement('span');suffixSpan.textContent=suffix;row.appendChild(suffixSpan);row.dataElement=dataElement;this.$.content.appendChild(row);},appendSimpleText_:function(label,indent,text,suffix){var el=this.ownerDocument.createElement('span');el.textContent=text;this.appendElementWithLabel_(label,indent,el,suffix);return el;}});'use strict';Polymer('tr-ui-a-generic-object-view-with-label',{ready:function(){this.labelEl_=document.createElement('div');this.genericObjectView_=document.createElement('tr-ui-a-generic-object-view');this.shadowRoot.appendChild(this.labelEl_);this.shadowRoot.appendChild(this.genericObjectView_);},get label(){return this.labelEl_.textContent;},set label(label){this.labelEl_.textContent=label;},get object(){return this.genericObjectView_.object;},set object(object){this.genericObjectView_.object=object;}});'use strict';Polymer('tr-ui-a-stack-frame',{ready:function(){this.stackFrame_=undefined;this.$.table.tableColumns=[];this.$.table.showHeader=true;},get stackFrame(){return this.stackFrame_;},set stackFrame(stackFrame){var table=this.$.table;this.stackFrame_=stackFrame;if(stackFrame===undefined){table.tableColumns=[];table.tableRows=[];table.rebuild();return;}
+var hasName=false;var hasTitle=false;table.tableRows=stackFrame.stackTrace;table.tableRows.forEach(function(row){hasName|=row.name!==undefined;hasTitle|=row.title!==undefined;});var cols=[];if(hasName){cols.push({title:'Name',value:function(row){return row.name;}});}
+if(hasTitle){cols.push({title:'Title',value:function(row){return row.title;}});}
+table.tableColumns=cols;table.rebuild();},tableForTesting:function(){return this.$.table;}});'use strict';Polymer('tr-ui-a-single-event-sub-view',{ready:function(){this.currentSelection_=undefined;this.$.table.tableColumns=[{title:'Label',value:function(row){return row.name;},width:'150px'},{title:'Value',width:'100%',value:function(row){return row.value;}}];this.$.table.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1)
+throw new Error('Only supports single slices');this.setSelectionWithoutErrorChecks(selection);},setSelectionWithoutErrorChecks:function(selection){this.currentSelection_=selection;this.updateContents_();},getEventRows_:function(event){var rows=[];if(event.error)
+rows.push({name:'Error',value:event.error});if(event.title)
+rows.push({name:'Title',value:event.title});if(event.category)
+rows.push({name:'Category',value:event.category});if(event.name)
+rows.push({name:'Name',value:event.name});var startEl=document.createElement('tr-ui-u-time-stamp-span');startEl.timestamp=event.start;rows.push({name:'Start',value:startEl});if(event.duration){var wallDurationEl=document.createElement('tr-ui-u-time-duration-span');wallDurationEl.duration=event.duration;rows.push({name:'Wall Duration',value:wallDurationEl});}
+if(event.cpuDuration){var cpuDurationEl=document.createElement('tr-ui-u-time-duration-span');cpuDurationEl.duration=event.cpuDuration;rows.push({name:'CPU Duration',value:cpuDurationEl});}
+if(event.subSlices!==undefined&&event.subSlices.length!==0){if(event.selfTime){var selfTimeEl=document.createElement('tr-ui-u-time-duration-span');selfTimeEl.duration=event.selfTime;rows.push({name:'Self Time',value:selfTimeEl});}
+if(event.cpuSelfTime){var cpuSelfTimeEl=document.createElement('tr-ui-u-time-duration-span');cpuSelfTimeEl.duration=event.cpuSelfTime;if(event.cpuSelfTime>event.selfTime){cpuSelfTimeEl.warning=' Note that CPU Self Time is larger than Self Time. '+'This is a known limitation of this system, which occurs '+'due to several subslices, rounding issues, and imprecise '+'time at which we get cpu- and real-time.';}
+rows.push({name:'CPU Self Time',value:cpuSelfTimeEl});}}
+if(event.durationInUserTime){var durationInUserTimeEl=document.createElement('tr-ui-u-time-duration-span');durationInUserTimeEl.duration=event.durationInUserTime;rows.push({name:'Duration (U)',value:durationInUserTimeEl});}
+function createStackFrameEl(sf){var sfEl=document.createElement('tr-ui-a-stack-frame');sfEl.stackFrame=sf;return sfEl;}
+if(event.startStackFrame&&event.endStackFrame){if(event.startStackFrame===event.endStackFrame){rows.push({name:'Start+End Stack Trace',value:createStackFrameEl(event.startStackFrame)});}else{rows.push({name:'Start Stack Trace',value:createStackFrameEl(event.startStackFrame)});rows.push({name:'End Stack Trace',value:createStackFrameEl(event.endStackFrame)});}}else if(event.startStackFrame){rows.push({name:'Start Stack Trace',value:createStackFrameEl(event.startStackFrame)});}else if(event.endStackFrame){rows.push({name:'End Stack Trace',value:createStackFrameEl(event.endStackFrame)});}
+if(event.info){var descriptionEl=tr.ui.b.createDiv({textContent:event.info.description,maxWidth:'300px'});rows.push({name:'Description',value:descriptionEl});if(event.info.docLinks){event.info.docLinks.forEach(function(linkObject){var linkEl=document.createElement('a');linkEl.target='_blank';linkEl.href=linkObject.href;linkEl.textContent=linkObject.textContent;rows.push({name:linkObject.label,value:linkEl});});}}
+if(event.associatedAlerts.length){var alertSubRows=[];event.associatedAlerts.forEach(function(alert){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(alert);},alert.info.description);alertSubRows.push({name:alert.title,value:linkEl});});rows.push({name:'Alerts',value:'',isExpanded:true,subRows:alertSubRows});}
+return rows;},addArgsToRows_:function(rows,args){var n=0;for(var argName in args){n+=1;}
+if(n>0){var subRows=[];for(var argName in args){var argView=document.createElement('tr-ui-a-generic-object-view');argView.object=args[argName];subRows.push({name:argName,value:argView});}
+rows.push({name:'Args',value:'',isExpanded:true,subRows:subRows});}
+return rows;},updateContents_:function(){if(this.currentSelection_===undefined){this.$.table.rows=[];this.$.table.rebuild();return;}
+var event=this.currentSelection_[0];var rows=this.getEventRows_(event);if(event.argsStripped)
+rows.push({name:'Args',value:'Stripped'});else
+this.addArgsToRows_(rows,event.args);this.$.table.tableRows=rows;this.$.table.rebuild();}});'use strict';tr.exportTo('tr.ui.analysis',function(){var FLOW_IN=0x1;var FLOW_OUT=0x2;var FLOW_IN_OUT=FLOW_IN|FLOW_OUT;function FlowClassifier(){this.numEvents_=0;this.eventsByGUID_={};}
+FlowClassifier.prototype={getFS_:function(event){var fs=this.eventsByGUID_[event.guid];if(fs===undefined){this.numEvents_++;fs={state:0,event:event};this.eventsByGUID_[event.guid]=fs;}
+return fs;},addInFlow:function(event){var fs=this.getFS_(event);fs.state|=FLOW_IN;return event;},addOutFlow:function(event){var fs=this.getFS_(event);fs.state|=FLOW_OUT;return event;},hasEvents:function(){return this.numEvents_>0;},get inFlowEvents(){var selection=new tr.model.EventSet();for(var guid in this.eventsByGUID_){var fs=this.eventsByGUID_[guid];if(fs.state===FLOW_IN)
+selection.push(fs.event);}
+return selection;},get outFlowEvents(){var selection=new tr.model.EventSet();for(var guid in this.eventsByGUID_){var fs=this.eventsByGUID_[guid];if(fs.state===FLOW_OUT)
+selection.push(fs.event);}
+return selection;},get internalFlowEvents(){var selection=new tr.model.EventSet();for(var guid in this.eventsByGUID_){var fs=this.eventsByGUID_[guid];if(fs.state===FLOW_IN_OUT)
+selection.push(fs.event);}
+return selection;}};return{FlowClassifier:FlowClassifier};});'use strict';Polymer('tr-ui-a-related-events',{ready:function(){this.eventGroups_=[];this.cancelFunctions_=[];this.$.table.tableColumns=[{title:'Event(s)',value:function(row){var typeEl=document.createElement('span');typeEl.innerText=row.type;if(row.tooltip)
+typeEl.title=row.tooltip;return typeEl;},width:'150px'},{title:'Link',width:'100%',value:function(row){var linkEl=document.createElement('tr-ui-a-analysis-link');if(row.name)
+linkEl.setSelectionAndContent(row.selection,row.name);else
+linkEl.selection=row.selection;return linkEl;}}];},hasRelatedEvents:function(){return(this.eventGroups_&&this.eventGroups_.length>0);},setRelatedEvents:function(eventSet){this.cancelAllTasks_();this.eventGroups_=[];this.addConnectedFlows_(eventSet);this.addConnectedEvents_(eventSet);this.addOverlappingSamples_(eventSet);this.updateContents_();},addConnectedFlows_:function(eventSet){var classifier=new tr.ui.analysis.FlowClassifier();eventSet.forEach(function(slice){if(slice.inFlowEvents){slice.inFlowEvents.forEach(function(flow){classifier.addInFlow(flow);});}
+if(slice.outFlowEvents){slice.outFlowEvents.forEach(function(flow){classifier.addOutFlow(flow);});}});if(!classifier.hasEvents())
+return;var addToEventGroups=function(type,flowEvent){this.eventGroups_.push({type:type,selection:new tr.model.EventSet(flowEvent),name:flowEvent.title});};classifier.inFlowEvents.forEach(addToEventGroups.bind(this,'Incoming flow'));classifier.outFlowEvents.forEach(addToEventGroups.bind(this,'Outgoing flow'));classifier.internalFlowEvents.forEach(addToEventGroups.bind(this,'Internal flow'));},cancelAllTasks_:function(){this.cancelFunctions_.forEach(function(cancelFunction){cancelFunction();});this.cancelFunctions_=[];},addConnectedEvents_:function(eventSet){this.cancelFunctions_.push(this.createEventsLinkIfNeeded_('Preceding events','Add all events that have led to the selected one(s), connected by '+'flow arrows or by call stack.',eventSet,function(event,events){this.addInFlowEvents_(event,events);this.addAncestors_(event,events);if(event.startSlice)
+events.push(event.startSlice);}.bind(this)));this.cancelFunctions_.push(this.createEventsLinkIfNeeded_('Following events','Add all events that have been caused by the selected one(s), '+'connected by flow arrows or by call stack.',eventSet,function(event,events){this.addOutFlowEvents_(event,events);this.addDescendents_(event,events);if(event.endSlice)
+events.push(event.endSlice);}.bind(this)));this.cancelFunctions_.push(this.createEventsLinkIfNeeded_('All connected events','Add all events connected to the selected one(s) by flow arrows or '+'by call stack.',eventSet,function(event,events){this.addInFlowEvents_(event,events);this.addOutFlowEvents_(event,events);this.addAncestors_(event,events);this.addDescendents_(event,events);if(event.startSlice)
+events.push(event.startSlice);if(event.endSlice)
+events.push(event.endSlice);}.bind(this)));},createEventsLinkIfNeeded_:function(title,tooltip,events,addFunction){events=new tr.model.EventSet(events);var lengthBefore=events.length;var task;var isCanceled=false;function addEventsUntilTimeout(startingIndex){if(isCanceled)
+return;var startingTime=window.performance.now();while(startingIndex<events.length){addFunction(events[startingIndex],events);startingIndex++;if(window.performance.now()-startingTime>8){var newTask=new tr.b.Task(addEventsUntilTimeout.bind(this,startingIndex),this);task.after(newTask);task=newTask;return;}}
+if(lengthBefore===events.length)
+return;this.eventGroups_.push({type:title,tooltip:tooltip,selection:events});this.updateContents_();};function cancelTask(){isCanceled=true;}
+task=new tr.b.Task(addEventsUntilTimeout.bind(this,0),this);tr.b.Task.RunWhenIdle(task);return cancelTask;},addInFlowEvents_:function(event,eventSet){if(!event.inFlowEvents)
+return;event.inFlowEvents.forEach(function(e){eventSet.push(e);});},addOutFlowEvents_:function(event,eventSet){if(!event.outFlowEvents)
+return;event.outFlowEvents.forEach(function(e){eventSet.push(e);});},addAncestors_:function(event,eventSet){if(!event.iterateAllAncestors)
+return;event.iterateAllAncestors(function(e){eventSet.push(e);});},addDescendents_:function(event,eventSet){if(!event.iterateAllDescendents)
+return;event.iterateAllDescendents(function(e){eventSet.push(e);});},addOverlappingSamples_:function(eventSet){var samples=new tr.model.EventSet;eventSet.forEach(function(slice){if(!slice.parentContainer||!slice.parentContainer.samples)
+return;var candidates=slice.parentContainer.samples;var range=tr.b.Range.fromExplicitRange(slice.start,slice.start+slice.duration);var filteredSamples=range.filterArray(candidates,function(value){return value.start;});filteredSamples.forEach(function(sample){samples.push(sample);});}.bind(this));if(samples.length>0){this.eventGroups_.push({type:'Overlapping samples',tooltip:'All samples overlapping the selected slice(s).',selection:samples});}},updateContents_:function(){var table=this.$.table;if(this.eventGroups_===undefined)
+table.tableRows=[];else
+table.tableRows=this.eventGroups_.slice();table.rebuild();}});'use strict';Polymer('tr-ui-a-single-thread-slice-sub-view',{get selection(){return this.$.content.selection;},set selection(selection){this.$.content.selection=selection;this.$.relatedEvents.setRelatedEvents(selection);if(this.$.relatedEvents.hasRelatedEvents())
+this.$.relatedEvents.style.display='';else
+this.$.relatedEvents.style.display='none';}});'use strict';Polymer('tr-ui-a-selection-summary-table',{created:function(){this.selection_=new tr.b.Range();},ready:function(){this.$.table.showHeader=false;this.$.table.tableColumns=[{title:'Name',value:function(row){return row.title;},width:'350px'},{title:'Value',width:'100%',value:function(row){return row.value;}}];},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;this.updateContents_();},updateContents_:function(){var selection=this.selection_;var rows=[];var hasRange;if(this.selection_&&(!selection.bounds.isEmpty))
+hasRange=true;else
+hasRange=false;var timeSpanConfig={ownerDocument:this.ownerDocument};rows.push({title:'Selection start',value:hasRange?tr.ui.units.createTimeStampSpan(selection.bounds.min,timeSpanConfig):'<empty>'});rows.push({title:'Selection extent',value:hasRange?tr.ui.units.createTimeDurationSpan(selection.bounds.range,timeSpanConfig):'<empty>'});this.$.table.tableRows=rows;this.$.table.rebuild();}});'use strict';tr.exportTo('tr.ui.analysis',function(){function MultiEventSummary(title,events){this.title=title;this.duration_=undefined;this.selfTime_=undefined;this.events_=events;this.cpuTimesComputed_=false;this.cpuSelfTime_=undefined;this.cpuDuration_=undefined;this.maxDuration_=undefined;this.maxCpuDuration_=undefined;this.maxSelfTime_=undefined;this.maxCpuSelfTime_=undefined;this.untotallableArgs_=[];this.totalledArgs_=undefined;};MultiEventSummary.prototype={set title(title){if(title=='Totals')
+this.totalsRow=true;this.title_=title;},get title(){return this.title_;},get duration(){if(this.duration_===undefined){this.duration_=tr.b.Statistics.sum(this.events_,function(event){return event.duration;});}
+return this.duration_;},get cpuSelfTime(){this.computeCpuTimesIfNeeded_();return this.cpuSelfTime_;},get cpuDuration(){this.computeCpuTimesIfNeeded_();return this.cpuDuration_;},computeCpuTimesIfNeeded_:function(){if(this.cpuTimesComputed_)
+return;this.cpuTimesComputed_=true;var cpuSelfTime=0;var cpuDuration=0;var hasCpuData=false;for(var i=0;i<this.events_.length;i++){var event=this.events_[i];if(event.cpuDuration!==undefined){cpuDuration+=event.cpuDuration;hasCpuData=true;}
+if(event.cpuSelfTime!==undefined){cpuSelfTime+=event.cpuSelfTime;hasCpuData=true;}}
+if(hasCpuData){this.cpuDuration_=cpuDuration;this.cpuSelfTime_=cpuSelfTime;}},get selfTime(){if(this.selfTime_===undefined){this.selfTime_=0;for(var i=0;i<this.events_.length;i++){if(this.events_[i].selfTime!==undefined)
+this.selfTime_+=this.events[i].selfTime;}}
+return this.selfTime_;},get events(){return this.events_;},get numEvents(){return this.events_.length;},get numAlerts(){if(this.numAlerts_===undefined){this.numAlerts_=tr.b.Statistics.sum(this.events_,function(event){return event.associatedAlerts.length;});}
+return this.numAlerts_;},get untotallableArgs(){this.updateArgsIfNeeded_();return this.untotallableArgs_;},get totalledArgs(){this.updateArgsIfNeeded_();return this.totalledArgs_;},get maxDuration(){if(this.maxDuration_===undefined){this.maxDuration_=tr.b.Statistics.max(this.events_,function(event){return event.duration;});}
+return this.maxDuration_;},get maxCpuDuration(){if(this.maxCpuDuration_===undefined){this.maxCpuDuration_=tr.b.Statistics.max(this.events_,function(event){return event.cpuDuration;});}
+return this.maxCpuDuration_;},get maxSelfTime(){if(this.maxSelfTime_===undefined){this.maxSelfTime_=tr.b.Statistics.max(this.events_,function(event){return event.selfTime;});}
+return this.maxSelfTime_;},get maxCpuSelfTime(){if(this.maxCpuSelfTime_===undefined){this.maxCpuSelfTime_=tr.b.Statistics.max(this.events_,function(event){return event.cpuSelfTime;});}
+return this.maxCpuSelfTime_;},updateArgsIfNeeded_:function(){if(this.totalledArgs_!==undefined)
+return;var untotallableArgs={};var totalledArgs={};for(var i=0;i<this.events_.length;i++){var event=this.events_[i];for(var argName in event.args){var argVal=event.args[argName];var type=typeof argVal;if(type!=='number'){untotallableArgs[argName]=true;delete totalledArgs[argName];continue;}
+if(untotallableArgs[argName]){continue;}
+if(totalledArgs[argName]===undefined)
+totalledArgs[argName]=0;totalledArgs[argName]+=argVal;}}
+this.untotallableArgs_=tr.b.dictionaryKeys(untotallableArgs);this.totalledArgs_=totalledArgs;}};return{MultiEventSummary:MultiEventSummary};});'use strict';Polymer('tr-ui-a-multi-event-summary-table',{ready:function(){this.showTotals_=false;this.eventsHaveDuration_=true;this.eventsHaveSubRows_=true;this.eventsByTitle_=undefined;},updateTableColumns_:function(rows,maxValues){var hasCpuData=false;var hasAlerts=false;rows.forEach(function(row){if(row.cpuDuration!==undefined)
+hasCpuData=true;if(row.cpuSelfTime!==undefined)
+hasCpuData=true;if(row.numAlerts)
+hasAlerts=true;});var ownerDocument=this.ownerDocument;var columns=[];columns.push({title:'Name',value:function(row){if(row.title==='Totals')
+return'Totals';var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(row.events);},row.title);return linkEl;},width:'350px',cmp:function(rowA,rowB){return rowA.title.localeCompare(rowB.title);}});if(this.eventsHaveDuration_){columns.push({title:'Wall Duration',value:function(row){return tr.ui.units.createTimeDurationSpan(row.duration,{total:row.totalsRow?undefined:maxValues.duration,ownerDocument:ownerDocument,rightAlign:true});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.duration-rowB.duration;}});}
+if(this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Duration',value:function(row){return tr.ui.units.createTimeDurationSpan(row.cpuDuration,{total:row.totalsRow?undefined:maxValues.cpuDuration,ownerDocument:ownerDocument,rightAlign:true});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.cpuDuration-rowB.cpuDuration;}});}
+if(this.eventsHaveSubRows_&&this.eventsHaveDuration_){columns.push({title:'Self time',value:function(row){return tr.ui.units.createTimeDurationSpan(row.selfTime,{total:row.totalsRow?undefined:maxValues.selfTime,ownerDocument:ownerDocument,rightAlign:true});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.selfTime-rowB.selfTime;}});}
+if(this.eventsHaveSubRows_&&this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Self Time',value:function(row){return tr.ui.units.createTimeDurationSpan(row.cpuSelfTime,{total:row.totalsRow?undefined:maxValues.cpuSelfTime,ownerDocument:ownerDocument,rightAlign:true});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.cpuSelfTime-rowB.cpuSelfTime;}});}
+columns.push({title:'Occurrences',value:function(row){return row.numEvents;},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.numEvents-rowB.numEvents;}});var alertsColumnIndex;if(hasAlerts){columns.push({title:'Num Alerts',value:function(row){return row.numAlerts;},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.numAlerts-rowB.numAlerts;}});alertsColumnIndex=columns.length-1;}
+var colWidthPercentage;if(columns.length==1)
+colWidthPercentage='100%';else
+colWidthPercentage=(100/(columns.length-1)).toFixed(3)+'%';for(var i=1;i<columns.length;i++)
+columns[i].width=colWidthPercentage;this.$.table.tableColumns=columns;if(hasAlerts){this.$.table.sortColumnIndex=alertsColumnIndex;this.$.table.sortDescending=true;}},configure:function(config){if(config.eventsByTitle===undefined)
+throw new Error('Required: eventsByTitle');if(config.showTotals!==undefined)
+this.showTotals_=config.showTotals;else
+this.showTotals_=true;if(config.eventsHaveDuration!==undefined)
+this.eventsHaveDuration_=config.eventsHaveDuration;else
+this.eventsHaveDuration_=true;if(config.eventsHaveSubRows!==undefined)
+this.eventsHaveSubRows_=config.eventsHaveSubRows;else
+this.eventsHaveSubRows_=true;this.eventsByTitle_=config.eventsByTitle;this.updateContents_();},get showTotals(){return this.showTotals_;},set showTotals(showTotals){this.showTotals_=showTotals;this.updateContents_();},get eventsHaveDuration(){return this.eventsHaveDuration_;},set eventsHaveDuration(eventsHaveDuration){this.eventsHaveDuration_=eventsHaveDuration;this.updateContents_();},get eventsHaveSubRows(){return this.eventsHaveSubRows_;},set eventsHaveSubRows(eventsHaveSubRows){this.eventsHaveSubRows_=eventsHaveSubRows;this.updateContents_();},get eventsByTitle(){return this.eventsByTitle_;},set eventsByTitle(eventsByTitle){this.eventsByTitle_=eventsByTitle;this.updateContents_();},get selectionBounds(){return this.selectionBounds_;},set selectionBounds(selectionBounds){this.selectionBounds_=selectionBounds;this.updateContents_();},updateContents_:function(){var eventsByTitle;if(this.eventsByTitle_!==undefined)
+eventsByTitle=this.eventsByTitle_;else
+eventsByTitle=[];var allEvents=[];var rows=[];tr.b.iterItems(eventsByTitle,function(title,eventsOfSingleTitle){allEvents.push.apply(allEvents,eventsOfSingleTitle);var row=new tr.ui.analysis.MultiEventSummary(title,eventsOfSingleTitle);rows.push(row);});this.updateTableColumns_(rows);this.$.table.tableRows=rows;var maxValues={duration:undefined,selfTime:undefined,cpuSelfTime:undefined,cpuDuration:undefined};if(this.eventsHaveDuration){for(var column in maxValues){maxValues[column]=tr.b.Statistics.max(rows,function(event){return event[column];});}}
+var footerRows=[];if(this.showTotals_){var multiEventSummary=new tr.ui.analysis.MultiEventSummary('Totals',allEvents);footerRows.push(multiEventSummary);}
+this.updateTableColumns_(rows,maxValues);this.$.table.tableRows=rows;this.$.table.footerRows=footerRows;this.$.table.rebuild();}});'use strict';Polymer('tr-ui-a-multi-event-details-table',{created:function(){this.selection_=undefined;this.eventsHaveDuration_=true;this.eventsHaveSubRows_=true;},ready:function(){this.initTitleTable_();},get eventsHaveDuration(){return this.eventsHaveDuration_;},set eventsHaveDuration(eventsHaveDuration){this.eventsHaveDuration_=eventsHaveDuration;this.updateContents_();},get eventsHaveSubRows(){return this.eventsHaveSubRows_;},set eventsHaveSubRows(eventsHaveSubRows){this.eventsHaveSubRows_=eventsHaveSubRows;this.updateContents_();},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;this.updateContents_();},updateContents_:function(){var selection=this.selection_;this.updateTitleTable_();if(this.selection_===undefined){this.$.table.tableRows=[];this.$.table.tableFooterRows=[];this.$.table.rebuild();return;}
+var summary=new tr.ui.analysis.MultiEventSummary('Totals',this.selection_);this.updateColumns_(summary);this.updateRows_(summary);this.$.table.rebuild();},initTitleTable_:function(){var table=this.$.titletable;table.showHeader=false;table.tableColumns=[{title:'Title',value:function(row){return row.title;},width:'350px'},{title:'Value',width:'100%',value:function(row){return row.value;}}];},updateTitleTable_:function(){var title;if(this.selection_&&this.selection_.length)
+title=this.selection_[0].title;else
+title='<No selection>';var table=this.$.titletable;table.tableRows=[{title:'Title',value:title}];},updateColumns_:function(summary){var hasCpuData;if(summary.cpuDuration!==undefined)
+hasCpuData=true;if(summary.cpuSelfTime!==undefined)
+hasCpuData=true;var colWidthPercentage;if(hasCpuData)
+colWidthPercentage='20%';else
+colWidthPercentage='33.3333%';var timeSpanConfig={ownerDocument:this.ownerDocument};var columns=[];columns.push({title:'Start',value:function(row){if(row.__proto__===tr.ui.analysis.MultiEventSummary.prototype){return row.title;}
+var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(row.event);});linkEl.appendChild(tr.ui.units.createTimeStampSpan(row.start,timeSpanConfig));return linkEl;},width:'350px',cmp:function(rowA,rowB){return rowA.start-rowB.start;}});if(this.eventsHaveDuration_){columns.push({title:'Wall Duration (ms)',value:function(row){return tr.ui.units.createTimeDurationSpan(row.duration,timeSpanConfig);},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.duration-rowB.duration;}});}
+if(this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Duration (ms)',value:function(row){return tr.ui.units.createTimeDurationSpan(row.cpuDuration,timeSpanConfig);},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.cpuDuration-rowB.cpuDuration;}});}
+if(this.eventsHaveSubRows_&&this.eventsHaveDuration_){columns.push({title:'Self time (ms)',value:function(row){return tr.ui.units.createTimeDurationSpan(row.selfTime,timeSpanConfig);},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.selfTime-rowB.selfTime;}});}
+if(this.eventsHaveSubRows_&&this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Self Time (ms)',value:function(row){return tr.ui.units.createTimeDurationSpan(row.cpuSelfTime,timeSpanConfig);},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.cpuSelfTime-rowB.cpuSelfTime;}});}
+var argKeys=tr.b.dictionaryKeys(summary.totalledArgs);argKeys.sort();var otherKeys=summary.untotallableArgs.slice(0);otherKeys.sort();argKeys.push.apply(argKeys,otherKeys);var keysWithColumns=argKeys.slice(0,4);var keysInOtherColumn=argKeys.slice(4);keysWithColumns.forEach(function(argKey){var hasTotal=summary.totalledArgs[argKey];var colDesc={title:'Arg: '+argKey,value:function(row){if(row.__proto__!==tr.ui.analysis.MultiEventSummary.prototype){var argView=document.createElement('tr-ui-a-generic-object-view');argView.object=row.args[argKey];return argView;}
+if(hasTotal)
+return row.totalledArgs[argKey];return'';},width:'<upated further down>'};if(hasTotal){colDesc.cmp=function(rowA,rowB){return rowA.args[argKey]-rowB.args[argKey];}}
+columns.push(colDesc);});if(keysInOtherColumn.length){columns.push({title:'Other Args',value:function(row){if(row.__proto__===tr.ui.analysis.MultiEventSummary.prototype)
+return'';var argView=document.createElement('tr-ui-a-generic-object-view');var obj={};for(var i=0;i<keysInOtherColumn.length;i++)
+obj[keysInOtherColumn[i]]=row.args[keysInOtherColumn[i]];argView.object=obj;return argView;},width:'<upated further down>'});}
+var colWidthPercentage;if(columns.length==1)
+colWidthPercentage='100%';else
+colWidthPercentage=(100/(columns.length-1)).toFixed(3)+'%';for(var i=1;i<columns.length;i++)
+columns[i].width=colWidthPercentage;this.$.table.tableColumns=columns;},updateRows_:function(summary){this.$.table.sortColumnIndex=0;function Row(event){this.event=event;}
+Row.prototype={get start(){return this.event.start;},get duration(){return this.event.duration;},get cpuDuration(){return this.event.cpuDuration;},get selfTime(){return this.event.selfTime;},get cpuSelfTime(){return this.event.cpuSelfTime;},get args(){return this.event.args;}};this.$.table.tableRows=this.selection_.map(function(event){return new Row(event);});this.$.table.footerRows=[summary];}});'use strict';Polymer('tr-ui-a-multi-event-sub-view',{created:function(){this.currentSelection_=undefined;this.eventsHaveDuration_=true;this.eventsHaveSubRows_=true;},set selection(selection){if(selection.length<=1)
+throw new Error('Only supports multiple items');this.setSelectionWithoutErrorChecks(selection);},get selection(){return this.currentSelection_;},setSelectionWithoutErrorChecks:function(selection){this.currentSelection_=selection;this.updateContents_();},get eventsHaveDuration(){return this.eventsHaveDuration_;},set eventsHaveDuration(eventsHaveDuration){this.eventsHaveDuration_=eventsHaveDuration;this.updateContents_();},get eventsHaveSubRows(){return this.eventsHaveSubRows_;},set eventsHaveSubRows(eventsHaveSubRows){this.eventsHaveSubRows_=eventsHaveSubRows;this.updateContents_();},updateContents_:function(){var selection=this.currentSelection_;this.$.content.textContent='';if(!selection)
+return;var eventsByTitle=selection.getEventsOrganizedByTitle();var numTitles=tr.b.dictionaryLength(eventsByTitle);var summaryTableEl=document.createElement('tr-ui-a-multi-event-summary-table');summaryTableEl.configure({showTotals:numTitles>1,eventsByTitle:eventsByTitle,eventsHaveDuration:this.eventsHaveDuration_,eventsHaveSubRows:this.eventsHaveSubRows_});this.$.content.appendChild(summaryTableEl);var selectionSummaryTableEl=document.createElement('tr-ui-a-selection-summary-table');selectionSummaryTableEl.selection=this.currentSelection_;this.$.content.appendChild(selectionSummaryTableEl);if(numTitles===1){var detailsTableEl=document.createElement('tr-ui-a-multi-event-details-table');detailsTableEl.eventsHaveDuration=this.eventsHaveDuration_;detailsTableEl.eventsHaveSubRows=this.eventsHaveSubRows_;detailsTableEl.selection=selection;this.$.content.appendChild(detailsTableEl);}}});'use strict';Polymer('tr-ui-a-multi-thread-slice-sub-view',{created:function(){this.selection_=undefined;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;if(tr.isExported('tr.ui.e.chrome.cc.RasterTaskSelection')){if(tr.ui.e.chrome.cc.RasterTaskSelection.supports(selection)){var ltvSelection=new tr.ui.e.chrome.cc.RasterTaskSelection(selection);var ltv=new tr.ui.e.chrome.cc.LayerTreeHostImplSnapshotView();ltv.objectSnapshot=ltvSelection.containingSnapshot;ltv.selection=ltvSelection;ltv.extraHighlightsByLayerId=ltvSelection.extraHighlightsByLayerId;this.$.content.textContent='';this.$.content.appendChild(ltv);this.requiresTallView_=true;return;}}
+this.$.content.textContent='';var mesv=document.createElement('tr-ui-a-multi-event-sub-view');mesv.selection=selection;this.$.content.appendChild(mesv);var relatedEvents=document.createElement('tr-ui-a-related-events');relatedEvents.setRelatedEvents(selection);if(relatedEvents.hasRelatedEvents()){this.$.content.appendChild(relatedEvents);}},get requiresTallView(){if(this.$.content.children.length===0)
+return false;var childTagName=this.$.content.children[0].tagName;if(childTagName==='TR-UI-A-MULTI-EVENT-SUB-VIEW')
+return false;return true;}});'use strict';Polymer('tr-ui-a-single-async-slice-sub-view',{getEventRows_:function(event){var rows=this.__proto__.__proto__.getEventRows_(event);rows.splice(0,0,{name:'ID',value:event.id});return rows;},get relatedEventsToHighlight(){if(!this.currentSelection_)
+return undefined;return this.currentSelection_[0].associatedEvents;}});'use strict';Polymer('tr-ui-a-multi-async-slice-sub-view',{get selection(){return this.$.content.selection;},set selection(selection){this.$.content.selection=selection;},get relatedEventsToHighlight(){if(!this.$.content.selection)
+return undefined;var selection=new tr.model.EventSet();this.$.content.selection.forEach(function(asyncEvent){if(!asyncEvent.associatedEvents)
+return;asyncEvent.associatedEvents.forEach(function(event){selection.push(event);});});if(selection.length)
+return selection;return undefined;}});'use strict';Polymer('tr-ui-a-single-cpu-slice-sub-view',{created:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1)
+throw new Error('Only supports single slices');if(!(selection[0]instanceof tr.model.CpuSlice))
+throw new Error('Only supports thread time slices');this.currentSelection_=selection;var cpuSlice=selection[0];var thread=cpuSlice.threadThatWasRunning;var shadowRoot=this.shadowRoot;if(thread){shadowRoot.querySelector('#process-name').textContent=thread.parent.userFriendlyName;shadowRoot.querySelector('#thread-name').textContent=thread.userFriendlyName;}else{shadowRoot.querySelector('#process-name').parentElement.style.display='none';shadowRoot.querySelector('#thread-name').textContent=cpuSlice.title;}
+shadowRoot.querySelector('#start').timestamp=cpuSlice.start;shadowRoot.querySelector('#duration').duration=cpuSlice.duration;var runningThreadEl=shadowRoot.querySelector('#running-thread');var timeSlice=cpuSlice.getAssociatedTimeslice();if(!timeSlice){runningThreadEl.parentElement.style.display='none';}else{var threadLink=document.createElement('tr-ui-a-analysis-link');threadLink.selection=new tr.model.EventSet(timeSlice);threadLink.textContent='Click to select';runningThreadEl.parentElement.style.display='';runningThreadEl.textContent='';runningThreadEl.appendChild(threadLink);}
+shadowRoot.querySelector('#args').object=cpuSlice.args;}});'use strict';Polymer('tr-ui-a-multi-cpu-slice-sub-view',{ready:function(){this.$.content.eventsHaveSubRows=false;},get selection(){return this.$.content.selection;},set selection(selection){this.$.content.setSelectionWithoutErrorChecks(selection);}});'use strict';Polymer('tr-ui-a-single-thread-time-slice-sub-view',{created:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1)
+throw new Error('Only supports single slices');if(!(selection[0]instanceof tr.model.ThreadTimeSlice))
+throw new Error('Only supports thread time slices');this.currentSelection_=selection;var timeSlice=selection[0];var thread=timeSlice.thread;var shadowRoot=this.shadowRoot;shadowRoot.querySelector('#state').textContent=timeSlice.title;var stateColor=tr.b.ColorScheme.colorsAsStrings[timeSlice.colorId];shadowRoot.querySelector('#state').style.backgroundColor=stateColor;shadowRoot.querySelector('#process-name').textContent=thread.parent.userFriendlyName;shadowRoot.querySelector('#thread-name').textContent=thread.userFriendlyName;shadowRoot.querySelector('#start').timestamp=timeSlice.start;shadowRoot.querySelector('#duration').duration=timeSlice.duration;var onCpuEl=shadowRoot.querySelector('#on-cpu');onCpuEl.textContent='';var runningInsteadEl=shadowRoot.querySelector('#running-instead');if(timeSlice.cpuOnWhichThreadWasRunning){runningInsteadEl.parentElement.removeChild(runningInsteadEl);var cpuLink=document.createElement('tr-ui-a-analysis-link');cpuLink.selection=new tr.model.EventSet(timeSlice.getAssociatedCpuSlice());cpuLink.textContent=timeSlice.cpuOnWhichThreadWasRunning.userFriendlyName;onCpuEl.appendChild(cpuLink);}else{onCpuEl.parentElement.removeChild(onCpuEl);var cpuSliceThatTookCpu=timeSlice.getCpuSliceThatTookCpu();if(cpuSliceThatTookCpu){var cpuLink=document.createElement('tr-ui-a-analysis-link');cpuLink.selection=new tr.model.EventSet(cpuSliceThatTookCpu);if(cpuSliceThatTookCpu.thread)
+cpuLink.textContent=cpuSliceThatTookCpu.thread.userFriendlyName;else
+cpuLink.textContent=cpuSliceThatTookCpu.title;runningInsteadEl.appendChild(cpuLink);}else{runningInsteadEl.parentElement.removeChild(runningInsteadEl);}}
+var argsEl=shadowRoot.querySelector('#args');if(tr.b.dictionaryKeys(timeSlice.args).length>0){var argsView=document.createElement('tr-ui-a-generic-object-view');argsView.object=timeSlice.args;argsEl.parentElement.style.display='';argsEl.textContent='';argsEl.appendChild(argsView);}else{argsEl.parentElement.style.display='none';}}});'use strict';Polymer('tr-ui-a-multi-thread-time-slice-sub-view',{ready:function(){this.$.content.eventsHaveSubRows=false;},get selection(){return this.$.content.selection;},set selection(selection){this.$.content.setSelectionWithoutErrorChecks(selection);}});'use strict';Polymer('tr-ui-a-single-instant-event-sub-view',{created:function(){this.currentSelection_=undefined;},set selection(selection){this.$.content.textContent='';var realView=document.createElement('tr-ui-a-single-event-sub-view');realView.setSelectionWithoutErrorChecks(selection);this.$.content.appendChild(realView);this.currentSelection_=selection;},get selection(){return this.currentSelection_;}});'use strict';Polymer('tr-ui-a-multi-instant-event-sub-view',{created:function(){this.currentSelection_=undefined;},set selection(selection){this.$.content.textContent='';var realView=document.createElement('tr-ui-a-multi-event-sub-view');realView.eventsHaveDuration=false;realView.eventsHaveSubRows=false;this.$.content.appendChild(realView);realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;},get selection(){return this.currentSelection_;}});'use strict';(function(){var COUNTER_SAMPLE_TABLE_COLUMNS=[{title:'Counter',width:'150px',value:function(row){return row.counter;}},{title:'Series',width:'150px',value:function(row){return row.series;}},{title:'Time',width:'150px',value:function(row){return row.start;}},{title:'Value',width:'100%',value:function(row){return row.value;}}];Polymer('tr-ui-a-counter-sample-sub-view',{ready:function(){this.currentSelection_=undefined;this.$.table.tableColumns=COUNTER_SAMPLE_TABLE_COLUMNS;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},updateContents_:function(){this.$.table.tableRows=this.selection?this.getRows_(this.selection.toArray()):[];this.$.table.rebuild();},getRows_:function(samples){var samplesByCounter=tr.b.group(samples,function(sample){return sample.series.counter.guid;});var rows=[];tr.b.iterItems(samplesByCounter,function(unused,counterSamples){var samplesBySeries=tr.b.group(counterSamples,function(sample){return sample.series.guid;});tr.b.iterItems(samplesBySeries,function(unused,seriesSamples){var seriesRows=this.getRowsForSamples_(seriesSamples);seriesRows[0].counter=seriesSamples[0].series.counter.name;seriesRows[0].series=seriesSamples[0].series.name;if(seriesRows.length>1){seriesRows[0].subRows=seriesRows.slice(1);seriesRows[0].isExpanded=true;}
+rows.push(seriesRows[0]);},this);},this);return rows;},getRowsForSamples_:function(samples){return samples.map(function(sample){return{start:sample.timestamp,value:sample.value};});}});})();'use strict';Polymer('tr-ui-a-single-flow-event-sub-view',{getEventRows_:function(event){var rows=this.__proto__.__proto__.getEventRows_(event);rows.splice(0,0,{name:'ID',value:event.id});function createLinkTo(slice){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(slice);});linkEl.textContent=slice.userFriendlyName;return linkEl;}
+rows.push({name:'From',value:createLinkTo(event.startSlice)});rows.push({name:'To',value:createLinkTo(event.endSlice)});return rows;}});'use strict';Polymer('tr-ui-a-multi-flow-event-sub-view',{ready:function(){this.$.content.eventsHaveDuration=false;this.$.content.eventsHaveSubRows=false;},set selection(selection){this.$.content.selection=selection;},get selection(){return this.$.content.selection;}});'use strict';tr.exportTo('tr.ui.analysis',function(){var ObjectInstanceView=tr.ui.b.define('object-instance-view');ObjectInstanceView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.objectInstance_=undefined;},get requiresTallView(){return true;},set modelEvent(obj){this.objectInstance=obj;},get modelEvent(){return this.objectInstance;},get objectInstance(){return this.objectInstance_;},set objectInstance(i){this.objectInstance_=i;this.updateContents();},updateContents:function(){throw new Error('Not implemented');}};var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectInstanceView;options.defaultMetadata={showInTrackView:true};tr.b.decorateExtensionRegistry(ObjectInstanceView,options);return{ObjectInstanceView:ObjectInstanceView};});'use strict';Polymer('tr-ui-a-single-object-instance-sub-view',{created:function(){this.currentSelection_=undefined;},get requiresTallView(){if(this.$.content.children.length===0)
+return false;if(this.$.content.children[0]instanceof
+tr.ui.analysis.ObjectInstanceView)
+return this.$.content.children[0].requiresTallView;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1)
+throw new Error('Only supports single item selections');if(!(selection[0]instanceof tr.model.ObjectInstance))
+throw new Error('Only supports object instances');this.$.content.textContent='';this.currentSelection_=selection;var instance=selection[0];var typeInfo=tr.ui.analysis.ObjectInstanceView.getTypeInfo(instance.category,instance.typeName);if(typeInfo){var customView=new typeInfo.constructor();this.$.content.appendChild(customView);customView.modelEvent=instance;}else{this.appendGenericAnalysis_(instance);}},appendGenericAnalysis_:function(instance){var html='';html+='<div class="title">'+
+instance.typeName+' '+
+instance.id+'</div>\n';html+='<table>';html+='<tr>';html+='<tr><td>creationTs:</td><td>'+
+instance.creationTs+'</td></tr>\n';if(instance.deletionTs!=Number.MAX_VALUE){html+='<tr><td>deletionTs:</td><td>'+
+instance.deletionTs+'</td></tr>\n';}else{html+='<tr><td>deletionTs:</td><td>not deleted</td></tr>\n';}
+html+='<tr><td>snapshots:</td><td id="snapshots"></td></tr>\n';html+='</table>';this.$.content.innerHTML=html;var snapshotsEl=this.$.content.querySelector('#snapshots');instance.snapshots.forEach(function(snapshot){var snapshotLink=document.createElement('tr-ui-a-analysis-link');snapshotLink.selection=new tr.model.EventSet(snapshot);snapshotsEl.appendChild(snapshotLink);});}});'use strict';tr.exportTo('tr.ui.analysis',function(){var ObjectSnapshotView=tr.ui.b.define('object-snapshot-view');ObjectSnapshotView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.objectSnapshot_=undefined;},get requiresTallView(){return true;},set modelEvent(obj){this.objectSnapshot=obj;},get modelEvent(){return this.objectSnapshot;},get objectSnapshot(){return this.objectSnapshot_;},set objectSnapshot(i){this.objectSnapshot_=i;this.updateContents();},updateContents:function(){throw new Error('Not implemented');}};var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectSnapshotView;options.defaultMetadata={showInstances:true,showInTrackView:true};tr.b.decorateExtensionRegistry(ObjectSnapshotView,options);return{ObjectSnapshotView:ObjectSnapshotView};});'use strict';Polymer('tr-ui-a-single-object-snapshot-sub-view',{created:function(){this.currentSelection_=undefined;},get requiresTallView(){if(this.children.length===0)
+return false;if(this.children[0]instanceof tr.ui.analysis.ObjectSnapshotView)
+return this.children[0].requiresTallView;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1)
+throw new Error('Only supports single item selections');if(!(selection[0]instanceof tr.model.ObjectSnapshot))
+throw new Error('Only supports object instances');this.textContent='';this.currentSelection_=selection;var snapshot=selection[0];var typeInfo=tr.ui.analysis.ObjectSnapshotView.getTypeInfo(snapshot.objectInstance.category,snapshot.objectInstance.typeName);if(typeInfo){var customView=new typeInfo.constructor();this.appendChild(customView);customView.modelEvent=snapshot;}else{this.appendGenericAnalysis_(snapshot);}},appendGenericAnalysis_:function(snapshot){var instance=snapshot.objectInstance;this.textContent='';var titleEl=document.createElement('div');titleEl.classList.add('title');titleEl.appendChild(document.createTextNode('Snapshot of '));this.appendChild(titleEl);var instanceLinkEl=document.createElement('tr-ui-a-analysis-link');instanceLinkEl.selection=new tr.model.EventSet(instance);titleEl.appendChild(instanceLinkEl);titleEl.appendChild(document.createTextNode(' @ '));titleEl.appendChild(tr.ui.units.createTimeStampSpan(snapshot.ts,{ownerDocument:this.ownerDocument}));var tableEl=document.createElement('table');this.appendChild(tableEl);var rowEl=document.createElement('tr');tableEl.appendChild(rowEl);var labelEl=document.createElement('td');labelEl.textContent='args:';rowEl.appendChild(labelEl);var argsEl=document.createElement('td');argsEl.id='args';rowEl.appendChild(argsEl);var objectViewEl=document.createElement('tr-ui-a-generic-object-view');objectViewEl.object=snapshot.args;argsEl.appendChild(objectViewEl);}});'use strict';Polymer('tr-ui-a-multi-object-sub-view',{created:function(){this.currentSelection_=undefined;},ready:function(){this.$.content.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;var objectEvents=tr.b.asArray(selection).sort(tr.b.Range.compareByMinTimes);var timeSpanConfig={ownerDocument:this.ownerDocument};var table=this.$.content;table.tableColumns=[{title:'First',value:function(event){if(event instanceof tr.model.ObjectSnapshot)
+return tr.ui.units.createTimeStampSpan(event.ts,timeSpanConfig);var spanEl=document.createElement('span');spanEl.appendChild(tr.ui.units.createTimeStampSpan(event.creationTs,timeSpanConfig));spanEl.appendChild(tr.ui.b.createSpan({textContent:'-',marginLeft:'4px',marginRight:'4px'}));if(event.deletionTs!=Number.MAX_VALUE){spanEl.appendChild(tr.ui.units.createTimeStampSpan(event.deletionTs,timeSpanConfig));}
+return spanEl;},width:'200px'},{title:'Second',value:function(event){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(event);},event.userFriendlyName);return linkEl;},width:'100%'}];table.tableRows=objectEvents;table.rebuild();}});'use strict';Polymer('tr-ui-a-single-sample-sub-view',{created:function(){this.currentSelection_=undefined;},ready:function(){this.$.content.tableColumns=[{title:'FirstColumn',value:function(row){return row.title;},width:'250px'},{title:'SecondColumn',value:function(row){return row.value;},width:'100%'}];this.$.content.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;if(this.currentSelection_===undefined){this.$.content.tableRows=[];return;}
+var sample=this.currentSelection_[0];var table=this.$.content;var rows=[];rows.push({title:'Title',value:sample.title});rows.push({title:'Sample time',value:tr.ui.units.createTimeStampSpan(sample.start,{ownerDocument:this.ownerDocument})});var sfEl=document.createElement('tr-ui-a-stack-frame');sfEl.stackFrame=sample.leafStackFrame;rows.push({title:'Stack trace',value:sfEl});table.tableRows=rows;table.rebuild();}});'use strict';tr.exportTo('tr.ui.analysis',function(){function zFunction(list){var n=list.length;if(n===0)
+return[];var z=new Array(n);z[0]=0;for(var i=1,left=0,right=0;i<n;++i){var maxLength;if(i<=right)
+maxLength=Math.min(right-i+1,z[i-left]);else
+maxLength=0;while(i+maxLength<n&&list[maxLength]===list[i+maxLength])
+++maxLength;if(i+maxLength-1>right){left=i;right=i+maxLength-1;}
+z[i]=maxLength;}
+return z;}
+function StackFrameTreeNode(title,opt_frame){this.title=title;this.frame=opt_frame;this.parent=undefined;this.children=[];this.childMap={};this.total=0;this.self=0;}
+StackFrameTreeNode.prototype={get subRows(){return this.children;},get stackTraceTitles(){var titles=[];for(var currentNode=this;currentNode!==undefined;currentNode=currentNode.parent){titles.push(currentNode.title);}
+return titles;},getOrCreateChild:function(title,opt_frame){var childNode=this.childMap[title];if(childNode!==undefined)
+return childNode;childNode=new StackFrameTreeNode(title,opt_frame);childNode.parent=this;this.children.push(childNode);this.childMap[title]=childNode;return childNode;},addStackTrace:function(trace,value,opt_traceContainsRootFrame){var currentNode=this;var startIndex=trace.length-(opt_traceContainsRootFrame?2:1);for(var i=startIndex;i>=0;i--){currentNode.total+=value;var stackFrame=trace[i];currentNode=currentNode.getOrCreateChild(stackFrame.title,stackFrame);}
+currentNode.total+=value;currentNode.self+=value;},convertToBottomUpView:function(){var bottomUpViewRoot=new StackFrameTreeNode(this.title,this.frame);bottomUpViewRoot.total=this.total;bottomUpViewRoot.self=this.self;this.addChildrenToBottomUpViewRecursively_(bottomUpViewRoot);return bottomUpViewRoot;},addChildrenToBottomUpViewRecursively_:function(bottomUpViewRoot){this.children.forEach(function(child){child.addToBottomUpViewRecursively_(bottomUpViewRoot);});},addToBottomUpViewRecursively_:function(bottomUpViewRoot){var remainingRecursiveSuffixLength=this.calculateRecursiveSuffixLength_();var bottomUpParentNode=bottomUpViewRoot;for(var topDownNode=this;topDownNode.parent!==undefined;topDownNode=topDownNode.parent){var bottomUpChildNode=bottomUpParentNode.getOrCreateChild(topDownNode.title,topDownNode.frame);bottomUpChildNode.self+=this.self;if(remainingRecursiveSuffixLength>0)
+remainingRecursiveSuffixLength--;else
+bottomUpChildNode.total+=this.total;bottomUpParentNode=bottomUpChildNode;}
+this.addChildrenToBottomUpViewRecursively_(bottomUpViewRoot);},calculateRecursiveSuffixLength_:function(){var maxLengths=zFunction(this.stackTraceTitles);var recursiveSuffixLength=0;for(var i=0;i<maxLengths.length;i++)
+recursiveSuffixLength=Math.max(recursiveSuffixLength,maxLengths[i]);return recursiveSuffixLength;}};return{StackFrameTreeNode:StackFrameTreeNode,zFunction:zFunction};});'use strict';(function(){Polymer('tr-ui-a-multi-sample-sub-view',{ready:function(){this.viewSelector_=this.$.view_selector;this.selection_=undefined;this.viewSelector_.addEventListener('change',this.viewSelectorChanged_.bind(this));},viewSelectorChanged_:function(){this.samplingData_=this.createSamplingSummary_(this.selection_,this.viewSelector_.value);this.updateContents_();},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;this.samplingData_=this.createSamplingSummary_(selection,this.viewSelector_.value);this.updateContents_();},createSamplingSummary_:function(selection,viewOption){var root=new tr.ui.analysis.StackFrameTreeNode('(root)',undefined);var samples=selection.getEventsOrganizedByBaseType().sample;samples.forEach(function(sample){root.addStackTrace(sample.stackTrace,1);});switch(viewOption){case'TOPDOWNVIEW':return root;case'BOTTOMUPVIEW':return root.convertToBottomUpView();default:throw new Error('Unknown sampling summary view option: \''+viewOption+'\'');}},updateContents_:function(){var columns=[this.createPercentColumn_('Total'),this.createSamplesColumn_('Total'),this.createPercentColumn_('Self'),this.createSamplesColumn_('Self'),{title:'Symbol',value:function(row){return row.title;},width:'250px',cmp:function(a,b){return a.title.localeCompare(b.title);},showExpandButtons:true}];this.$.table.tableColumns=columns;this.$.table.sortColumnIndex=1;this.$.table.sortDescending=true;this.$.table.tableRows=this.samplingData_.subRows;this.$.table.rebuild();},createPercentColumn_:function(title){var field=title.toLowerCase();return{title:title+' percent',value:function(row){var percent=row[field]/this.samplingData_.total;var span=document.createElement('tr-ui-u-scalar-span');span.value=(percent*100).toFixed(2);span.percentage=percent;span.unit=tr.b.u.Units.unitlessNumber;return span;}.bind(this),width:'60px',cmp:function(a,b){return a[field]-b[field];}};},createSamplesColumn_:function(title){var field=title.toLowerCase();return{title:title+' samples',value:function(row){return row[field];},width:'60px',cmp:function(a,b){return a[field]-b[field];}};}});})();'use strict';Polymer('tr-ui-a-single-interaction-record-sub-view',{created:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.textContent='';var realView=document.createElement('tr-ui-a-single-event-sub-view');this.appendChild(realView);realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;},get relatedEventsToHighlight(){if(!this.currentSelection_)
+return undefined;return this.currentSelection_[0].associatedEvents;}});'use strict';Polymer('tr-ui-a-multi-interaction-record-sub-view',{created:function(){this.currentSelection_=undefined;},set selection(selection){this.currentSelection_=selection;this.textContent='';var realView=document.createElement('tr-ui-a-multi-event-sub-view');this.appendChild(realView);realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;},get selection(){return this.currentSelection_;},get relatedEventsToHighlight(){if(!this.currentSelection_)
+return undefined;var selection=new tr.model.EventSet();this.currentSelection_.forEach(function(ir){ir.associatedEvents.forEach(function(event){selection.push(event);});});return selection;}});'use strict';Polymer('tr-ui-a-alert-sub-view',{ready:function(){this.currentSelection_=undefined;this.$.table.tableColumns=[{title:'Label',value:function(row){return row.name;},width:'150px'},{title:'Value',width:'100%',value:function(row){return row.value;}}];this.$.table.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},getRowsForSingleAlert_:function(alert){var rows=[];for(var argName in alert.args){var argView=document.createElement('tr-ui-a-generic-object-view');argView.object=alert.args[argName];rows.push({name:argName,value:argView});}
+if(alert.associatedEvents.length){alert.associatedEvents.forEach(function(event,i){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return event;},event.title);var valueString='';if(event instanceof tr.model.TimedEvent)
+valueString='took '+event.duration.toFixed(2)+'ms';rows.push({name:linkEl,value:valueString});});}
+var descriptionEl=tr.ui.b.createDiv({textContent:alert.info.description,maxWidth:'300px'});rows.push({name:'Description',value:descriptionEl});if(alert.info.docLinks){alert.info.docLinks.forEach(function(linkObject){var linkEl=document.createElement('a');linkEl.target='_blank';linkEl.href=linkObject.href;linkEl.textContent=linkObject.textContent;rows.push({name:linkObject.label,value:linkEl});});}
+return rows;},getRowsForAlerts_:function(alerts){if(alerts.length==1){var rows=[{name:'Alert',value:alerts[0].title}];var detailRows=this.getRowsForSingleAlert_(alerts[0]);rows.push.apply(rows,detailRows);return rows;}else{return alerts.map(function(alert){return{name:'Alert',value:alert.title,isExpanded:alerts.size<10,subRows:this.getRowsForSingleAlert_(alert)};},this);}},updateContents_:function(){if(this.currentSelection_===undefined){this.$.table.rows=[];this.$.table.rebuild();return;}
+var alerts=this.currentSelection_;this.$.table.tableRows=this.getRowsForAlerts_(alerts);this.$.table.rebuild();},get relatedEventsToHighlight(){if(!this.currentSelection_)
+return undefined;return this.currentSelection_[0].associatedEvents;}});'use strict';Polymer('tr-ui-a-single-frame-sub-view',{ready:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!=1)
+throw new Error('Only supports single frame!');this.currentSelection_=selection;this.$.asv.selection=selection[0].associatedAlerts;},get relatedEventsToHighlight(){if(!this.currentSelection_)
+return undefined;return this.currentSelection_[0].associatedEvents;}});'use strict';Polymer('tr-ui-a-multi-frame-sub-view',{created:function(){this.currentSelection_=undefined;},set selection(selection){this.textContent='';var realView=document.createElement('tr-ui-a-multi-event-sub-view');realView.eventsHaveDuration=false;realView.eventsHaveSubRows=false;this.appendChild(realView);realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;},get selection(){return this.currentSelection_;},get relatedEventsToHighlight(){if(!this.currentSelection_)
+return undefined;var selection=new tr.model.EventSet();this.currentSelection_.forEach(function(frameEvent){frameEvent.associatedEvents.forEach(function(event){selection.push(event);});});return selection;}});'use strict';tr.exportTo('tr.ui.analysis',function(){var NO_BREAK_SPACE=String.fromCharCode(160);var COLLATOR=new Intl.Collator(undefined,{numeric:true});function TitleColumn(title){this.title=title;}
+TitleColumn.prototype={supportsCellSelection:false,value:function(row){var formattedTitle=this.formatTitle(row);var defined=row.defined;if(defined===undefined||defined.length===0)
+return formattedTitle;var firstDefined=defined[0];var lastDefined=defined[defined.length-1];var changeDefinedCount=0;for(var i=1;i<defined.length;i++){if(defined[i]!==defined[i-1])
+changeDefinedCount++;}
+var color=undefined;var prefix=undefined;if(!firstDefined&&lastDefined){color='red';prefix='+++';}else if(firstDefined&&!lastDefined){color='green';prefix='---';}
+if(changeDefinedCount>1){color='purple';}
+if(color===undefined&&prefix===undefined)
+return formattedTitle;var titleEl=document.createElement('span');if(prefix!==undefined){var prefixEl=tr.ui.b.createSpan({textContent:prefix});prefixEl.style.fontFamily='monospace';titleEl.appendChild(prefixEl);titleEl.appendChild(tr.ui.b.asHTMLOrTextNode(NO_BREAK_SPACE));}
+if(color!==undefined)
+titleEl.style.color=color;titleEl.appendChild(tr.ui.b.asHTMLOrTextNode(formattedTitle));return titleEl;},formatTitle:function(row){return row.title;},cmp:function(rowA,rowB){return COLLATOR.compare(rowA.title,rowB.title);}};function MemoryColumn(name,title,units,cellGetter,aggregationMode){this.name=name;this.title=title;this.units=units;this.cell=cellGetter;this.aggregationMode=aggregationMode;this.color=undefined;}
+MemoryColumn.fromRows=function(rows,cellKey,aggregationMode,opt_titleBuilder){var columnTraits={};function gatherTraits(row){if(row===undefined)
+return;var attrCells=row[cellKey];if(attrCells===undefined)
+return;tr.b.iterItems(attrCells,function(attrName,attrCell){if(attrCell===undefined)
+return;var attrValues=attrCell.attrs;if(attrValues===undefined)
+return;var existingTraits=columnTraits[attrName];attrValues.forEach(function(attrValue){if(attrValue===undefined)
+return;if(existingTraits===undefined){columnTraits[attrName]=existingTraits={constructor:attrValue.constructor,units:attrValue.units};return;}
+if(existingTraits.constructor!==attrValue.constructor||existingTraits.units!==attrValue.units){existingTraits.constructor=tr.model.UnknownAttribute;existingTraits.units=undefined;}});});if(row.subRows!==undefined)
+row.subRows.forEach(gatherTraits);};rows.forEach(gatherTraits);var titleBuilder=opt_titleBuilder||tr.b.identity;var columns=[];tr.b.iterItems(columnTraits,function(columnName,columnTraits){var cellGetter=fieldGetter(cellKey,columnName);var title=titleBuilder(columnName);columns.push(MemoryColumn.fromAttributeTraits(columnName,title,columnTraits,cellGetter,aggregationMode));});return columns;};MemoryColumn.fromAttributeTraits=function(name,title,traits,cellGetter,aggregationMode){var constructor;if(traits.constructor===tr.model.ScalarAttribute)
+constructor=ScalarMemoryColumn;else
+constructor=MemoryColumn;return new constructor(name,title,traits.units,cellGetter,aggregationMode);};MemoryColumn.spaceEqually=function(columns){var columnWidth=(100/columns.length).toFixed(3)+'%';columns.forEach(function(column){column.width=columnWidth;});};MemoryColumn.sortByImportance=function(columns,importanceRules){var positions=columns.map(function(column,srcIndex){return{importance:column.getImportance(importanceRules),column:column};});positions.sort(function(a,b){if(a.importance===b.importance)
+return COLLATOR.compare(a.column.name,b.column.name);return b.importance-a.importance;});positions.forEach(function(position,dstIndex){columns[dstIndex]=position.column;});};MemoryColumn.columnNamesToImportanceRules=function(columnNames){return columnNames.map(function(columnName,columnIndex){return{condition:columnName,importance:columnNames.length-columnIndex};});};MemoryColumn.iconFromAttributeInfoType=function(type){switch(type){case tr.model.AttributeInfoType.WARNING:return{symbol:String.fromCharCode(9888),color:'red'};case tr.model.AttributeInfoType.LINK:return{symbol:String.fromCharCode(9903)};case tr.model.AttributeInfoType.MEMORY_OWNER:return{symbol:String.fromCharCode(8702),color:'green'};case tr.model.AttributeInfoType.MEMORY_OWNED:return{symbol:String.fromCharCode(8701),color:'green'};case tr.model.AttributeInfoType.OVERALL_VALUE:return{symbol:String.fromCharCode(8614)};case tr.model.AttributeInfoType.RECENT_VALUE:return{symbol:String.fromCharCode(8618)};case tr.model.AttributeInfoType.HAS_HEAP_DUMP:return{symbol:String.fromCharCode(9283)};default:return{symbol:String.fromCharCode(9432),color:'blue'};}
+throw new Error('Unreachable');};MemoryColumn.AggregationMode={DIFF:0,MAX:1};MemoryColumn.prototype={attrs:function(row){var cell=this.cell(row);if(cell===undefined)
+return undefined;return cell.attrs;},value:function(row){var attrs=this.attrs(row);if(this.hasAllAttrsUndefined(attrs))
+return'';return this.formatAttributes(attrs);},hasAllAttrsUndefined:function(attrs){if(attrs===undefined)
+return true;return attrs.every(function(attr){return attr===undefined;});},formatAttributes:function(attrs){var formattedValue=this.formatAttributeValues(attrs);var color;if(typeof this.color==='function')
+color=this.color(attrs);else
+color=this.color;var infos=this.getInfos(attrs);if((color===undefined||formattedValue==='')&&infos.length===0)
+return formattedValue;var attrEl=document.createElement('span');attrEl.style.display='flex';attrEl.style.alignItems='center';attrEl.appendChild(tr.ui.b.asHTMLOrTextNode(formattedValue));infos.forEach(function(info){var infoEl=document.createElement('span');infoEl.style.paddingLeft='4px';infoEl.style.cursor='help';infoEl.style.fontWeight='bold';var icon=MemoryColumn.iconFromAttributeInfoType(info.type);infoEl.textContent=icon.symbol;if(icon.color!==undefined)
+infoEl.style.color=icon.color;infoEl.title=info.message;attrEl.appendChild(infoEl);},this);if(color!==undefined)
+attrEl.style.color=color;return attrEl;},formatAttributeValues:function(attrs){if(attrs.length===1)
+return this.formatSingleAttributeValue(attrs[0]);else
+return this.formatMultipleAttributeValues(attrs);},formatSingleAttributeValue:function(attr){return String(attr.value);},formatMultipleAttributeValues:function(attrs){var commonAttr=this.getCommonAttributeOrUndefined(attrs);if(commonAttr===undefined){return tr.ui.b.createSpan({textContent:'(multiple values)',italic:true});}
+return this.formatSingleAttributeValue(commonAttr);},cmp:function(rowA,rowB){var attrsA=this.attrs(rowA);var attrsB=this.attrs(rowB);if(attrsA!==undefined&&attrsB!==undefined&&attrsA.length!==attrsB.length)
+throw new Error('Different number of attributes');var undefinedA=this.hasAllAttrsUndefined(attrsA);var undefinedB=this.hasAllAttrsUndefined(attrsB);if(undefinedA&&undefinedB)
+return 0;if(undefinedA)
+return-1;if(undefinedB)
+return 1;return this.compareAttributes(attrsA,attrsB);},compareAttributes:function(attrsA,attrsB){if(attrsA.length===1)
+return this.compareSingleAttributes(attrsA[0],attrsB[0]);else
+return this.compareMultipleAttributes(attrsA,attrsB);},compareSingleAttributes:function(attrA,attrB){var strA=String(attrA.value);var strB=String(attrB.value);return COLLATOR.compare(strA,strB);},compareMultipleAttributes:function(attrsA,attrsB){var commonAttrA=this.getCommonAttributeOrUndefined(attrsA);var commonAttrB=this.getCommonAttributeOrUndefined(attrsB);var hasMultipleValuesA=commonAttrA===undefined;var hasMultipleValuesB=commonAttrB===undefined;if(hasMultipleValuesA&&hasMultipleValuesB)
+return 0;if(hasMultipleValuesA)
+return 1;if(hasMultipleValuesB)
+return-1;return this.compareSingleAttributes(commonAttrA,commonAttrB);},getCommonAttributeOrUndefined:function(attrs){var firstDefinedAttribute=undefined;for(var i=0;i<attrs.length;i++){var attr=attrs[i];if(attr===undefined)
+continue;if(firstDefinedAttribute===undefined){firstDefinedAttribute=attr;continue;}
+if(firstDefinedAttribute.value!==attr.value||firstDefinedAttribute.units!==attr.units){return undefined;}}
+return firstDefinedAttribute;},getInfos:function(attrs){if(attrs.length!==1){var hasDumpInfo=undefined;attrs.some(function(attr){if(attr===undefined)
+return false;return attr.infos.some(function(info){if(info.type!==tr.model.AttributeInfoType.HAS_HEAP_DUMP)
+return false;hasDumpInfo=info;return true;});});if(hasDumpInfo)
+return[hasDumpInfo];else
+return[];}
+return attrs[0].infos;},getImportance:function(importanceRules){if(importanceRules.length===0)
+return 0;for(var i=0;i<importanceRules.length;i++){var importanceRule=importanceRules[i];if(this.matchesNameCondition(importanceRule.condition))
+return importanceRule.importance;}
+var minImportance=importanceRules[0].importance;for(var i=1;i<importanceRules.length;i++){minImportance=Math.min(minImportance,importanceRules[i].importance);}
+return minImportance-1;},matchesNameCondition:function(condition){if(condition===undefined)
+return true;if(typeof(condition)==='string')
+return this.name===condition;return condition.test(this.name);}};function ScalarMemoryColumn(name,title,units,cellGetter,aggregationMode){MemoryColumn.call(this,name,title,units,cellGetter,aggregationMode);}
+ScalarMemoryColumn.prototype={__proto__:MemoryColumn.prototype,formatSingleAttributeValue:function(attr){return this.formatUnits(attr.value,false);},formatMultipleAttributeValues:function(attrs){switch(this.aggregationMode){case MemoryColumn.AggregationMode.DIFF:return this.formatUnits(this.getDiffAttrValue(attrs),true);case MemoryColumn.AggregationMode.MAX:return this.formatUnits(this.getMaxAttrValue(attrs),false);default:return tr.ui.b.createSpan({textContent:'(unsupported aggregation mode)',italic:true});}},formatUnits:function(value,isDelta){if(value===undefined)
+return'';var sizeEl=document.createElement('tr-ui-u-scalar-span');sizeEl.value=value;if(this.units==='bytes')
+sizeEl.unit=tr.b.u.Units.sizeInBytes;else
+sizeEl.unit=tr.b.u.Units.unitlessNumber;if(!isDelta)
+return sizeEl;sizeEl.isDelta=true;if(value===0)
+return sizeEl;var wrapperEl=document.createElement('span');wrapperEl.style.color=value>0?'red':'green';wrapperEl.appendChild(sizeEl);return wrapperEl;},compareSingleAttributes:function(attrA,attrB){return attrA.value-attrB.value;},compareMultipleAttributes:function(attrA,attrB){switch(this.aggregationMode){case MemoryColumn.AggregationMode.DIFF:var diffA=this.getDiffAttrValue(attrA)||0;var diffB=this.getDiffAttrValue(attrB)||0;return diffA-diffB;case MemoryColumn.AggregationMode.MAX:return this.getMaxAttrValue(attrA)-this.getMaxAttrValue(attrB);default:return 0;}},getDiffAttrValue:function(attrs){var firstAttr=attrs[0];var lastAttr=attrs[attrs.length-1];if(firstAttr===undefined&&lastAttr===undefined)
+return undefined;var firstValue=firstAttr===undefined?0:firstAttr.value;var lastValue=lastAttr===undefined?0:lastAttr.value;return lastValue-firstValue;},getMaxAttrValue:function(attrs){return attrs.reduce(function(accumulator,attr){if(attr===undefined)
+return accumulator;if(accumulator===undefined||attr.value>accumulator)
+accumulator=attr.value;return accumulator;},undefined);}};function MemoryCell(attrs){this.attrs=attrs;}
+MemoryCell.extractAttributes=function(cell){if(cell===undefined)
+return undefined;return cell.attrs;};function fieldGetter(){var fields=tr.b.asArray(arguments);return function(row){var value=row;for(var i=0;i<fields.length;i++)
+value=value[fields[i]];return value;};}
+var RECURSIVE_EXPANSION_MAX_SUB_ROW_COUNT=10;function expandTableRowsRecursively(table){function expandRowRecursively(row){if(row.subRows===undefined||row.subRows.length===0)
+return;if(row.subRows.length>RECURSIVE_EXPANSION_MAX_SUB_ROW_COUNT)
+return;table.setExpandedForTableRow(row,true);row.subRows.forEach(expandRowRecursively);}
+table.tableRows.forEach(expandRowRecursively);}
+function aggregateTableRowCellsRecursively(row,cellKey){var subRows=row.subRows;if(subRows===undefined)
+return;subRows.forEach(function(subRow){aggregateTableRowCellsRecursively(subRow,cellKey);});aggregateTableRowCells(row,subRows,cellKey);}
+function aggregateTableRowCells(row,subRows,cellKey){var rowCells=row[cellKey];if(rowCells===undefined)
+row[cellKey]=rowCells={};var subRowCellNames={};subRows.forEach(function(subRow){var subRowCells=subRow[cellKey];if(subRowCells===undefined)
+return;tr.b.iterItems(subRowCells,function(columnName){subRowCellNames[columnName]=true;});});tr.b.iterItems(subRowCellNames,function(cellName){var existingRowCell=rowCells[cellName];var existingRowAttributes=MemoryCell.extractAttributes(existingRowCell);var timestampCount=undefined;if(existingRowAttributes!==undefined)
+timestampCount=existingRowAttributes.length;subRows.forEach(function(subRow){var subRowCells=subRow[cellKey];if(subRowCells===undefined)
+return;var subRowCellAttributes=MemoryCell.extractAttributes(subRowCells[cellName]);if(subRowCellAttributes===undefined)
+return;if(timestampCount===undefined)
+timestampCount=subRowCellAttributes.length;else if(timestampCount!==subRowCellAttributes.length)
+throw new Error('Rows have different number of timestamps');});if(timestampCount===undefined)
+throw new Error('Handling non-existent cell name \''+cellName+'\'');var aggregatedAttributes=new Array(timestampCount);for(var i=0;i<timestampCount;i++){var existingRowAttribute=undefined;if(existingRowAttributes!==undefined)
+existingRowAttribute=existingRowAttributes[i];var subRowAttributes=subRows.map(function(subRow){var subRowCells=subRow[cellKey];if(subRowCells===undefined)
+return undefined;var subRowCellAttributes=MemoryCell.extractAttributes(subRowCells[cellName]);if(subRowCellAttributes===undefined)
+return;return subRowCellAttributes[i];});aggregatedAttributes[i]=tr.model.Attribute.aggregate(subRowAttributes,existingRowAttribute);}
+if(existingRowCell!==undefined){existingRowCell.attrs=aggregatedAttributes;}else{rowCells[cellName]=new MemoryCell(aggregatedAttributes);}});}
+function createCells(timeToValues,valueAttrsGetter,opt_cellAddedCallback){var attrNameToAttrs=tr.b.invertArrayOfDicts(timeToValues,valueAttrsGetter);return tr.b.mapItems(attrNameToAttrs,function(attrName,attrs){var cell=new tr.ui.analysis.MemoryCell(attrs);if(opt_cellAddedCallback!==undefined)
+opt_cellAddedCallback(attrName,cell);return cell;});}
+function addAttributeIfDefined(dstDict,attrName,attrClass,units,value,opt_addedCallback){if(value===undefined)
+return;var attr=new attrClass(units,value);dstDict[attrName]=attr;if(opt_addedCallback!==undefined)
+opt_addedCallback(attr);}
+return{TitleColumn:TitleColumn,MemoryColumn:MemoryColumn,ScalarMemoryColumn:ScalarMemoryColumn,MemoryCell:MemoryCell,fieldGetter:fieldGetter,expandTableRowsRecursively:expandTableRowsRecursively,aggregateTableRowCellsRecursively:aggregateTableRowCellsRecursively,aggregateTableRowCells:aggregateTableRowCells,createCells:createCells,addAttributeIfDefined:addAttributeIfDefined};});'use strict';Polymer('tr-ui-a-stacked-pane',{rebuild:function(){if(!this.paneDirty_){return;}
+this.paneDirty_=false;this.rebuildPane_();},scheduleRebuildPane_:function(){if(this.paneDirty_)
+return;this.paneDirty_=true;setTimeout(this.rebuild.bind(this),0);},rebuildPane_:function(){},set childPaneBuilder(childPaneBuilder){this.childPaneBuilder_=childPaneBuilder;this.dispatchEvent(new tr.b.Event('request-child-pane-change'));},get childPaneBuilder(){return this.childPaneBuilder_;},appended:function(){this.rebuild();}});'use strict';tr.exportTo('tr.ui.analysis',function(){var COLUMN_IMPORTANCE_RULES=tr.ui.analysis.MemoryColumn.columnNamesToImportanceRules(['Total size','Self size']);Polymer('tr-ui-a-memory-dump-heap-details-pane',{created:function(){this.heapDumps_=undefined;this.aggregationMode_=undefined;this.bottomUpView_=false;},ready:function(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;this.$.view_mode_container.appendChild(tr.ui.b.createSelector(this,'bottomUpView','memoryDumpHeapDetailsPane.bottomUpView',false,[{label:'Tree (top down)',value:false},{label:'Heavy (bottom up)',value:true}]));},set heapDumps(heapDumps){this.heapDumps_=heapDumps;this.scheduleRebuildPane_();},get heapDumps(){return this.heapDumps_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuildPane_();},get aggregationMode(){return this.aggregationMode_;},set bottomUpView(bottomUpView){this.bottomUpView_=bottomUpView;this.scheduleRebuildPane_();},get bottomUpView(){return this.bottomUpView_;},rebuildPane_:function(){if(this.heapDumps_===undefined||this.heapDumps_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.view_mode_container.style.display='none';this.$.table.clear();this.$.table.rebuild();return;}
+this.$.info_text.style.display='none';this.$.table.style.display='block';this.$.view_mode_container.style.display='block';var stackFrameTrees=this.createStackFrameTrees_(this.heapDumps_);var rows=this.createRows_(stackFrameTrees);var columns=this.createColumns_(rows);this.$.table.tableRows=rows;this.$.table.tableColumns=columns;this.$.table.rebuild();tr.ui.analysis.expandTableRowsRecursively(this.$.table);},createStackFrameTrees_:function(heapDumps){return heapDumps.map(function(heapDump){if(heapDump===undefined)
+return undefined;var rootNode=new tr.ui.analysis.StackFrameTreeNode(heapDump.allocatorName);var sumSize=undefined;heapDump.entries.forEach(function(entry){var size=entry.size;var leafStackFrame=entry.leafStackFrame;if(leafStackFrame===undefined){if(sumSize!==undefined)
+throw new Error('Multiple sum stack frames');sumSize=size;return;}
+rootNode.addStackTrace(leafStackFrame.stackTrace,size,true);},this);if(sumSize!==undefined&&sumSize>rootNode.total){var unspecifiedSize=sumSize-rootNode.total;rootNode.total=sumSize;var unspecifiedNode=rootNode.getOrCreateChild('<unspecified>');unspecifiedNode.total+=unspecifiedSize;unspecifiedNode.self+=unspecifiedSize;}
+if(this.bottomUpView)
+return rootNode.convertToBottomUpView();else
+return rootNode;},this);},createRows_:function(stackFrameTrees){return[this.createHeapRowRecursively_(stackFrameTrees)];},createHeapRowRecursively_:function(nodes){var title=tr.b.findFirstInArray(nodes).title;var defined=nodes.map(function(node){return node!==undefined;});var cells=tr.ui.analysis.createCells(nodes,function(node){return{'Total size':new tr.model.ScalarAttribute('bytes',node.total),'Self size':new tr.model.ScalarAttribute('bytes',node.self)};});var groupedChildNodes=tr.b.dictionaryValues(tr.b.invertArrayOfDicts(nodes,function(node){return node.children;}));var row={title:title,defined:defined,cells:cells};if(groupedChildNodes.length>0){row.subRows=groupedChildNodes.map(this.createHeapRowRecursively_,this);}
+return row;},createColumns_:function(rows){var titleColumn=new tr.ui.analysis.TitleColumn('Stack frame');titleColumn.width='500px';var attributeColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'cells',this.aggregationMode_);tr.ui.analysis.MemoryColumn.sortByImportance(attributeColumns,COLUMN_IMPORTANCE_RULES);tr.ui.analysis.MemoryColumn.spaceEqually(attributeColumns);var columns=[titleColumn].concat(attributeColumns);return columns;}});return{};});'use strict';tr.exportTo('tr.ui.analysis',function(){var IMPORTANCE_RULES=[{condition:tr.model.MemoryAllocatorDump.SIZE_ATTRIBUTE_NAME,importance:10},{condition:tr.model.MemoryAllocatorDump.EFFECTIVE_SIZE_ATTRIBUTE_NAME,importance:9},{condition:'page_size',importance:0},{condition:/size/,importance:5},{importance:0}];function AllocatorDumpNameColumn(title){tr.ui.analysis.TitleColumn.call(this,title);}
+AllocatorDumpNameColumn.prototype={__proto__:tr.ui.analysis.TitleColumn.prototype,formatTitle:function(row){if(!row.suballocation)
+return row.title;return tr.ui.b.createSpan({textContent:row.title,italic:true,tooltip:row.fullName});}};Polymer('tr-ui-a-memory-dump-allocator-details-pane',{created:function(){this.memoryAllocatorDumps_=undefined;this.heapDumps_=undefined;this.aggregationMode_=undefined;},ready:function(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;},set memoryAllocatorDumps(memoryAllocatorDumps){this.memoryAllocatorDumps_=memoryAllocatorDumps;this.scheduleRebuildPane_();},get memoryAllocatorDumps(){return this.memoryAllocatorDumps_;},set heapDumps(heapDumps){this.heapDumps_=heapDumps;this.scheduleRebuildPane_();},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuildPane_();},get aggregationMode(){return this.aggregationMode_;},rebuildPane_:function(){if(this.memoryAllocatorDumps_===undefined||this.memoryAllocatorDumps_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.table.clear();this.$.table.rebuild();this.childPaneBuilder=undefined;return;}
+this.$.info_text.style.display='none';this.$.table.style.display='block';var rows=this.createRows_();var columns=this.createColumns_(rows);this.$.table.tableRows=rows;this.$.table.tableColumns=columns;this.$.table.rebuild();tr.ui.analysis.expandTableRowsRecursively(this.$.table);if(this.heapDumps_===undefined){this.childPaneBuilder=undefined;}else{this.childPaneBuilder=function(){var pane=document.createElement('tr-ui-a-memory-dump-heap-details-pane');pane.heapDumps=this.heapDumps_;pane.aggregationMode=this.aggregationMode_;return pane;}.bind(this);}},createRows_:function(){return[this.createAllocatorRowRecursively_(this.memoryAllocatorDumps_)];},createAllocatorRowRecursively_:function(dumps){var definedDump=tr.b.findFirstInArray(dumps);var title=definedDump.name;var fullName=definedDump.fullName;var defined=dumps.map(function(dump){return dump!==undefined;});var cells=tr.ui.analysis.createCells(dumps,function(dump){return dump.attributes;});var suballocatedBy=undefined;if(title.startsWith('__')){for(var i=0;i<dumps.length;i++){var dump=dumps[i];if(dump===undefined||dump.ownedBy.length===0){continue;}
+var ownerDump=dump.ownedBy[0].source;if(dump.ownedBy.length>1||dump.children.length>0||ownerDump.containerMemoryDump!==dump.containerMemoryDump){suballocatedBy=undefined;break;}
+if(suballocatedBy===undefined){suballocatedBy=ownerDump.fullName;}else if(suballocatedBy!==ownerDump.fullName){suballocatedBy=undefined;break;}}}
+var row={title:title,fullName:fullName,defined:defined,cells:cells,suballocatedBy:suballocatedBy};var childDumpNameToDumps=tr.b.invertArrayOfDicts(dumps,function(dump){return tr.b.arrayToDict(dump.children,function(child){return child.name;});});var subRows=[];var suballocationClassificationRootNode=undefined;tr.b.iterItems(childDumpNameToDumps,function(childName,childDumps){var childRow=this.createAllocatorRowRecursively_(childDumps);if(childRow.suballocatedBy===undefined){subRows.push(childRow);}else{suballocationClassificationRootNode=this.classifySuballocationRow_(childRow,suballocationClassificationRootNode);}},this);if(suballocationClassificationRootNode!==undefined){var suballocationRow=this.createSuballocationRowRecursively_('suballocations',suballocationClassificationRootNode);tr.ui.analysis.aggregateTableRowCellsRecursively(suballocationRow,'cells');subRows.push(suballocationRow);}
+if(subRows.length>0)
+row.subRows=subRows;return row;},classifySuballocationRow_:function(suballocationRow,rootNode){if(rootNode===undefined){rootNode={children:{},row:undefined};}
+var suballocationLevels=suballocationRow.suballocatedBy.split('/');var currentNode=rootNode;for(var i=0;i<suballocationLevels.length;i++){var suballocationLevel=suballocationLevels[i];var nextNode=currentNode.children[suballocationLevel];if(nextNode===undefined){currentNode.children[suballocationLevel]=nextNode={children:{},row:undefined};}
+var currentNode=nextNode;}
+if(currentNode.row!==undefined)
+throw new Error('Multiple suballocations with the same owner name');currentNode.row=suballocationRow;return rootNode;},createSuballocationRowRecursively_:function(name,node){var childCount=Object.keys(node.children).length;if(childCount===0){if(node.row===undefined)
+throw new Error('Suballocation node must have a row or children');var row=node.row;row.title=name;row.suballocation=true;return row;}
+var subRows=tr.b.dictionaryValues(tr.b.mapItems(node.children,this.createSuballocationRowRecursively_,this));if(node.row!==undefined){var row=node.row;row.title='<unspecified>';row.suballocation=true;subRows.unshift(row);}
+var defined=new Array(subRows[0].defined.length);for(var i=0;i<subRows.length;i++){subRows[i].defined.forEach(function(definedValue,index){defined[index]=defined[index]||definedValue;});}
+return{title:name,suballocation:true,defined:defined,cells:{},subRows:subRows};},createColumns_:function(rows){var titleColumn=new AllocatorDumpNameColumn('Component');titleColumn.width='200px';var attributeColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'cells',this.aggregationMode_);tr.ui.analysis.MemoryColumn.spaceEqually(attributeColumns);tr.ui.analysis.MemoryColumn.sortByImportance(attributeColumns,IMPORTANCE_RULES);var columns=[titleColumn].concat(attributeColumns);return columns;}});return{};});'use strict';tr.exportTo('tr.ui.analysis',function(){var COLUMN_IMPORTANCE_RULES=tr.ui.analysis.MemoryColumn.columnNamesToImportanceRules(['Start address','Virtual size','Protection flags','PSS','Private dirty','Private clean','Shared dirty','Shared clean','Swapped']);var CLASSIFICATION_RULES={name:'Total',children:[{name:'Android',file:/^\/dev\/ashmem(?!\/libc malloc)/,children:[{name:'Java runtime',file:/^\/dev\/ashmem\/dalvik-/,children:[{name:'Spaces',file:/\/dalvik-(alloc|main|large object|non moving|zygote) space/,children:[{name:'Normal',file:/\/dalvik-(alloc|main)/},{name:'Large',file:/\/dalvik-large object/},{name:'Zygote',file:/\/dalvik-zygote/},{name:'Non-moving',file:/\/dalvik-non moving/}]},{name:'Linear Alloc',file:/\/dalvik-LinearAlloc/},{name:'Indirect Reference Table',file:/\/dalvik-indirect.ref/},{name:'Cache',file:/\/dalvik-jit-code-cache/},{name:'Accounting'}]},{name:'Cursor',file:/\/CursorWindow/},{name:'Ashmem'}]},{name:'Native heap',file:/^((\[heap\])|(\[anon:)|(\/dev\/ashmem\/libc malloc)|(\[discounted tracing overhead\])|$)/},{name:'Stack',file:/^\[stack/},{name:'Files',file:/\.((((jar)|(apk)|(ttf)|(odex)|(oat)|(arg))$)|(dex)|(so))/,children:[{name:'so',file:/\.so/},{name:'jar',file:/\.jar$/},{name:'apk',file:/\.apk$/},{name:'ttf',file:/\.ttf$/},{name:'dex',file:/\.((dex)|(odex$))/},{name:'oat',file:/\.oat$/},{name:'art',file:/\.art$/}]},{name:'Devices',file:/(^\/dev\/)|(anon_inode:dmabuf)/,children:[{name:'GPU',file:/\/((nv)|(mali)|(kgsl))/},{name:'DMA',file:/anon_inode:dmabuf/}]}]};function createEmptyRuleRow(rule){var row={title:rule.name,rule:rule,subRows:[]};if(rule.children!==undefined)
+row.subRows=rule.children.map(createEmptyRuleRow);return row;}
+function hexString(address,is64BitAddress){if(address===undefined)
+return undefined;var hexPadding=is64BitAddress?'0000000000000000':'00000000';return(hexPadding+address.toString(16)).substr(-hexPadding.length);}
+function classifyRegionRow(ruleRow,regionRow){var rule=ruleRow.rule;if(rule===undefined||rule.children===undefined||rule.children.length===0){ruleRow.subRows.push(regionRow);return;}
+function regionRowMatchesChildRule(childRule){var fileRegExp=childRule.file;if(fileRegExp===undefined)
+return true;return fileRegExp.test(regionRow.title);}
+var matchedChildRuleIndex=tr.b.findFirstIndexInArray(rule.children,regionRowMatchesChildRule);if(matchedChildRuleIndex===-1){matchedChildRuleIndex=rule.children.length;if(matchedChildRuleIndex>=ruleRow.subRows.length){ruleRow.subRows.push({title:'Other',subRows:[]});}}
+classifyRegionRow(ruleRow.subRows[matchedChildRuleIndex],regionRow);}
+function pruneEmptyRuleRows(row){if(row.subRows===undefined||row.subRows.length===0)
+return;if(row.subRows[0].rule===undefined){return;}
+row.subRows.forEach(pruneEmptyRuleRows);row.subRows=row.subRows.filter(function(subRow){return subRow.subRows.length>0;});}
+Polymer('tr-ui-a-memory-dump-vm-regions-details-pane',{created:function(){this.vmRegions_=undefined;this.aggregationMode_=undefined;},ready:function(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;},set vmRegions(vmRegions){this.vmRegions_=vmRegions;this.scheduleRebuildPane_();},get vmRegions(){return this.vmRegions_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuildPane_();},get aggregationMode(){return this.aggregationMode_;},rebuildPane_:function(){var unclassifiedRows=[];if(this.vmRegions_!==undefined)
+unclassifiedRows=this.createUnclassifiedRows_(this.vmRegions_);if(unclassifiedRows.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.table.clear();this.$.table.rebuild();return;}
+this.$.info_text.style.display='none';this.$.table.style.display='block';var rows=this.classifyRows_(unclassifiedRows);var columns=this.createColumns_(rows);this.$.table.tableRows=rows;this.$.table.tableColumns=columns;this.$.table.rebuild();tr.ui.analysis.expandTableRowsRecursively(this.$.table);},joinRegions_:function(timeToRegionIdToRegion){return tr.b.dictionaryValues(tr.b.invertArrayOfDicts(timeToRegionIdToRegion,function(regionIdToRegion){return tr.b.arrayToDict(regionIdToRegion,function(region){return[region.mappedFile,region.startAddress].join('#');});}));},createUnclassifiedRows_:function(timeToRegionIdToRegion){var is64BitAddress=timeToRegionIdToRegion.some(function(regionIdToRegion){if(regionIdToRegion===undefined)
+return false;return regionIdToRegion.some(function(region){if(region.startAddress===undefined)
+return false;return region.startAddress>=4294967296;});});var regionIdToTimeToRegion=this.joinRegions_(timeToRegionIdToRegion);return regionIdToTimeToRegion.map(function(timeToRegion){var definedRegion=tr.b.findFirstInArray(timeToRegion);var defined=timeToRegion.map(function(region){return region!==undefined;});var constantCells=tr.ui.analysis.createCells([definedRegion],function(region){var attrs={};tr.ui.analysis.addAttributeIfDefined(attrs,'Start address',tr.model.StringAttribute,'',hexString(region.startAddress,is64BitAddress));return attrs;});var variableCells=tr.ui.analysis.createCells(timeToRegion,function(region){var attrs={};tr.ui.analysis.addAttributeIfDefined(attrs,'Virtual size',tr.model.ScalarAttribute,'bytes',region.sizeInBytes);tr.ui.analysis.addAttributeIfDefined(attrs,'Protection flags',tr.model.StringAttribute,'',region.protectionFlagsToString);tr.ui.analysis.addAttributeIfDefined(attrs,'PSS',tr.model.ScalarAttribute,'bytes',region.byteStats.proportionalResident);tr.ui.analysis.addAttributeIfDefined(attrs,'Private dirty',tr.model.ScalarAttribute,'bytes',region.byteStats.privateDirtyResident);tr.ui.analysis.addAttributeIfDefined(attrs,'Private clean',tr.model.ScalarAttribute,'bytes',region.byteStats.privateCleanResident);tr.ui.analysis.addAttributeIfDefined(attrs,'Shared dirty',tr.model.ScalarAttribute,'bytes',region.byteStats.sharedDirtyResident);tr.ui.analysis.addAttributeIfDefined(attrs,'Shared clean',tr.model.ScalarAttribute,'bytes',region.byteStats.sharedCleanResident);tr.ui.analysis.addAttributeIfDefined(attrs,'Swapped',tr.model.ScalarAttribute,'bytes',region.byteStats.swapped);return attrs;});return{title:definedRegion.mappedFile||'',defined:defined,constantCells:constantCells,variableCells:variableCells};});},classifyRows_:function(unclassifiedRows){var rootRow=createEmptyRuleRow(CLASSIFICATION_RULES);unclassifiedRows.map(classifyRegionRow.bind(undefined,rootRow));pruneEmptyRuleRows(rootRow);tr.ui.analysis.aggregateTableRowCellsRecursively(rootRow,'constantCells');tr.ui.analysis.aggregateTableRowCellsRecursively(rootRow,'variableCells');return[rootRow];},createColumns_:function(rows){var titleColumn=new tr.ui.analysis.TitleColumn('Mapped file');titleColumn.width='200px';var constantColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'constantCells');var variableColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'variableCells',this.aggregationMode_);var attributeColumns=constantColumns.concat(variableColumns);tr.ui.analysis.MemoryColumn.sortByImportance(attributeColumns,COLUMN_IMPORTANCE_RULES);tr.ui.analysis.MemoryColumn.spaceEqually(attributeColumns);var columns=[titleColumn].concat(attributeColumns);return columns;}});return{};});'use strict';Polymer('tr-ui-b-color-legend',{ready:function(){var blackSquareCharCode=9632;this.$.square.innerText=String.fromCharCode(blackSquareCharCode);this.label_=undefined;this.compoundEventSelectionState_=tr.model.CompoundEventSelectionState.NOT_SELECTED;},set compoundEventSelectionState(compoundEventSelectionState){this.compoundEventSelectionState_=compoundEventSelectionState;},get label(){return this.label_;},set label(label){if(label===undefined){this.setLabelAndColorId(undefined,undefined);return;}
+var colorId=tr.b.ColorScheme.getColorIdForGeneralPurposeString(label);this.setLabelAndColorId(label,colorId);},setLabelAndColorId:function(label,colorId){this.label_=label;this.$.label.textContent='';this.$.label.appendChild(tr.ui.b.asHTMLOrTextNode(label));if(colorId===undefined)
+this.$.square.style.color='initial';else
+this.$.square.style.color=tr.b.ColorScheme.colorsAsStrings[colorId];}});'use strict';Polymer('tr-ui-b-view-specific-brushing-state',{get viewId(){return this.getAttribute('view-id');},set viewId(viewId){this.setAttribute('view-id',viewId);},get:function(){var viewId=this.viewId;if(!viewId)
+throw new Error('Element must have a view-id attribute!');var brushingStateController=tr.c.BrushingStateController.getControllerForElement(this);if(!brushingStateController)
+return undefined;return brushingStateController.getViewSpecificBrushingState(viewId);},set:function(state){var viewId=this.viewId;if(!viewId)
+throw new Error('Element must have a view-id attribute!');var brushingStateController=tr.c.BrushingStateController.getControllerForElement(this);if(!brushingStateController)
+return;brushingStateController.changeViewSpecificBrushingState(viewId,state);}});'use strict';tr.exportTo('tr.ui.analysis',function(){var ColorScheme=tr.b.ColorScheme;var USED_MEMORY_SIZE_COLUMNS_IMPORTANCE_RULES=tr.ui.analysis.MemoryColumn.columnNamesToImportanceRules(['Total resident','Peak total resident','PSS','Private dirty','Swapped']);var ALLOCATOR_SIZE_COLUMNS_IMPORTANCE_RULES=[{condition:'tracing',importance:0},{importance:1}];var DISPLAYED_SIZE_ATTRIBUTE_NAME=tr.model.MemoryAllocatorDump.DISPLAYED_SIZE_ATTRIBUTE_NAME;var LINK_SYMBOL=String.fromCharCode(9903);var GREATER_THAN_OR_EQUAL_TO_SYMBOL=String.fromCharCode(8805);function ProcessNameColumn(title){tr.ui.analysis.TitleColumn.call(this,title);}
+ProcessNameColumn.prototype={__proto__:tr.ui.analysis.TitleColumn.prototype,formatTitle:function(row){if(row.noLegend)
+return row.title;var titleEl=document.createElement('tr-ui-b-color-legend');titleEl.label=row.title;return titleEl;}};Polymer('tr-ui-a-memory-dump-overview-pane',{created:function(){this.processMemoryDumps_=undefined;this.aggregationMode_=undefined;},ready:function(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.CELL;this.$.table.addEventListener('selection-changed',function(tableEvent){tableEvent.stopPropagation();this.changeChildPane_();}.bind(this));},set processMemoryDumps(processMemoryDumps){this.processMemoryDumps_=processMemoryDumps;this.scheduleRebuildPane_();},get processMemoryDumps(){return this.processMemoryDumps_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuildPane_();},get aggregationMode(){return this.aggregationMode_;},get selectedMemoryCell(){if(this.processMemoryDumps_===undefined||this.processMemoryDumps_.length===0){return undefined;}
+var selectedTableRow=this.$.table.selectedTableRow;if(!selectedTableRow)
+return undefined;var selectedColumnIndex=this.$.table.selectedColumnIndex;if(selectedColumnIndex===undefined)
+return undefined;var selectedColumn=this.$.table.tableColumns[selectedColumnIndex];var selectedMemoryCell=selectedColumn.cell(selectedTableRow);return selectedMemoryCell;},changeChildPane_:function(){this.storeSelection_();var builder=undefined;if(this.selectedMemoryCell!==undefined)
+builder=this.selectedMemoryCell.buildDetailsPane;this.childPaneBuilder=builder;},rebuildPane_:function(){if(this.processMemoryDumps_===undefined||this.processMemoryDumps_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.table.clear();this.$.table.rebuild();return;}
+this.$.info_text.style.display='none';this.$.table.style.display='block';var rows=this.createRows_();var footerRows=this.createFooterRows_(rows);var columns=this.createColumns_(rows);this.$.table.tableRows=rows;this.$.table.footerRows=footerRows;this.$.table.tableColumns=columns;this.$.table.rebuild();this.restoreSelection_();},createRows_:function(){var timeToPidToProcessMemoryDump=this.processMemoryDumps_;var pidToTimeToProcessMemoryDump=tr.b.invertArrayOfDicts(timeToPidToProcessMemoryDump);var rows=[];var aggregationMode=this.aggregationMode_;return tr.b.dictionaryValues(tr.b.mapItems(pidToTimeToProcessMemoryDump,function(pid,timeToDump){var process=tr.b.findFirstInArray(timeToDump).process;var defined=timeToDump.map(function(dump){return dump!==undefined;});var timeToVmRegions=timeToDump.map(function(dump){if(dump===undefined)
+return undefined;return dump.mostRecentVmRegions;});function buildVmRegionsPane(){var pane=document.createElement('tr-ui-a-memory-dump-vm-regions-details-pane');pane.vmRegions=timeToVmRegions;pane.aggregationMode=aggregationMode;return pane;}
+var usedMemoryCells=tr.ui.analysis.createCells(timeToDump,function(dump){var sizes={};if(dump.totals!==undefined){tr.ui.analysis.addAttributeIfDefined(sizes,'Total resident',tr.model.ScalarAttribute,'bytes',dump.totals.residentBytes);tr.ui.analysis.addAttributeIfDefined(sizes,'Peak total resident',tr.model.ScalarAttribute,'bytes',dump.totals.peakResidentBytes,function(attr){if(dump.totals.arePeakResidentBytesResettable){attr.infos.push(new tr.model.AttributeInfo(tr.model.AttributeInfoType.RECENT_VALUE,'Peak RSS since previous memory dump.'));}else{attr.infos.push(new tr.model.AttributeInfo(tr.model.AttributeInfoType.OVERALL_VALUE,'Peak RSS since process startup. Finer grained '+'peaks require a Linux kernel version '+
+GREATER_THAN_OR_EQUAL_TO_SYMBOL+' 4.0.'));}});}
+var vmRegionAttributeAddedCallback=undefined;if(!dump.hasOwnVmRegions){vmRegionAttributeAddedCallback=function(attr){attr.infos.push(new tr.model.AttributeInfo(tr.model.AttributeInfoType.LINK,'Older value (process did not dump memory maps).'));attr.isOlderValue=true;};}
+tr.ui.analysis.addAttributeIfDefined(sizes,'PSS',tr.model.ScalarAttribute,'bytes',dump.getMostRecentTotalVmRegionStat('proportionalResident'),vmRegionAttributeAddedCallback);tr.ui.analysis.addAttributeIfDefined(sizes,'Private dirty',tr.model.ScalarAttribute,'bytes',dump.getMostRecentTotalVmRegionStat('privateDirtyResident'),vmRegionAttributeAddedCallback);tr.ui.analysis.addAttributeIfDefined(sizes,'Swapped',tr.model.ScalarAttribute,'bytes',dump.getMostRecentTotalVmRegionStat('swapped'),vmRegionAttributeAddedCallback);return sizes;},function(attrName,cell){cell.buildDetailsPane=buildVmRegionsPane;});var allocatorCells=tr.ui.analysis.createCells(timeToDump,function(dump){if(dump.memoryAllocatorDumps===undefined)
+return undefined;var sizes={};dump.memoryAllocatorDumps.forEach(function(allocatorDump){var rootAttribute=allocatorDump.attributes[DISPLAYED_SIZE_ATTRIBUTE_NAME];if(rootAttribute===undefined)
+return;var allocatorName=allocatorDump.fullName;var overviewAttribute=new rootAttribute.constructor(rootAttribute.units,rootAttribute.value);if(dump.heapDumps!==undefined&&dump.heapDumps[allocatorName]!==undefined){overviewAttribute.infos.push(new tr.model.AttributeInfo(tr.model.AttributeInfoType.HAS_HEAP_DUMP,'Heap dump provided'));}
+sizes[allocatorName]=overviewAttribute;});return sizes;},function(allocatorName,cell){var memoryAllocatorDumps=timeToDump.map(function(dump){if(dump===undefined)
+return undefined;return dump.getMemoryAllocatorDumpByFullName(allocatorName);});var heapDumps=undefined;timeToDump.forEach(function(dump,index){if(dump===undefined||dump.heapDumps===undefined)
+return;if(heapDumps===undefined)
+heapDumps=new Array(timeToDump.length);heapDumps[index]=dump.heapDumps[allocatorName];});cell.buildDetailsPane=function(){var pane=document.createElement('tr-ui-a-memory-dump-allocator-details-pane');pane.memoryAllocatorDumps=memoryAllocatorDumps;pane.heapDumps=heapDumps;pane.aggregationMode=aggregationMode;return pane;};});return{title:process.userFriendlyName,defined:defined,usedMemoryCells:usedMemoryCells,allocatorCells:allocatorCells};}));},createFooterRows_:function(rows){if(rows.length<=1)
+return[];var totalRow={title:'Total',noLegend:true};tr.ui.analysis.aggregateTableRowCells(totalRow,rows,'usedMemoryCells');tr.ui.analysis.aggregateTableRowCells(totalRow,rows,'allocatorCells');return[totalRow];},createColumns_:function(rows){var titleColumn=new ProcessNameColumn('Process');titleColumn.width='200px';var usedMemorySizeColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'usedMemoryCells',this.aggregationMode_);tr.ui.analysis.MemoryColumn.sortByImportance(usedMemorySizeColumns,USED_MEMORY_SIZE_COLUMNS_IMPORTANCE_RULES);var allocatorSizeColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'allocatorCells',this.aggregationMode_,function(allocatorName){var titleEl=document.createElement('tr-ui-b-color-legend');titleEl.label=allocatorName;return titleEl;});tr.ui.analysis.MemoryColumn.sortByImportance(allocatorSizeColumns,ALLOCATOR_SIZE_COLUMNS_IMPORTANCE_RULES);var tracingColumn=tr.b.findFirstInArray(allocatorSizeColumns,function(column){return column.name==='tracing';});if(tracingColumn!==undefined){var tracingColumnColor=ColorScheme.getColorForReservedNameAsString('tracing_memory_column');tracingColumn.title=tr.ui.b.createSpan({textContent:'tracing',color:tracingColumnColor});tracingColumn.color=tracingColumnColor;}
+usedMemorySizeColumns.forEach(function(column){var olderUsedMCC=ColorScheme.getColorForReservedNameAsString('older_used_memory_column');var usedMCC=ColorScheme.getColorForReservedNameAsString('used_memory_column');column.title=tr.ui.b.createSpan({textContent:column.title,color:usedMCC});column.color=function(attrs){return attrs.length===1&&attrs[0].isOlderValue?olderUsedMCC:usedMCC;}});var sizeColumns=usedMemorySizeColumns.concat(allocatorSizeColumns);tr.ui.analysis.MemoryColumn.spaceEqually(sizeColumns);var columns=[titleColumn].concat(sizeColumns);return columns;},storeSelection_:function(){var selectedRowTitle;var selectedRow=this.$.table.selectedTableRow;if(selectedRow!==undefined)
+selectedRowTitle=selectedRow.title;var selectedColumnName;var selectedColumnIndex=this.$.table.selectedColumnIndex;if(selectedColumnIndex!==undefined){var selectedColumn=this.$.table.tableColumns[selectedColumnIndex];selectedColumnName=selectedColumn.name;}
+this.$.state.set({rowTitle:selectedRowTitle,columnName:selectedColumnName});},restoreSelection_:function(){var settings=this.$.state.get();if(settings===undefined||settings.rowTitle===undefined||settings.columnName===undefined)
+return;var selectedColumnName=settings.columnName;var selectedColumnIndex=tr.b.findFirstIndexInArray(this.$.table.tableColumns,function(column){return column.name===selectedColumnName;});if(selectedColumnIndex<0)
+return;var selectedRowTitle=settings.rowTitle;var selectedRow=tr.b.findFirstInArray(this.$.table.tableRows,function(row){return row.title===selectedRowTitle;});if(selectedRow===undefined)
+return;this.$.table.selectedTableRow=selectedRow;this.$.table.selectedColumnIndex=selectedColumnIndex;}});return{};});'use strict';tr.exportTo('tr.ui.analysis',function(){Polymer('tr-ui-a-memory-dump-header-pane',{created:function(){this.containerMemoryDumps_=undefined;},ready:function(){this.$.aggregation_mode_container.appendChild(tr.ui.b.createSelector(this,'aggregationMode','memoryDumpHeaderPane.aggregationMode',tr.ui.analysis.MemoryColumn.AggregationMode.DIFF,[{label:'Diff',value:tr.ui.analysis.MemoryColumn.AggregationMode.DIFF},{label:'Max',value:tr.ui.analysis.MemoryColumn.AggregationMode.MAX}]));},set containerMemoryDumps(containerMemoryDumps){this.containerMemoryDumps_=containerMemoryDumps;this.scheduleRebuildPane_();},get containerMemoryDumps(){return this.containerMemoryDumps_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuildPane_();},get aggregationMode(){return this.aggregationMode_;},rebuildPane_:function(){this.updateLabel_();this.updateAggregationModeSelector_();this.changeChildPane_();},updateLabel_:function(){this.$.label.textContent='';if(this.containerMemoryDumps_===undefined||this.containerMemoryDumps_.length<=0){this.$.label.textContent='No memory dumps selected';return;}
+var containerDumpCount=this.containerMemoryDumps_.length;var isMultiSelection=containerDumpCount>1;this.$.label.appendChild(document.createTextNode('Selected '+containerDumpCount+' memory dump'+
+(isMultiSelection?'s':'')+' in '+this.containerMemoryDumps_[0].containerName+' at '));this.$.label.appendChild(document.createTextNode(tr.b.u.TimeStamp.format(this.containerMemoryDumps_[0].start)));if(isMultiSelection){var ELLIPSIS=String.fromCharCode(8230);this.$.label.appendChild(document.createTextNode(ELLIPSIS));this.$.label.appendChild(document.createTextNode(tr.b.u.TimeStamp.format(this.containerMemoryDumps_[containerDumpCount-1].start)));}},updateAggregationModeSelector_:function(){var displayStyle;if(this.containerMemoryDumps_===undefined||this.containerMemoryDumps_.length<=1)
+displayStyle='none';else
+displayStyle='initial';this.$.aggregation_mode_container.style.display=displayStyle;},changeChildPane_:function(){this.childPaneBuilder=function(){if(this.containerMemoryDumps_===undefined||this.containerMemoryDumps_.length<=0)
+return undefined;var overviewPane=document.createElement('tr-ui-a-memory-dump-overview-pane');overviewPane.processMemoryDumps=this.containerMemoryDumps_.map(function(containerDump){return containerDump.processMemoryDumps;});overviewPane.aggregationMode=this.aggregationMode;return overviewPane;}.bind(this);}});return{};});'use strict';Polymer('tr-ui-a-stacked-pane-view',{setPaneBuilder:function(paneBuilder,opt_parentPane){var paneContainer=this.$.pane_container;if(opt_parentPane){if(!(opt_parentPane instanceof HTMLElement))
+throw new Error('Parent pane must be an HTML element');if(opt_parentPane.parentElement!==paneContainer)
+throw new Error('Parent pane must be a child of the pane container');}
+while(paneContainer.lastElementChild!==null&&paneContainer.lastElementChild!==opt_parentPane){var removedPane=this.$.pane_container.lastElementChild;var listener=this.listeners_.get(removedPane);if(listener===undefined)
+throw new Error('No listener associated with pane');this.listeners_.delete(removedPane);removedPane.removeEventListener('request-child-pane-change',listener);paneContainer.removeChild(removedPane);}
+if(opt_parentPane&&opt_parentPane.parentElement!==paneContainer)
+throw new Error('Parent pane was removed from the pane container');if(!paneBuilder)
+return;var pane=paneBuilder();if(!pane)
+return;if(!(pane instanceof HTMLElement))
+throw new Error('Pane must be an HTML element');var listener=function(event){this.setPaneBuilder(pane.childPaneBuilder,pane);}.bind(this);if(!this.listeners_){this.listeners_=new WeakMap();}
+this.listeners_.set(pane,listener);pane.addEventListener('request-child-pane-change',listener);paneContainer.appendChild(pane);pane.appended();},rebuild:function(){var currentPane=this.$.pane_container.firstElementChild;while(currentPane){currentPane.rebuild();currentPane=currentPane.nextElementSibling;}},get panesForTesting(){var panes=[];var currentChild=this.$.pane_container.firstElementChild;while(currentChild){panes.push(currentChild);currentChild=currentChild.nextElementSibling;}
+return panes;}});'use strict';tr.exportTo('tr.ui.analysis',function(){Polymer('tr-ui-a-container-memory-dump-sub-view',{set selection(selection){if(selection===undefined){this.currentSelection_=undefined;this.dumpsByContainerName_=undefined;this.updateContents_();return;}
+selection.forEach(function(event){if(!(event instanceof tr.model.ContainerMemoryDump)){throw new Error('Memory dump sub-view only supports container memory dumps');}});this.currentSelection_=selection;this.dumpsByContainerName_=tr.b.group(this.currentSelection_.toArray(),function(dump){return dump.containerName;});tr.b.iterItems(this.dumpsByContainerName_,function(containerName,dumps){dumps.sort(function(a,b){return a.start-b.start;});});this.updateContents_();},get selection(){return this.currentSelection_;},get requiresTallView(){return true;},updateContents_:function(){this.$.content.textContent='';if(this.dumpsByContainerName_===undefined)
+return;var containerNames=Object.keys(this.dumpsByContainerName_);if(containerNames.length===0)
+return;if(containerNames.length>1)
+this.buildViewForMultipleContainerNames_();else
+this.buildViewForSingleContainerName_();},buildViewForSingleContainerName_:function(){var containerMemoryDumps=this.currentSelection_;var dumpView=this.ownerDocument.createElement('tr-ui-a-stacked-pane-view');this.$.content.appendChild(dumpView);dumpView.setPaneBuilder(function(){var headerPane=document.createElement('tr-ui-a-memory-dump-header-pane');headerPane.containerMemoryDumps=containerMemoryDumps;return headerPane;});},buildViewForMultipleContainerNames_:function(){var ownerDocument=this.ownerDocument;var rows=tr.b.dictionaryValues(tr.b.mapItems(this.dumpsByContainerName_,function(containerName,dumps){return{containerName:containerName,subRows:dumps,isExpanded:true};}));rows.sort(function(a,b){return a.containerName.localeCompare(b.containerName);});var columns=[{title:'Dump',value:function(row){if(row.subRows===undefined)
+return this.singleDumpValue_(row);else
+return this.groupedDumpValue_(row);},singleDumpValue_:function(row){var linkEl=ownerDocument.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(new tr.model.EventSet([row]));linkEl.appendChild(tr.ui.units.createTimeStampSpan(row.start,{ownerDocument:ownerDocument}));return linkEl;},groupedDumpValue_:function(row){var linkEl=ownerDocument.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(new tr.model.EventSet(row.subRows));linkEl.appendChild(tr.ui.b.createSpan({ownerDocument:ownerDocument,textContent:row.subRows.length+' memory dump'+
+(row.subRows.length===1?'':'s')+' in '}));linkEl.appendChild(tr.ui.b.createSpan({ownerDocument:ownerDocument,textContent:row.containerName,bold:true}));return linkEl;}}];var table=this.ownerDocument.createElement('tr-ui-b-table');table.tableColumns=columns;table.tableRows=rows;table.showHeader=false;table.rebuild();this.$.content.appendChild(table);}});return{};});'use strict';var EventSet=tr.model.EventSet;Polymer('tr-ui-a-power-sample-table',{ready:function(){this.$.table.tableColumns=[{title:'Time',width:'100px',value:function(row){return tr.ui.units.createTimeStampSpan(row.start);}},{title:'Power (mW)',width:'100%',value:function(row){return row.power;}}];this.samples=new EventSet();},get samples(){return this.samples_;},set samples(samples){this.samples_=(samples===undefined)?new EventSet():samples;this.updateContents_();},updateContents_:function(){this.$.table.tableRows=this.samples.toArray();this.$.table.rebuild();}});'use strict';Polymer('tr-ui-a-single-power-sample-sub-view',{ready:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},updateContents_:function(){this.$.samplesTable.samples=this.selection;}});!function(){function n(n){return null!=n&&!isNaN(n)}function t(n){return n.length}function e(n){for(var t=1;n*t%1;)t*=10;return t}function r(n,t){try{for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}catch(r){n.prototype=t}}function u(){}function i(n){return aa+n in this}function o(n){return n=aa+n,n in this&&delete this[n]}function a(){var n=[];return this.forEach(function(t){n.push(t)}),n}function c(){var n=0;for(var t in this)t.charCodeAt(0)===ca&&++n;return n}function s(){for(var n in this)if(n.charCodeAt(0)===ca)return!1;return!0}function l(){}function f(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function h(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.substring(1);for(var e=0,r=sa.length;r>e;++e){var u=sa[e]+t;if(u in n)return u}}function g(){}function p(){}function v(n){function t(){for(var t,r=e,u=-1,i=r.length;++u<i;)(t=r[u].on)&&t.apply(this,arguments);return n}var e=[],r=new u;return t.on=function(t,u){var i,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,i=e.indexOf(o)).concat(e.slice(i+1)),r.remove(t)),u&&e.push(r.set(t,{on:u})),n)},t}function d(){Xo.event.preventDefault()}function m(){for(var n,t=Xo.event;n=t.sourceEvent;)t=n;return t}function y(n){for(var t=new p,e=0,r=arguments.length;++e<r;)t[arguments[e]]=v(t);return t.of=function(e,r){return function(u){try{var i=u.sourceEvent=Xo.event;u.target=n,Xo.event=u,t[u.type].apply(e,r)}finally{Xo.event=i}}},t}function x(n){return fa(n,da),n}function M(n){return"function"==typeof n?n:function(){return ha(n,this)}}function _(n){return"function"==typeof n?n:function(){return ga(n,this)}}function b(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function u(){this.setAttribute(n,t)}function i(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=Xo.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?i:u}function w(n){return n.trim().replace(/\s+/g," ")}function S(n){return new RegExp("(?:^|\\s+)"+Xo.requote(n)+"(?:\\s+|$)","g")}function k(n){return n.trim().split(/^|\s+/)}function E(n,t){function e(){for(var e=-1;++e<u;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<u;)n[e](this,r)}n=k(n).map(A);var u=n.length;return"function"==typeof t?r:e}function A(n){var t=S(n);return function(e,r){if(u=e.classList)return r?u.add(n):u.remove(n);var u=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(u)||e.setAttribute("class",w(u+" "+n))):e.setAttribute("class",w(u.replace(t," ")))}}function C(n,t,e){function r(){this.style.removeProperty(n)}function u(){this.style.setProperty(n,t,e)}function i(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?i:u}function N(n,t){function e(){delete this[n]}function r(){this[n]=t}function u(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?u:r}function L(n){return"function"==typeof n?n:(n=Xo.ns.qualify(n)).local?function(){return this.ownerDocument.createElementNS(n.space,n.local)}:function(){return this.ownerDocument.createElementNS(this.namespaceURI,n)}}function T(n){return{__data__:n}}function q(n){return function(){return va(this,n)}}function z(n){return arguments.length||(n=Xo.ascending),function(t,e){return t&&e?n(t.__data__,e.__data__):!t-!e}}function R(n,t){for(var e=0,r=n.length;r>e;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function D(n){return fa(n,ya),n}function P(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t<c;);return o}}function U(){var n=this.__transition__;n&&++n.active}function j(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function u(){var u=c(t,Bo(arguments));r.call(this),this.addEventListener(n,this[o]=u,u.$=e),u._=t}function i(){var t,e=new RegExp("^__on([^.]+)"+Xo.requote(n)+"$");for(var r in this)if(t=r.match(e)){var u=this[r];this.removeEventListener(t[1],u,u.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),c=H;a>0&&(n=n.substring(0,a));var s=Ma.get(n);return s&&(n=s,c=F),a?t?u:r:t?g:i}function H(n,t){return function(e){var r=Xo.event;Xo.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{Xo.event=r}}}function F(n,t){var e=H(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function O(){var n=".dragsuppress-"+ ++ba,t="click"+n,e=Xo.select(Go).on("touchmove"+n,d).on("dragstart"+n,d).on("selectstart"+n,d);if(_a){var r=Jo.style,u=r[_a];r[_a]="none"}return function(i){function o(){e.on(t,null)}e.on(n,null),_a&&(r[_a]=u),i&&(e.on(t,function(){d(),o()},!0),setTimeout(o,0))}}function Y(n,t){t.changedTouches&&(t=t.changedTouches[0]);var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>wa&&(Go.scrollX||Go.scrollY)){e=Xo.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var u=e[0][0].getScreenCTM();wa=!(u.f||u.e),e.remove()}return wa?(r.x=t.pageX,r.y=t.pageY):(r.x=t.clientX,r.y=t.clientY),r=r.matrixTransform(n.getScreenCTM().inverse()),[r.x,r.y]}var i=n.getBoundingClientRect();return[t.clientX-i.left-n.clientLeft,t.clientY-i.top-n.clientTop]}function I(n){return n>0?1:0>n?-1:0}function Z(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function V(n){return n>1?0:-1>n?Sa:Math.acos(n)}function X(n){return n>1?Ea:-1>n?-Ea:Math.asin(n)}function $(n){return((n=Math.exp(n))-1/n)/2}function B(n){return((n=Math.exp(n))+1/n)/2}function W(n){return((n=Math.exp(2*n))-1)/(n+1)}function J(n){return(n=Math.sin(n/2))*n}function G(){}function K(n,t,e){return new Q(n,t,e)}function Q(n,t,e){this.h=n,this.s=t,this.l=e}function nt(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,gt(u(n+120),u(n),u(n-120))}function tt(n,t,e){return new et(n,t,e)}function et(n,t,e){this.h=n,this.c=t,this.l=e}function rt(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),ut(e,Math.cos(n*=Na)*t,Math.sin(n)*t)}function ut(n,t,e){return new it(n,t,e)}function it(n,t,e){this.l=n,this.a=t,this.b=e}function ot(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=ct(u)*Fa,r=ct(r)*Oa,i=ct(i)*Ya,gt(lt(3.2404542*u-1.5371385*r-.4985314*i),lt(-.969266*u+1.8760108*r+.041556*i),lt(.0556434*u-.2040259*r+1.0572252*i))}function at(n,t,e){return n>0?tt(Math.atan2(e,t)*La,Math.sqrt(t*t+e*e),n):tt(0/0,0/0,n)}function ct(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function st(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function lt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function ft(n){return gt(n>>16,255&n>>8,255&n)}function ht(n){return ft(n)+""}function gt(n,t,e){return new pt(n,t,e)}function pt(n,t,e){this.r=n,this.g=t,this.b=e}function vt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function dt(n,t,e){var r,u,i,o,a=0,c=0,s=0;if(u=/([a-z]+)\((.*)\)/i.exec(n))switch(i=u[2].split(","),u[1]){case"hsl":return e(parseFloat(i[0]),parseFloat(i[1])/100,parseFloat(i[2])/100);case"rgb":return t(Mt(i[0]),Mt(i[1]),Mt(i[2]))}return(o=Va.get(n))?t(o.r,o.g,o.b):(null!=n&&"#"===n.charAt(0)&&(r=parseInt(n.substring(1),16),isNaN(r)||(4===n.length?(a=(3840&r)>>4,a=a>>4|a,c=240&r,c=c>>4|c,s=15&r,s=s<<4|s):7===n.length&&(a=(16711680&r)>>16,c=(65280&r)>>8,s=255&r))),t(a,c,s))}function mt(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),K(r,u,c)}function yt(n,t,e){n=xt(n),t=xt(t),e=xt(e);var r=st((.4124564*n+.3575761*t+.1804375*e)/Fa),u=st((.2126729*n+.7151522*t+.072175*e)/Oa),i=st((.0193339*n+.119192*t+.9503041*e)/Ya);return ut(116*u-16,500*(r-u),200*(u-i))}function xt(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function Mt(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function _t(n){return"function"==typeof n?n:function(){return n}}function bt(n){return n}function wt(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),St(t,e,n,r)}}function St(n,t,e,r){function u(){var n,t=c.status;if(!t&&c.responseText||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return o.error.call(i,r),void 0}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=Xo.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,s=null;return!Go.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=Xo.event;Xo.event=n;try{o.progress.call(i,c)}finally{Xo.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(s=n,i):s},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(Bo(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var l in a)c.setRequestHeader(l,a[l]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=s&&(c.responseType=s),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},Xo.rebind(i,o,"on"),null==r?i:i.get(kt(r))}function kt(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Et(){var n=At(),t=Ct()-n;t>24?(isFinite(t)&&(clearTimeout(Wa),Wa=setTimeout(Et,t)),Ba=0):(Ba=1,Ga(Et))}function At(){var n=Date.now();for(Ja=Xa;Ja;)n>=Ja.t&&(Ja.f=Ja.c(n-Ja.t)),Ja=Ja.n;return n}function Ct(){for(var n,t=Xa,e=1/0;t;)t.f?t=n?n.n=t.n:Xa=t.n:(t.t<e&&(e=t.t),t=(n=t).n);return $a=n,e}function Nt(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Lt(n,t){var e=Math.pow(10,3*oa(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Tt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r?function(n){for(var t=n.length,u=[],i=0,o=r[0];t>0&&o>0;)u.push(n.substring(t-=o,t+o)),o=r[i=(i+1)%r.length];return u.reverse().join(e)}:bt;return function(n){var e=Qa.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"",c=e[4]||"",s=e[5],l=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1;switch(h&&(h=+h.substring(1)),(s||"0"===r&&"="===o)&&(s=r="0",o="=",f&&(l-=Math.floor((l-1)/4))),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=nc.get(g)||qt;var y=s&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):a;if(0>p){var c=Xo.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x=n.lastIndexOf("."),M=0>x?n:n.substring(0,x),_=0>x?"":t+n.substring(x+1);!s&&f&&(M=i(M));var b=v.length+M.length+_.length+(y?0:u.length),w=l>b?new Array(b=l-b+1).join(r):"";return y&&(M=i(w+M)),u+=v,n=M+_,("<"===o?u+n+w:">"===o?w+u+n:"^"===o?w.substring(0,b>>=1)+u+n+w.substring(b):u+(y?n:w+n))+e}}}function qt(n){return n+""}function zt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Rt(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new ec(e-1)),1),e}function i(n,e){return t(n=new ec(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{ec=zt;var r=new zt;return r._=n,o(r,t,e)}finally{ec=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Dt(n);return c.floor=c,c.round=Dt(r),c.ceil=Dt(u),c.offset=Dt(i),c.range=a,n}function Dt(n){return function(t,e){try{ec=zt;var r=new zt;return r._=t,n(r,e)._}finally{ec=Date}}}function Pt(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.substring(c,a)),null!=(u=uc[e=n.charAt(++a)])&&(e=n.charAt(++a)),(i=C[e])&&(e=i(t,null==u?"e"===e?" ":"0":u)),o.push(e),c=a+1);return o.push(n.substring(c,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},u=e(r,n,t,0);if(u!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var i=null!=r.Z&&ec!==zt,o=new(i?zt:ec);return"j"in r?o.setFullYear(r.y,0,r.j):"w"in r&&("W"in r||"U"in r)?(o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+Math.floor(r.Z/100),r.M+r.Z%100,r.S,r.L),i?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var u,i,o,a=0,c=t.length,s=e.length;c>a;){if(r>=s)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=N[o in uc?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){b.lastIndex=0;var r=b.exec(t.substring(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){M.lastIndex=0;var r=M.exec(t.substring(e));return r?(n.w=_.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.substring(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.substring(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,C.c.toString(),t,r)}function c(n,t,r){return e(n,C.x.toString(),t,r)}function s(n,t,r){return e(n,C.X.toString(),t,r)}function l(n,t,e){var r=x.get(t.substring(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{ec=zt;var t=new ec;return t._=n,r(t)}finally{ec=Date}}var r=t(n);return e.parse=function(n){try{ec=zt;var t=r.parse(n);return t&&t._}finally{ec=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ee;var x=Xo.map(),M=jt(v),_=Ht(v),b=jt(d),w=Ht(d),S=jt(m),k=Ht(m),E=jt(y),A=Ht(y);p.forEach(function(n,t){x.set(n.toLowerCase(),t)});var C={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return Ut(n.getDate(),t,2)},e:function(n,t){return Ut(n.getDate(),t,2)},H:function(n,t){return Ut(n.getHours(),t,2)},I:function(n,t){return Ut(n.getHours()%12||12,t,2)},j:function(n,t){return Ut(1+tc.dayOfYear(n),t,3)},L:function(n,t){return Ut(n.getMilliseconds(),t,3)},m:function(n,t){return Ut(n.getMonth()+1,t,2)},M:function(n,t){return Ut(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return Ut(n.getSeconds(),t,2)},U:function(n,t){return Ut(tc.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Ut(tc.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return Ut(n.getFullYear()%100,t,2)},Y:function(n,t){return Ut(n.getFullYear()%1e4,t,4)},Z:ne,"%":function(){return"%"}},N={a:r,A:u,b:i,B:o,c:a,d:Bt,e:Bt,H:Jt,I:Jt,j:Wt,L:Qt,m:$t,M:Gt,p:l,S:Kt,U:Ot,w:Ft,W:Yt,x:c,X:s,y:Zt,Y:It,Z:Vt,"%":te};return t}function Ut(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function jt(n){return new RegExp("^(?:"+n.map(Xo.requote).join("|")+")","i")}function Ht(n){for(var t=new u,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function Ft(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Ot(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e));return r?(n.U=+r[0],e+r[0].length):-1}function Yt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e));return r?(n.W=+r[0],e+r[0].length):-1}function It(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Zt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.y=Xt(+r[0]),e+r[0].length):-1}function Vt(n,t,e){return/^[+-]\d{4}$/.test(t=t.substring(e,e+5))?(n.Z=+t,e+5):-1}function Xt(n){return n+(n>68?1900:2e3)}function $t(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Bt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function Wt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function Jt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function Gt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function Kt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function Qt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ne(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=~~(oa(t)/60),u=oa(t)%60;return e+Ut(r,"0",2)+Ut(u,"0",2)}function te(n,t,e){oc.lastIndex=0;var r=oc.exec(t.substring(e,e+1));return r?e+r[0].length:-1}function ee(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function re(){}function ue(n,t,e){var r=e.s=n+t,u=r-n,i=r-u;e.t=n-i+(t-u)}function ie(n,t){n&&lc.hasOwnProperty(n.type)&&lc[n.type](n,t)}function oe(n,t,e){var r,u=-1,i=n.length-e;for(t.lineStart();++u<i;)r=n[u],t.point(r[0],r[1],r[2]);t.lineEnd()}function ae(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)oe(n[e],t,1);t.polygonEnd()}function ce(){function n(n,t){n*=Na,t=t*Na/2+Sa/4;var e=n-r,o=e>=0?1:-1,a=o*e,c=Math.cos(t),s=Math.sin(t),l=i*s,f=u*c+l*Math.cos(a),h=l*o*Math.sin(a);hc.add(Math.atan2(h,f)),r=n,u=c,i=s}var t,e,r,u,i;gc.point=function(o,a){gc.point=n,r=(t=o)*Na,u=Math.cos(a=(e=a)*Na/2+Sa/4),i=Math.sin(a)},gc.lineEnd=function(){n(t,e)}}function se(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function le(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function fe(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function he(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ge(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function pe(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function ve(n){return[Math.atan2(n[1],n[0]),X(n[2])]}function de(n,t){return oa(n[0]-t[0])<Aa&&oa(n[1]-t[1])<Aa}function me(n,t){n*=Na;var e=Math.cos(t*=Na);ye(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function ye(n,t,e){++pc,dc+=(n-dc)/pc,mc+=(t-mc)/pc,yc+=(e-yc)/pc}function xe(){function n(n,u){n*=Na;var i=Math.cos(u*=Na),o=i*Math.cos(n),a=i*Math.sin(n),c=Math.sin(u),s=Math.atan2(Math.sqrt((s=e*c-r*a)*s+(s=r*o-t*c)*s+(s=t*a-e*o)*s),t*o+e*a+r*c);vc+=s,xc+=s*(t+(t=o)),Mc+=s*(e+(e=a)),_c+=s*(r+(r=c)),ye(t,e,r)}var t,e,r;kc.point=function(u,i){u*=Na;var o=Math.cos(i*=Na);t=o*Math.cos(u),e=o*Math.sin(u),r=Math.sin(i),kc.point=n,ye(t,e,r)}}function Me(){kc.point=me}function _e(){function n(n,t){n*=Na;var e=Math.cos(t*=Na),o=e*Math.cos(n),a=e*Math.sin(n),c=Math.sin(t),s=u*c-i*a,l=i*o-r*c,f=r*a-u*o,h=Math.sqrt(s*s+l*l+f*f),g=r*o+u*a+i*c,p=h&&-V(g)/h,v=Math.atan2(h,g);bc+=p*s,wc+=p*l,Sc+=p*f,vc+=v,xc+=v*(r+(r=o)),Mc+=v*(u+(u=a)),_c+=v*(i+(i=c)),ye(r,u,i)}var t,e,r,u,i;kc.point=function(o,a){t=o,e=a,kc.point=n,o*=Na;var c=Math.cos(a*=Na);r=c*Math.cos(o),u=c*Math.sin(o),i=Math.sin(a),ye(r,u,i)},kc.lineEnd=function(){n(t,e),kc.lineEnd=Me,kc.point=me}}function be(){return!0}function we(n,t,e,r,u){var i=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(de(e,r)){u.lineStart();for(var a=0;t>a;++a)u.point((e=n[a])[0],e[1]);return u.lineEnd(),void 0}var c=new ke(e,n,null,!0),s=new ke(e,null,c,!1);c.o=s,i.push(c),o.push(s),c=new ke(r,n,null,!1),s=new ke(r,null,c,!0),c.o=s,i.push(c),o.push(s)}}),o.sort(t),Se(i),Se(o),i.length){for(var a=0,c=e,s=o.length;s>a;++a)o[a].e=c=!c;for(var l,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;l=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,s=l.length;s>a;++a)u.point((f=l[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){l=g.p.z;for(var a=l.length-1;a>=0;--a)u.point((f=l[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,l=g.z,p=!p}while(!g.v);u.lineEnd()}}}function Se(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r<t;)u.n=e=n[r],e.p=u,u=e;u.n=e=n[0],e.p=u}}function ke(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Ee(n,t,e,r){return function(u,i){function o(t,e){var r=u(t,e);n(t=r[0],e=r[1])&&i.point(t,e)}function a(n,t){var e=u(n,t);d.point(e[0],e[1])}function c(){y.point=a,d.lineStart()}function s(){y.point=o,d.lineEnd()}function l(n,t){v.push([n,t]);var e=u(n,t);M.point(e[0],e[1])}function f(){M.lineStart(),v=[]}function h(){l(v[0][0],v[0][1]),M.lineEnd();var n,t=M.clean(),e=x.buffer(),r=e.length;if(v.pop(),p.push(v),v=null,r){if(1&t){n=e[0];var u,r=n.length-1,o=-1;for(i.lineStart();++o<r;)i.point((u=n[o])[0],u[1]);return i.lineEnd(),void 0}r>1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Ae))}}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:s,polygonStart:function(){y.point=l,y.lineStart=f,y.lineEnd=h,g=[],p=[],i.polygonStart()},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=s,g=Xo.merge(g);var n=Le(m,p);g.length?we(g,Ne,n,e,i):n&&(i.lineStart(),e(null,null,1,i),i.lineEnd()),i.polygonEnd(),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},x=Ce(),M=t(x);return y}}function Ae(n){return n.length>1}function Ce(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:g,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Ne(n,t){return((n=n.x)[0]<0?n[1]-Ea-Aa:Ea-n[1])-((t=t.x)[0]<0?t[1]-Ea-Aa:Ea-t[1])}function Le(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;hc.reset();for(var a=0,c=t.length;c>a;++a){var s=t[a],l=s.length;if(l)for(var f=s[0],h=f[0],g=f[1]/2+Sa/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===l&&(d=0),n=s[d];var m=n[0],y=n[1]/2+Sa/4,x=Math.sin(y),M=Math.cos(y),_=m-h,b=_>=0?1:-1,w=b*_,S=w>Sa,k=p*x;if(hc.add(Math.atan2(k*b*Math.sin(w),v*M+k*Math.cos(w))),i+=S?_+b*ka:_,S^h>=e^m>=e){var E=fe(se(f),se(n));pe(E);var A=fe(u,E);pe(A);var C=(S^_>=0?-1:1)*X(A[2]);(r>C||r===C&&(E[0]||E[1]))&&(o+=S^_>=0?1:-1)}if(!d++)break;h=m,p=x,v=M,f=n}}return(-Aa>i||Aa>i&&0>hc)^1&o}function Te(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?Sa:-Sa,c=oa(i-e);oa(c-Sa)<Aa?(n.point(e,r=(r+o)/2>0?Ea:-Ea),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=Sa&&(oa(e-u)<Aa&&(e-=u*Aa),oa(i-a)<Aa&&(i-=a*Aa),r=qe(e,r,i,o),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=i,r=o),u=a},lineEnd:function(){n.lineEnd(),e=r=0/0},clean:function(){return 2-t}}}function qe(n,t,e,r){var u,i,o=Math.sin(n-e);return oa(o)>Aa?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function ze(n,t,e,r){var u;if(null==n)u=e*Ea,r.point(-Sa,u),r.point(0,u),r.point(Sa,u),r.point(Sa,0),r.point(Sa,-u),r.point(0,-u),r.point(-Sa,-u),r.point(-Sa,0),r.point(-Sa,u);else if(oa(n[0]-t[0])>Aa){var i=n[0]<t[0]?Sa:-Sa;u=e*i/2,r.point(-i,u),r.point(0,u),r.point(i,u)}else r.point(t[0],t[1])}function Re(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,s,l;return{lineStart:function(){s=c=!1,l=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?Sa:-Sa),h):0;if(!e&&(s=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(de(e,g)||de(p,g))&&(p[0]+=Aa,p[1]+=Aa,v=t(p[0],p[1]))),v!==c)l=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(l=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&de(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return l|(s&&c)<<1}}}function r(n,t,e){var r=se(n),u=se(t),o=[1,0,0],a=fe(r,u),c=le(a,a),s=a[0],l=c-s*s;if(!l)return!e&&n;var f=i*c/l,h=-i*s/l,g=fe(o,a),p=ge(o,f),v=ge(a,h);he(p,v);var d=g,m=le(p,d),y=le(d,d),x=m*m-y*(le(p,p)-1);if(!(0>x)){var M=Math.sqrt(x),_=ge(d,(-m-M)/y);if(he(_,p),_=ve(_),!e)return _;var b,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(b=w,w=S,S=b);var A=S-w,C=oa(A-Sa)<Aa,N=C||Aa>A;if(!C&&k>E&&(b=k,k=E,E=b),N?C?k+E>0^_[1]<(oa(_[0]-w)<Aa?k:E):k<=_[1]&&_[1]<=E:A>Sa^(w<=_[0]&&_[0]<=S)){var L=ge(d,(-m+M)/y);return he(L,p),[_,ve(L)]}}}function u(t,e){var r=o?n:Sa-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=oa(i)>Aa,c=cr(n,6*Na);return Ee(t,e,c,o?[0,-n]:[-Sa,n-Sa])}function De(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,s=o.y,l=a.x,f=a.y,h=0,g=1,p=l-c,v=f-s;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-s,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-s,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:s+h*v}),1>g&&(u.b={x:c+g*p,y:s+g*v}),u}}}}}}function Pe(n,t,e,r){function u(r,u){return oa(r[0]-n)<Aa?u>0?0:3:oa(r[0]-e)<Aa?u>0?2:1:oa(r[1]-t)<Aa?u>0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,s=a[0];c>o;++o)i=a[o],s[1]<=r?i[1]>r&&Z(s,i,n)>0&&++t:i[1]<=r&&Z(s,i,n)<0&&--t,s=i;return 0!==t}function s(i,a,c,s){var l=0,f=0;if(null==i||(l=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do s.point(0===l||3===l?n:e,l>1?r:t);while((l=(l+c+4)%4)!==f)}else s.point(a[0],a[1])}function l(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){l(n,t)&&a.point(n,t)}function h(){N.point=p,d&&d.push(m=[]),S=!0,w=!1,_=b=0/0}function g(){v&&(p(y,x),M&&w&&A.rejoin(),v.push(A.buffer())),N.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Ac,Math.min(Ac,n)),t=Math.max(-Ac,Math.min(Ac,t));var e=l(n,t);if(d&&m.push([n,t]),S)y=n,x=t,M=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:_,y:b},b:{x:n,y:t}};C(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}_=n,b=t,w=e}var v,d,m,y,x,M,_,b,w,S,k,E=a,A=Ce(),C=De(n,t,e,r),N={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=Xo.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),s(null,null,1,a),a.lineEnd()),u&&we(v,i,t,s,a),a.polygonEnd()),v=d=m=null}};return N}}function Ue(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function je(n){var t=0,e=Sa/3,r=nr(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*Sa/180,e=n[1]*Sa/180):[180*(t/Sa),180*(e/Sa)]},u}function He(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,X((i-(n*n+e*e)*u*u)/(2*u))]},e}function Fe(){function n(n,t){Nc+=u*n-r*t,r=n,u=t}var t,e,r,u;Rc.point=function(i,o){Rc.point=n,t=r=i,e=u=o},Rc.lineEnd=function(){n(t,e)}}function Oe(n,t){Lc>n&&(Lc=n),n>qc&&(qc=n),Tc>t&&(Tc=t),t>zc&&(zc=t)}function Ye(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Ie(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Ie(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Ie(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Ze(n,t){dc+=n,mc+=t,++yc}function Ve(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);xc+=o*(t+n)/2,Mc+=o*(e+r)/2,_c+=o,Ze(t=n,e=r)}var t,e;Pc.point=function(r,u){Pc.point=n,Ze(t=r,e=u)}}function Xe(){Pc.point=Ze}function $e(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);xc+=o*(r+n)/2,Mc+=o*(u+t)/2,_c+=o,o=u*n-r*t,bc+=o*(r+n),wc+=o*(u+t),Sc+=3*o,Ze(r=n,u=t)}var t,e,r,u;Pc.point=function(i,o){Pc.point=n,Ze(t=r=i,e=u=o)},Pc.lineEnd=function(){n(t,e)}}function Be(n){function t(t,e){n.moveTo(t,e),n.arc(t,e,o,0,ka)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:g};return a}function We(n){function t(n){return(a?r:e)(n)}function e(t){return Ke(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){x=0/0,S.point=i,t.lineStart()}function i(e,r){var i=se([e,r]),o=n(e,r);u(x,M,y,_,b,w,x=o[0],M=o[1],y=e,_=i[0],b=i[1],w=i[2],a,t),t.point(x,M)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=s,S.lineEnd=l}function s(n,t){i(f=n,h=t),g=x,p=M,v=_,d=b,m=w,S.point=i}function l(){u(x,M,y,_,b,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,x,M,_,b,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,s,l,f,h,g,p,v,d,m){var y=l-t,x=f-e,M=y*y+x*x;if(M>4*i&&d--){var _=a+g,b=c+p,w=s+v,S=Math.sqrt(_*_+b*b+w*w),k=Math.asin(w/=S),E=oa(oa(w)-1)<Aa||oa(r-h)<Aa?(r+h)/2:Math.atan2(b,_),A=n(E,k),C=A[0],N=A[1],L=C-t,T=N-e,q=x*L-y*T;(q*q/M>i||oa((y*L+x*T)/M-.5)>.3||o>a*g+c*p+s*v)&&(u(t,e,r,a,c,s,C,N,E,_/=S,b/=S,w,d,m),m.point(C,N),u(C,N,E,_,b,w,l,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Na),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function Je(n){var t=We(function(t,e){return n([t*La,e*La])});return function(n){return tr(t(n))}}function Ge(n){this.stream=n}function Ke(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function Qe(n){return nr(function(){return n})()}function nr(n){function t(n){return n=a(n[0]*Na,n[1]*Na),[n[0]*h+c,s-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(s-n[1])/h),n&&[n[0]*La,n[1]*La]}function r(){a=Ue(o=ur(m,y,x),i);var n=i(v,d);return c=g-n[0]*h,s=p+n[1]*h,u()}function u(){return l&&(l.valid=!1,l=null),t}var i,o,a,c,s,l,f=We(function(n,t){return n=i(n,t),[n[0]*h+c,s-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,y=0,x=0,M=Ec,_=bt,b=null,w=null;return t.stream=function(n){return l&&(l.valid=!1),l=tr(M(o,f(_(n)))),l.valid=!0,l},t.clipAngle=function(n){return arguments.length?(M=null==n?(b=n,Ec):Re((b=+n)*Na),u()):b},t.clipExtent=function(n){return arguments.length?(w=n,_=n?Pe(n[0][0],n[0][1],n[1][0],n[1][1]):bt,u()):w},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Na,d=n[1]%360*Na,r()):[v*La,d*La]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Na,y=n[1]%360*Na,x=n.length>2?n[2]%360*Na:0,r()):[m*La,y*La,x*La]},Xo.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function tr(n){return Ke(n,function(t,e){n.point(t*Na,e*Na)})}function er(n,t){return[n,t]}function rr(n,t){return[n>Sa?n-ka:-Sa>n?n+ka:n,t]}function ur(n,t,e){return n?t||e?Ue(or(n),ar(t,e)):or(n):t||e?ar(t,e):rr}function ir(n){return function(t,e){return t+=n,[t>Sa?t-ka:-Sa>t?t+ka:t,e]}}function or(n){var t=ir(n);return t.invert=ir(-n),t}function ar(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*r+a*u;return[Math.atan2(c*i-l*o,a*r-s*u),X(l*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*i-c*o;return[Math.atan2(c*i+s*o,a*r+l*u),X(l*r-a*u)]},e}function cr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=sr(e,u),i=sr(e,i),(o>0?i>u:u>i)&&(u+=o*ka)):(u=n+o*ka,i=n-.5*c);for(var s,l=u;o>0?l>i:i>l;l-=c)a.point((s=ve([e,-r*Math.cos(l),-r*Math.sin(l)]))[0],s[1])}}function sr(n,t){var e=se(t);e[0]-=n,pe(e);var r=V(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Aa)%(2*Math.PI)}function lr(n,t,e){var r=Xo.range(n,t-Aa,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function fr(n,t,e){var r=Xo.range(n,t-Aa,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function hr(n){return n.source}function gr(n){return n.target}function pr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),s=u*Math.sin(n),l=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(J(r-t)+u*o*J(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*l,u=e*s+t*f,o=e*i+t*a;return[Math.atan2(u,r)*La,Math.atan2(o,Math.sqrt(r*r+u*u))*La]}:function(){return[n*La,t*La]};return p.distance=h,p}function vr(){function n(n,u){var i=Math.sin(u*=Na),o=Math.cos(u),a=oa((n*=Na)-t),c=Math.cos(a);Uc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;jc.point=function(u,i){t=u*Na,e=Math.sin(i*=Na),r=Math.cos(i),jc.point=n},jc.lineEnd=function(){jc.point=jc.lineEnd=g}}function dr(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function mr(n,t){function e(n,t){var e=oa(oa(t)-Ea)<Aa?0:o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(Sa/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=I(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Ea]},e):xr}function yr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return oa(u)<Aa?er:(e.invert=function(n,t){var e=i-t;return[Math.atan2(n,e)/u,i-I(u)*Math.sqrt(n*n+e*e)]},e)}function xr(n,t){return[n,Math.log(Math.tan(Sa/4+t/2))]}function Mr(n){var t,e=Qe(n),r=e.scale,u=e.translate,i=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=u.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=i.apply(e,arguments);if(o===e){if(t=null==n){var a=Sa*r(),c=u();i([[c[0]-a,c[1]-a],[c[0]+a,c[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function _r(n,t){return[Math.log(Math.tan(Sa/4+t/2)),-n]}function br(n){return n[0]}function wr(n){return n[1]}function Sr(n){for(var t=n.length,e=[0,1],r=2,u=2;t>u;u++){for(;r>1&&Z(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function kr(n,t){return n[0]-t[0]||n[1]-t[1]}function Er(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Ar(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],s=e[1],l=t[1]-c,f=r[1]-s,h=(a*(c-s)-f*(u-i))/(f*o-a*l);return[u+h*o,c+h*l]}function Cr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Nr(){Jr(this),this.edge=this.site=this.circle=null}function Lr(n){var t=Jc.pop()||new Nr;return t.site=n,t}function Tr(n){Or(n),$c.remove(n),Jc.push(n),Jr(n)}function qr(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Tr(n);for(var c=i;c.circle&&oa(e-c.circle.x)<Aa&&oa(r-c.circle.cy)<Aa;)i=c.P,a.unshift(c),Tr(c),c=i;a.unshift(c),Or(c);for(var s=o;s.circle&&oa(e-s.circle.x)<Aa&&oa(r-s.circle.cy)<Aa;)o=s.N,a.push(s),Tr(s),s=o;a.push(s),Or(s);var l,f=a.length;for(l=1;f>l;++l)s=a[l],c=a[l-1],$r(s.edge,c.site,s.site,u);c=a[0],s=a[f-1],s.edge=Vr(c.site,s.site,null,u),Fr(c),Fr(s)}function zr(n){for(var t,e,r,u,i=n.x,o=n.y,a=$c._;a;)if(r=Rr(a,o)-i,r>Aa)a=a.L;else{if(u=i-Dr(a,o),!(u>Aa)){r>-Aa?(t=a.P,e=a):u>-Aa?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Lr(n);if($c.insert(t,c),t||e){if(t===e)return Or(t),e=Lr(t.site),$c.insert(c,e),c.edge=e.edge=Vr(t.site,c.site),Fr(t),Fr(e),void 0;if(!e)return c.edge=Vr(t.site,c.site),void 0;Or(t),Or(e);var s=t.site,l=s.x,f=s.y,h=n.x-l,g=n.y-f,p=e.site,v=p.x-l,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,x=v*v+d*d,M={x:(d*y-g*x)/m+l,y:(h*x-v*y)/m+f};$r(e.edge,s,p,M),c.edge=Vr(s,n,null,M),e.edge=Vr(n,p,null,M),Fr(t),Fr(e)}}function Rr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,s=c-t;if(!s)return a;var l=a-r,f=1/i-1/s,h=l/s;return f?(-h+Math.sqrt(h*h-2*f*(l*l/(-2*s)-c+s/2+u-i/2)))/f+r:(r+a)/2}function Dr(n,t){var e=n.N;if(e)return Rr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Pr(n){this.site=n,this.edges=[]}function Ur(n){for(var t,e,r,u,i,o,a,c,s,l,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Xc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)l=a[o].end(),r=l.x,u=l.y,s=a[++o%c].start(),t=s.x,e=s.y,(oa(r-t)>Aa||oa(u-e)>Aa)&&(a.splice(o,0,new Br(Xr(i.site,l,oa(r-f)<Aa&&p-u>Aa?{x:f,y:oa(t-f)<Aa?e:p}:oa(u-p)<Aa&&h-r>Aa?{x:oa(e-p)<Aa?t:h,y:p}:oa(r-h)<Aa&&u-g>Aa?{x:h,y:oa(t-h)<Aa?e:g}:oa(u-g)<Aa&&r-f>Aa?{x:oa(e-g)<Aa?t:f,y:g}:null),i.site,null)),++c)}function jr(n,t){return t.angle-n.angle}function Hr(){Jr(this),this.x=this.y=this.arc=this.site=this.cy=null}function Fr(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,u=n.site,i=e.site;if(r!==i){var o=u.x,a=u.y,c=r.x-o,s=r.y-a,l=i.x-o,f=i.y-a,h=2*(c*f-s*l);if(!(h>=-Ca)){var g=c*c+s*s,p=l*l+f*f,v=(f*g-s*p)/h,d=(c*p-l*g)/h,f=d+a,m=Gc.pop()||new Hr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,x=Wc._;x;)if(m.y<x.y||m.y===x.y&&m.x<=x.x){if(!x.L){y=x.P;break}x=x.L}else{if(!x.R){y=x;break}x=x.R}Wc.insert(y,m),y||(Bc=m)}}}}function Or(n){var t=n.circle;t&&(t.P||(Bc=t.N),Wc.remove(t),Gc.push(t),Jr(t),n.circle=null)}function Yr(n){for(var t,e=Vc,r=De(n[0][0],n[0][1],n[1][0],n[1][1]),u=e.length;u--;)t=e[u],(!Ir(t,n)||!r(t)||oa(t.a.x-t.b.x)<Aa&&oa(t.a.y-t.b.y)<Aa)&&(t.a=t.b=null,e.splice(u,1))}function Ir(n,t){var e=n.b;if(e)return!0;var r,u,i=n.a,o=t[0][0],a=t[1][0],c=t[0][1],s=t[1][1],l=n.l,f=n.r,h=l.x,g=l.y,p=f.x,v=f.y,d=(h+p)/2,m=(g+v)/2;if(v===g){if(o>d||d>=a)return;if(h>p){if(i){if(i.y>=s)return}else i={x:d,y:c};e={x:d,y:s}}else{if(i){if(i.y<c)return}else i={x:d,y:s};e={x:d,y:c}}}else if(r=(h-p)/(v-g),u=m-r*d,-1>r||r>1)if(h>p){if(i){if(i.y>=s)return}else i={x:(c-u)/r,y:c};e={x:(s-u)/r,y:s}}else{if(i){if(i.y<c)return}else i={x:(s-u)/r,y:s};e={x:(c-u)/r,y:c}}else if(v>g){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.x<o)return}else i={x:a,y:r*a+u};e={x:o,y:r*o+u}}return n.a=i,n.b=e,!0}function Zr(n,t){this.l=n,this.r=t,this.a=this.b=null}function Vr(n,t,e,r){var u=new Zr(n,t);return Vc.push(u),e&&$r(u,n,t,e),r&&$r(u,t,n,r),Xc[n.i].edges.push(new Br(u,n,t)),Xc[t.i].edges.push(new Br(u,t,n)),u}function Xr(n,t,e){var r=new Zr(n,null);return r.a=t,r.b=e,Vc.push(r),r}function $r(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function Br(n,t,e){var r=n.a,u=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(u.x-r.x,r.y-u.y):Math.atan2(r.x-u.x,u.y-r.y)}function Wr(){this._=null}function Jr(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function Gr(n,t){var e=t,r=t.R,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function Kr(n,t){var e=t,r=t.L,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function Qr(n){for(;n.L;)n=n.L;return n}function nu(n,t){var e,r,u,i=n.sort(tu).pop();for(Vc=[],Xc=new Array(n.length),$c=new Wr,Wc=new Wr;;)if(u=Bc,i&&(!u||i.y<u.y||i.y===u.y&&i.x<u.x))(i.x!==e||i.y!==r)&&(Xc[i.i]=new Pr(i),zr(i),e=i.x,r=i.y),i=n.pop();else{if(!u)break;qr(u.arc)}t&&(Yr(t),Ur(t));var o={cells:Xc,edges:Vc};return $c=Wc=Vc=Xc=null,o}function tu(n,t){return t.y-n.y||t.x-n.x}function eu(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function ru(n){return n.x}function uu(n){return n.y}function iu(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function ou(n,t,e,r,u,i){if(!n(t,e,r,u,i)){var o=.5*(e+u),a=.5*(r+i),c=t.nodes;c[0]&&ou(n,c[0],e,r,o,a),c[1]&&ou(n,c[1],o,r,u,a),c[2]&&ou(n,c[2],e,a,o,i),c[3]&&ou(n,c[3],o,a,u,i)}}function au(n,t){n=Xo.rgb(n),t=Xo.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+vt(Math.round(e+i*n))+vt(Math.round(r+o*n))+vt(Math.round(u+a*n))}}function cu(n,t){var e,r={},u={};for(e in n)e in t?r[e]=fu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function su(n,t){return t-=n=+n,function(e){return n+t*e}}function lu(n,t){var e,r,u,i,o,a=0,c=0,s=[],l=[];for(n+="",t+="",Qc.lastIndex=0,r=0;e=Qc.exec(t);++r)e.index&&s.push(t.substring(a,c=e.index)),l.push({i:s.length,x:e[0]}),s.push(null),a=Qc.lastIndex;for(a<t.length&&s.push(t.substring(a)),r=0,i=l.length;(e=Qc.exec(n))&&i>r;++r)if(o=l[r],o.x==e[0]){if(o.i)if(null==s[o.i+1])for(s[o.i-1]+=o.x,s.splice(o.i,1),u=r+1;i>u;++u)l[u].i--;else for(s[o.i-1]+=o.x+s[o.i+1],s.splice(o.i,2),u=r+1;i>u;++u)l[u].i-=2;else if(null==s[o.i+1])s[o.i]=o.x;else for(s[o.i]=o.x+s[o.i+1],s.splice(o.i+1,1),u=r+1;i>u;++u)l[u].i--;l.splice(r,1),i--,r--}else o.x=su(parseFloat(e[0]),parseFloat(o.x));for(;i>r;)o=l.pop(),null==s[o.i+1]?s[o.i]=o.x:(s[o.i]=o.x+s[o.i+1],s.splice(o.i+1,1)),i--;return 1===s.length?null==s[0]?(o=l[0].x,function(n){return o(n)+""}):function(){return t}:function(n){for(r=0;i>r;++r)s[(o=l[r]).i]=o.x(n);return s.join("")}}function fu(n,t){for(var e,r=Xo.interpolators.length;--r>=0&&!(e=Xo.interpolators[r](n,t)););return e}function hu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(fu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function gu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function pu(n){return function(t){return 1-n(1-t)}}function vu(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function du(n){return n*n}function mu(n){return n*n*n}function yu(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function xu(n){return function(t){return Math.pow(t,n)}}function Mu(n){return 1-Math.cos(n*Ea)}function _u(n){return Math.pow(2,10*(n-1))}function bu(n){return 1-Math.sqrt(1-n*n)}function wu(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/ka*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*ka/t)}}function Su(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function ku(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Eu(n,t){n=Xo.hcl(n),t=Xo.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return rt(e+i*n,r+o*n,u+a*n)+""}}function Au(n,t){n=Xo.hsl(n),t=Xo.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return nt(e+i*n,r+o*n,u+a*n)+""}}function Cu(n,t){n=Xo.lab(n),t=Xo.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ot(e+i*n,r+o*n,u+a*n)+""}}function Nu(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Lu(n){var t=[n.a,n.b],e=[n.c,n.d],r=qu(t),u=Tu(t,e),i=qu(zu(e,t,-u))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,u*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*La,this.translate=[n.e,n.f],this.scale=[r,i],this.skew=i?Math.atan2(u,i)*La:0}function Tu(n,t){return n[0]*t[0]+n[1]*t[1]}function qu(n){var t=Math.sqrt(Tu(n,n));return t&&(n[0]/=t,n[1]/=t),t}function zu(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Ru(n,t){var e,r=[],u=[],i=Xo.transform(n),o=Xo.transform(t),a=i.translate,c=o.translate,s=i.rotate,l=o.rotate,f=i.skew,h=o.skew,g=i.scale,p=o.scale;return a[0]!=c[0]||a[1]!=c[1]?(r.push("translate(",null,",",null,")"),u.push({i:1,x:su(a[0],c[0])},{i:3,x:su(a[1],c[1])})):c[0]||c[1]?r.push("translate("+c+")"):r.push(""),s!=l?(s-l>180?l+=360:l-s>180&&(s+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:su(s,l)})):l&&r.push(r.pop()+"rotate("+l+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:su(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:su(g[0],p[0])},{i:e-2,x:su(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i<e;)r[(t=u[i]).i]=t.x(n);return r.join("")}}function Du(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return(e-n)*t}}function Pu(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return Math.max(0,Math.min(1,(e-n)*t))}}function Uu(n){for(var t=n.source,e=n.target,r=Hu(t,e),u=[t];t!==r;)t=t.parent,u.push(t);for(var i=u.length;e!==r;)u.splice(i,0,e),e=e.parent;return u}function ju(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Hu(n,t){if(n===t)return n;for(var e=ju(n),r=ju(t),u=e.pop(),i=r.pop(),o=null;u===i;)o=u,u=e.pop(),i=r.pop();return o}function Fu(n){n.fixed|=2}function Ou(n){n.fixed&=-7}function Yu(n){n.fixed|=4,n.px=n.x,n.py=n.y}function Iu(n){n.fixed&=-5}function Zu(n,t,e){var r=0,u=0;if(n.charge=0,!n.leaf)for(var i,o=n.nodes,a=o.length,c=-1;++c<a;)i=o[c],null!=i&&(Zu(i,t,e),n.charge+=i.charge,r+=i.charge*i.cx,u+=i.charge*i.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var s=t*e[n.point.index];n.charge+=n.pointCharge=s,r+=s*n.point.x,u+=s*n.point.y}n.cx=r/n.charge,n.cy=u/n.charge}function Vu(n,t){return Xo.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=Wu,n}function Xu(n){return n.children}function $u(n){return n.value}function Bu(n,t){return t.value-n.value}function Wu(n){return Xo.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function Ju(n){return n.x}function Gu(n){return n.y}function Ku(n,t,e){n.y0=t,n.y=e}function Qu(n){return Xo.range(n.length)}function ni(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function ti(n){for(var t,e=1,r=0,u=n[0][1],i=n.length;i>e;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function ei(n){return n.reduce(ri,0)}function ri(n,t){return n+t[1]}function ui(n,t){return ii(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function ii(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function oi(n){return[Xo.min(n),Xo.max(n)]}function ai(n,t){return n.parent==t.parent?1:2}function ci(n){var t=n.children;return t&&t.length?t[0]:n._tree.thread}function si(n){var t,e=n.children;return e&&(t=e.length)?e[t-1]:n._tree.thread}function li(n,t){var e=n.children;if(e&&(u=e.length))for(var r,u,i=-1;++i<u;)t(r=li(e[i],t),n)>0&&(n=r);return n}function fi(n,t){return n.x-t.x}function hi(n,t){return t.x-n.x}function gi(n,t){return n.depth-t.depth}function pi(n,t){function e(n,r){var u=n.children;if(u&&(o=u.length))for(var i,o,a=null,c=-1;++c<o;)i=u[c],e(i,a),a=i;t(n,r)}e(n,null)}function vi(n){for(var t,e=0,r=0,u=n.children,i=u.length;--i>=0;)t=u[i]._tree,t.prelim+=e,t.mod+=e,e+=t.shift+(r+=t.change)}function di(n,t,e){n=n._tree,t=t._tree;var r=e/(t.number-n.number);n.change+=r,t.change-=r,t.shift+=e,t.prelim+=e,t.mod+=e}function mi(n,t,e){return n._tree.ancestor.parent==t.parent?n._tree.ancestor:e}function yi(n,t){return n.value-t.value}function xi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function Mi(n,t){n._pack_next=t,t._pack_prev=n}function _i(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function bi(n){function t(n){l=Math.min(n.x-n.r,l),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(s=e.length)){var e,r,u,i,o,a,c,s,l=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(wi),r=e[0],r.x=-r.r,r.y=0,t(r),s>1&&(u=e[1],u.x=u.r,u.y=0,t(u),s>2))for(i=e[2],Ei(r,u,i),t(i),xi(r,i),r._pack_prev=i,xi(i,u),u=r._pack_next,o=3;s>o;o++){Ei(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(_i(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!_i(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.r<r.r?Mi(r,u=a):Mi(r=c,u),o--):(xi(r,i),u=i,t(i))}var m=(l+f)/2,y=(h+g)/2,x=0;for(o=0;s>o;o++)i=e[o],i.x-=m,i.y-=y,x=Math.max(x,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=x,e.forEach(Si)}}function wi(n){n._pack_next=n._pack_prev=n}function Si(n){delete n._pack_next,delete n._pack_prev}function ki(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i<o;)ki(u[i],t,e,r)}function Ei(n,t,e){var r=n.r+e.r,u=t.x-n.x,i=t.y-n.y;if(r&&(u||i)){var o=t.r+e.r,a=u*u+i*i;o*=o,r*=r;var c=.5+(r-o)/(2*a),s=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+c*u+s*i,e.y=n.y+c*i-s*u}else e.x=n.x+r,e.y=n.y}function Ai(n){return 1+Xo.max(n,function(n){return n.y})}function Ci(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Ni(n){var t=n.children;return t&&t.length?Ni(t[0]):n}function Li(n){var t,e=n.children;return e&&(t=e.length)?Li(e[t-1]):n}function Ti(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function qi(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function zi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ri(n){return n.rangeExtent?n.rangeExtent():zi(n.range())}function Di(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Pi(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Ui(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:ls}function ji(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)u.push(e(n[o-1],n[o])),i.push(r(t[o-1],t[o]));return function(t){var e=Xo.bisect(n,t,1,a)-1;return i[e](u[e](t))}}function Hi(n,t,e,r){function u(){var u=Math.min(n.length,t.length)>2?ji:Di,c=r?Pu:Du;return o=u(n,t,c,e),a=u(t,n,c,fu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Nu)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Ii(n,t)},i.tickFormat=function(t,e){return Zi(n,t,e)},i.nice=function(t){return Oi(n,t),u()},i.copy=function(){return Hi(n,t,e,r)},u()}function Fi(n,t){return Xo.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Oi(n,t){return Pi(n,Ui(Yi(n,t)[2]))}function Yi(n,t){null==t&&(t=10);var e=zi(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Ii(n,t){return Xo.range.apply(Xo,Yi(n,t))}function Zi(n,t,e){var r=Yi(n,t);return Xo.format(e?e.replace(Qa,function(n,t,e,u,i,o,a,c,s,l){return[t,e,u,i,o,a,c,s||"."+Xi(l,r),l].join("")}):",."+Vi(r[2])+"f")}function Vi(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Xi(n,t){var e=Vi(t[2]);return n in fs?Math.abs(e-Vi(Math.max(Math.abs(t[0]),Math.abs(t[1]))))+ +("e"!==n):e-2*("%"===n)}function $i(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Pi(r.map(u),e?Math:gs);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=zi(r),o=[],a=n[0],c=n[1],s=Math.floor(u(a)),l=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(l-s)){if(e){for(;l>s;s++)for(var h=1;f>h;h++)o.push(i(s)*h);o.push(i(s))}else for(o.push(i(s));s++<l;)for(var h=f-1;h>0;h--)o.push(i(s)*h);for(s=0;o[s]<a;s++);for(l=o.length;o[l-1]>c;l--);o=o.slice(s,l)}return o},o.tickFormat=function(n,t){if(!arguments.length)return hs;arguments.length<2?t=hs:"function"!=typeof t&&(t=Xo.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return $i(n.copy(),t,e,r)},Fi(o,n)}function Bi(n,t,e){function r(t){return n(u(t))}var u=Wi(t),i=Wi(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Ii(e,n)},r.tickFormat=function(n,t){return Zi(e,n,t)},r.nice=function(n){return r.domain(Oi(e,n))},r.exponent=function(o){return arguments.length?(u=Wi(t=o),i=Wi(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Bi(n.copy(),t,e)},Fi(r,n)}function Wi(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Ji(n,t){function e(e){return o[((i.get(e)||"range"===t.t&&i.set(e,n.push(e)))-1)%o.length]}function r(t,e){return Xo.range(n.length).map(function(n){return t+e*n})}var i,o,a;return e.domain=function(r){if(!arguments.length)return n;n=[],i=new u;for(var o,a=-1,c=r.length;++a<c;)i.has(o=r[a])||i.set(o,n.push(o));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(o=n,a=0,t={t:"range",a:arguments},e):o},e.rangePoints=function(u,i){arguments.length<2&&(i=0);var c=u[0],s=u[1],l=(s-c)/(Math.max(1,n.length-1)+i);return o=r(n.length<2?(c+s)/2:c+l*i/2,l),a=0,t={t:"rangePoints",a:arguments},e},e.rangeBands=function(u,i,c){arguments.length<2&&(i=0),arguments.length<3&&(c=i);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=(f-l)/(n.length-i+2*c);return o=r(l+h*c,h),s&&o.reverse(),a=h*(1-i),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(u,i,c){arguments.length<2&&(i=0),arguments.length<3&&(c=i);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=Math.floor((f-l)/(n.length-i+2*c)),g=f-l-(n.length-i)*h;return o=r(l+Math.round(g/2),h),s&&o.reverse(),a=Math.round(h*(1-i)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return a},e.rangeExtent=function(){return zi(t.a[0])},e.copy=function(){return Ji(n,t)},e.domain(n)}function Gi(n,t){function e(){var e=0,i=t.length;for(u=[];++e<i;)u[e-1]=Xo.quantile(n,e/i);return r}function r(n){return isNaN(n=+n)?void 0:t[Xo.bisect(u,n)]}var u;return r.domain=function(t){return arguments.length?(n=t.filter(function(n){return!isNaN(n)}).sort(Xo.ascending),e()):n},r.range=function(n){return arguments.length?(t=n,e()):t},r.quantiles=function(){return u},r.invertExtent=function(e){return e=t.indexOf(e),0>e?[0/0,0/0]:[e>0?u[e-1]:n[0],e<u.length?u[e]:n[n.length-1]]},r.copy=function(){return Gi(n,t)},e()}function Ki(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(i*(t-n))))]}function u(){return i=e.length/(t-n),o=e.length-1,r}var i,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],u()):[n,t]},r.range=function(n){return arguments.length?(e=n,u()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return Ki(n,t,e)},u()}function Qi(n,t){function e(e){return e>=e?t[Xo.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return Qi(n,t)},e}function no(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Ii(n,t)},t.tickFormat=function(t,e){return Zi(n,t,e)},t.copy=function(){return no(n)},t}function to(n){return n.innerRadius}function eo(n){return n.outerRadius}function ro(n){return n.startAngle}function uo(n){return n.endAngle}function io(n){function t(t){function o(){s.push("M",i(n(l),a))}for(var c,s=[],l=[],f=-1,h=t.length,g=_t(e),p=_t(r);++f<h;)u.call(this,c=t[f],f)?l.push([+g.call(this,c,f),+p.call(this,c,f)]):l.length&&(o(),l=[]);return l.length&&o(),s.length?s.join(""):null}var e=br,r=wr,u=be,i=oo,o=i.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(u=n,t):u},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?i=n:(i=Ms.get(n)||oo).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function oo(n){return n.join("L")}function ao(n){return oo(n)+"Z"}function co(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&u.push("H",r[0]),u.join("")}function so(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("V",(r=n[t])[1],"H",r[0]);return u.join("")}function lo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r=n[t])[0],"V",r[1]);return u.join("")}function fo(n,t){return n.length<4?oo(n):n[1]+po(n.slice(1,n.length-1),vo(n,t))}function ho(n,t){return n.length<3?oo(n):n[0]+po((n.push(n[0]),n),vo([n[n.length-2]].concat(n,[n[1]]),t))}function go(n,t){return n.length<3?oo(n):n[0]+po(n,vo(n,t))}function po(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return oo(n);var e=n.length!=t.length,r="",u=n[0],i=n[1],o=t[0],a=o,c=1;if(e&&(r+="Q"+(i[0]-2*o[0]/3)+","+(i[1]-2*o[1]/3)+","+i[0]+","+i[1],u=n[1],c=2),t.length>1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var s=2;s<t.length;s++,c++)i=n[c],a=t[s],r+="S"+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1]}if(e){var l=n[c];r+="Q"+(i[0]+2*a[0]/3)+","+(i[1]+2*a[1]/3)+","+l[0]+","+l[1]}return r}function vo(n,t){for(var e,r=[],u=(1-t)/2,i=n[0],o=n[1],a=1,c=n.length;++a<c;)e=i,i=o,o=n[a],r.push([u*(o[0]-e[0]),u*(o[1]-e[1])]);return r}function mo(n){if(n.length<3)return oo(n);var t=1,e=n.length,r=n[0],u=r[0],i=r[1],o=[u,u,u,(r=n[1])[0]],a=[i,i,i,r[1]],c=[u,",",i,"L",_o(ws,o),",",_o(ws,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),bo(c,o,a);return n.pop(),c.push("L",r),c.join("")}function yo(n){if(n.length<4)return oo(n);for(var t,e=[],r=-1,u=n.length,i=[0],o=[0];++r<3;)t=n[r],i.push(t[0]),o.push(t[1]);for(e.push(_o(ws,i)+","+_o(ws,o)),--r;++r<u;)t=n[r],i.shift(),i.push(t[0]),o.shift(),o.push(t[1]),bo(e,i,o);return e.join("")}function xo(n){for(var t,e,r=-1,u=n.length,i=u+4,o=[],a=[];++r<4;)e=n[r%u],o.push(e[0]),a.push(e[1]);for(t=[_o(ws,o),",",_o(ws,a)],--r;++r<i;)e=n[r%u],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),bo(t,o,a);return t.join("")}function Mo(n,t){var e=n.length-1;if(e)for(var r,u,i=n[0][0],o=n[0][1],a=n[e][0]-i,c=n[e][1]-o,s=-1;++s<=e;)r=n[s],u=s/e,r[0]=t*r[0]+(1-t)*(i+u*a),r[1]=t*r[1]+(1-t)*(o+u*c);return mo(n)}function _o(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function bo(n,t,e){n.push("C",_o(_s,t),",",_o(_s,e),",",_o(bs,t),",",_o(bs,e),",",_o(ws,t),",",_o(ws,e))}function wo(n,t){return(t[1]-n[1])/(t[0]-n[0])}function So(n){for(var t=0,e=n.length-1,r=[],u=n[0],i=n[1],o=r[0]=wo(u,i);++t<e;)r[t]=(o+(o=wo(u=i,i=n[t+1])))/2;return r[t]=o,r}function ko(n){for(var t,e,r,u,i=[],o=So(n),a=-1,c=n.length-1;++a<c;)t=wo(n[a],n[a+1]),oa(t)<Aa?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,u=e*e+r*r,u>9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function Eo(n){return n.length<3?oo(n):n[0]+po(n,ko(n))}function Ao(n){for(var t,e,r,u=-1,i=n.length;++u<i;)t=n[u],e=t[0],r=t[1]+ys,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Co(n){function t(t){function c(){v.push("M",a(n(m),f),l,s(n(d.reverse()),f),"Z")}for(var h,g,p,v=[],d=[],m=[],y=-1,x=t.length,M=_t(e),_=_t(u),b=e===r?function(){return g}:_t(r),w=u===i?function(){return p}:_t(i);++y<x;)o.call(this,h=t[y],y)?(d.push([g=+M.call(this,h,y),p=+_.call(this,h,y)]),m.push([+b.call(this,h,y),+w.call(this,h,y)])):d.length&&(c(),d=[],m=[]);return d.length&&c(),v.length?v.join(""):null}var e=br,r=br,u=0,i=wr,o=be,a=oo,c=a.key,s=a,l="L",f=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r},t.y=function(n){return arguments.length?(u=i=n,t):i},t.y0=function(n){return arguments.length?(u=n,t):u},t.y1=function(n){return arguments.length?(i=n,t):i},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(c="function"==typeof n?a=n:(a=Ms.get(n)||oo).key,s=a.reverse||a,l=a.closed?"M":"L",t):c},t.tension=function(n){return arguments.length?(f=n,t):f},t}function No(n){return n.radius}function Lo(n){return[n.x,n.y]}function To(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]+ys;return[e*Math.cos(r),e*Math.sin(r)]}}function qo(){return 64}function zo(){return"circle"}function Ro(n){var t=Math.sqrt(n/Sa);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function Do(n,t){return fa(n,Ns),n.id=t,n}function Po(n,t,e,r){var u=n.id;return R(n,"function"==typeof e?function(n,i,o){n.__transition__[u].tween.set(t,r(e.call(n,n.__data__,i,o)))}:(e=r(e),function(n){n.__transition__[u].tween.set(t,e)}))}function Uo(n){return null==n&&(n=""),function(){this.textContent=n}}function jo(n,t,e,r){var i=n.__transition__||(n.__transition__={active:0,count:0}),o=i[e];if(!o){var a=r.time;o=i[e]={tween:new u,time:a,ease:r.ease,delay:r.delay,duration:r.duration},++i.count,Xo.timer(function(r){function u(r){return i.active>e?s():(i.active=e,o.event&&o.event.start.call(n,l,t),o.tween.forEach(function(e,r){(r=r.call(n,l,t))&&v.push(r)}),Xo.timer(function(){return p.c=c(r||1)?be:c,1},0,a),void 0)}function c(r){if(i.active!==e)return s();for(var u=r/g,a=f(u),c=v.length;c>0;)v[--c].call(n,a);return u>=1?(o.event&&o.event.end.call(n,l,t),s()):void 0}function s(){return--i.count?delete i[e]:delete n.__transition__,1}var l=n.__data__,f=o.ease,h=o.delay,g=o.duration,p=Ja,v=[];return p.t=h+a,r>=h?u(r-h):(p.c=u,void 0)},0,a)}}function Ho(n,t){n.attr("transform",function(n){return"translate("+t(n)+",0)"})}function Fo(n,t){n.attr("transform",function(n){return"translate(0,"+t(n)+")"})}function Oo(n){return n.toISOString()}function Yo(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=Xo.bisect(js,u);return i==js.length?[t.year,Yi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/js[i-1]<js[i]/u?i-1:i]:[Os,Yi(n,e)[2]]}return r.invert=function(t){return Io(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(Io)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,Io(+e+1),t).length}var i=r.domain(),o=zi(i),a=null==n?u(o,10):"number"==typeof n&&u(o,n);return a&&(n=a[0],t=a[1]),r.domain(Pi(i,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=Io(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Io(+t+1);return t}}:n))},r.ticks=function(n,t){var e=zi(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Io(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Yo(n.copy(),t,e)},Fi(r,n)}function Io(n){return new Date(n)}function Zo(n){return JSON.parse(n.responseText)}function Vo(n){var t=Wo.createRange();return t.selectNode(Wo.body),t.createContextualFragment(n.responseText)}var Xo={version:"3.4.3"};Date.now||(Date.now=function(){return+new Date});var $o=[].slice,Bo=function(n){return $o.call(n)},Wo=document,Jo=Wo.documentElement,Go=window;try{Bo(Jo.childNodes)[0].nodeType}catch(Ko){Bo=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}try{Wo.createElement("div").style.setProperty("opacity",0,"")}catch(Qo){var na=Go.Element.prototype,ta=na.setAttribute,ea=na.setAttributeNS,ra=Go.CSSStyleDeclaration.prototype,ua=ra.setProperty;na.setAttribute=function(n,t){ta.call(this,n,t+"")},na.setAttributeNS=function(n,t,e){ea.call(this,n,t,e+"")},ra.setProperty=function(n,t,e){ua.call(this,n,t+"",e)}}Xo.ascending=function(n,t){return t>n?-1:n>t?1:n>=t?0:0/0},Xo.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},Xo.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&e>r&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&e>r&&(e=r)}return e},Xo.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&r>e&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&r>e&&(e=r)}return e},Xo.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i<o&&!(null!=(e=u=n[i])&&e>=e);)e=u=void 0;for(;++i<o;)null!=(r=n[i])&&(e>r&&(e=r),r>u&&(u=r))}else{for(;++i<o&&!(null!=(e=u=t.call(n,n[i],i))&&e>=e);)e=void 0;for(;++i<o;)null!=(r=t.call(n,n[i],i))&&(e>r&&(e=r),r>u&&(u=r))}return[e,u]},Xo.sum=function(n,t){var e,r=0,u=n.length,i=-1;if(1===arguments.length)for(;++i<u;)isNaN(e=+n[i])||(r+=e);else for(;++i<u;)isNaN(e=+t.call(n,n[i],i))||(r+=e);return r},Xo.mean=function(t,e){var r,u=t.length,i=0,o=-1,a=0;if(1===arguments.length)for(;++o<u;)n(r=t[o])&&(i+=(r-i)/++a);else for(;++o<u;)n(r=e.call(t,t[o],o))&&(i+=(r-i)/++a);return a?i:void 0},Xo.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),u=+n[r-1],i=e-r;return i?u+i*(n[r]-u):u},Xo.median=function(t,e){return arguments.length>1&&(t=t.map(e)),t=t.filter(n),t.length?Xo.quantile(t.sort(Xo.ascending),.5):void 0},Xo.bisector=function(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n.call(t,t[i],i)<e?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;e<n.call(t,t[i],i)?u=i:r=i+1}return r}}};var ia=Xo.bisector(function(n){return n});Xo.bisectLeft=ia.left,Xo.bisect=Xo.bisectRight=ia.right,Xo.shuffle=function(n){for(var t,e,r=n.length;r;)e=0|Math.random()*r--,t=n[r],n[r]=n[e],n[e]=t;return n},Xo.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},Xo.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},Xo.zip=function(){if(!(u=arguments.length))return[];for(var n=-1,e=Xo.min(arguments,t),r=new Array(e);++n<e;)for(var u,i=-1,o=r[n]=new Array(u);++i<u;)o[i]=arguments[i][n];return r},Xo.transpose=function(n){return Xo.zip.apply(Xo,n)},Xo.keys=function(n){var t=[];for(var e in n)t.push(e);return t},Xo.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},Xo.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},Xo.merge=function(n){for(var t,e,r,u=n.length,i=-1,o=0;++i<u;)o+=n[i].length;for(e=new Array(o);--u>=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var oa=Math.abs;Xo.range=function(n,t,r){if(arguments.length<3&&(r=1,arguments.length<2&&(t=n,n=0)),1/0===(t-n)/r)throw new Error("infinite range");var u,i=[],o=e(oa(r)),a=-1;if(n*=o,t*=o,r*=o,0>r)for(;(u=n+r*++a)>t;)i.push(u/o);else for(;(u=n+r*++a)<t;)i.push(u/o);return i},Xo.map=function(n){var t=new u;if(n instanceof u)n.forEach(function(n,e){t.set(n,e)});else for(var e in n)t.set(e,n[e]);return t},r(u,{has:i,get:function(n){return this[aa+n]},set:function(n,t){return this[aa+n]=t},remove:o,keys:a,values:function(){var n=[];return this.forEach(function(t,e){n.push(e)}),n},entries:function(){var n=[];return this.forEach(function(t,e){n.push({key:t,value:e})}),n},size:c,empty:s,forEach:function(n){for(var t in this)t.charCodeAt(0)===ca&&n.call(this,t.substring(1),this[t])}});var aa="\x00",ca=aa.charCodeAt(0);Xo.nest=function(){function n(t,a,c){if(c>=o.length)return r?r.call(i,a):e?a.sort(e):a;for(var s,l,f,h,g=-1,p=a.length,v=o[c++],d=new u;++g<p;)(h=d.get(s=v(l=a[g])))?h.push(l):d.set(s,[l]);return t?(l=t(),f=function(e,r){l.set(e,n(t,r,c))}):(l={},f=function(e,r){l[e]=n(t,r,c)}),d.forEach(f),l}function t(n,e){if(e>=o.length)return n;var r=[],u=a[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,i={},o=[],a=[];return i.map=function(t,e){return n(e,t,0)},i.entries=function(e){return t(n(Xo.map,e,0),0)},i.key=function(n){return o.push(n),i},i.sortKeys=function(n){return a[o.length-1]=n,i},i.sortValues=function(n){return e=n,i},i.rollup=function(n){return r=n,i},i},Xo.set=function(n){var t=new l;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},r(l,{has:i,add:function(n){return this[aa+n]=!0,n},remove:function(n){return n=aa+n,n in this&&delete this[n]},values:a,size:c,empty:s,forEach:function(n){for(var t in this)t.charCodeAt(0)===ca&&n.call(this,t.substring(1))}}),Xo.behavior={},Xo.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r<u;)n[e=arguments[r]]=f(n,t,t[e]);return n};var sa=["webkit","ms","moz","Moz","o","O"];Xo.dispatch=function(){for(var n=new p,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=v(n);return n},p.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.substring(e+1),n=n.substring(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},Xo.event=null,Xo.requote=function(n){return n.replace(la,"\\$&")};var la=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,fa={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},ha=function(n,t){return t.querySelector(n)},ga=function(n,t){return t.querySelectorAll(n)},pa=Jo[h(Jo,"matchesSelector")],va=function(n,t){return pa.call(n,t)};"function"==typeof Sizzle&&(ha=function(n,t){return Sizzle(n,t)[0]||null},ga=Sizzle,va=Sizzle.matchesSelector),Xo.selection=function(){return xa};var da=Xo.selection.prototype=[];da.select=function(n){var t,e,r,u,i=[];n=M(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var c=-1,s=r.length;++c<s;)(u=r[c])?(t.push(e=n.call(u,u.__data__,c,o)),e&&"__data__"in u&&(e.__data__=u.__data__)):t.push(null)}return x(i)},da.selectAll=function(n){var t,e,r=[];n=_(n);for(var u=-1,i=this.length;++u<i;)for(var o=this[u],a=-1,c=o.length;++a<c;)(e=o[a])&&(r.push(t=Bo(n.call(e,e.__data__,a,u))),t.parentNode=e);return x(r)};var ma={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};Xo.ns={prefix:ma,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&(e=n.substring(0,t),n=n.substring(t+1)),ma.hasOwnProperty(e)?{space:ma[e],local:n}:n}},da.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=Xo.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(b(t,n[t]));return this}return this.each(b(n,t))},da.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=k(n)).length,u=-1;if(t=e.classList){for(;++u<r;)if(!t.contains(n[u]))return!1}else for(t=e.getAttribute("class");++u<r;)if(!S(n[u]).test(t))return!1;return!0}for(t in n)this.each(E(t,n[t]));return this}return this.each(E(n,t))},da.style=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(C(e,n[e],t));return this}if(2>r)return Go.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(C(n,t,e))},da.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(N(t,n[t]));return this}return this.each(N(n,t))},da.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},da.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},da.append=function(n){return n=L(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},da.insert=function(n,t){return n=L(n),t=M(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},da.remove=function(){return this.each(function(){var n=this.parentNode;n&&n.removeChild(this)})},da.data=function(n,t){function e(n,e){var r,i,o,a=n.length,f=e.length,h=Math.min(a,f),g=new Array(f),p=new Array(f),v=new Array(a);if(t){var d,m=new u,y=new u,x=[];for(r=-1;++r<a;)d=t.call(i=n[r],i.__data__,r),m.has(d)?v[r]=i:m.set(d,i),x.push(d);for(r=-1;++r<f;)d=t.call(e,o=e[r],r),(i=m.get(d))?(g[r]=i,i.__data__=o):y.has(d)||(p[r]=T(o)),y.set(d,o),m.remove(d);for(r=-1;++r<a;)m.has(x[r])&&(v[r]=n[r])}else{for(r=-1;++r<h;)i=n[r],o=e[r],i?(i.__data__=o,g[r]=i):p[r]=T(o);for(;f>r;++r)p[r]=T(e[r]);for(;a>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,c.push(p),s.push(g),l.push(v)}var r,i,o=-1,a=this.length;if(!arguments.length){for(n=new Array(a=(r=this[0]).length);++o<a;)(i=r[o])&&(n[o]=i.__data__);return n}var c=D([]),s=x([]),l=x([]);if("function"==typeof n)for(;++o<a;)e(r=this[o],n.call(r,r.parentNode.__data__,o));else for(;++o<a;)e(r=this[o],n);return s.enter=function(){return c},s.exit=function(){return l},s},da.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},da.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=q(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return x(u)},da.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],u=r.length-1,i=r[u];--u>=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},da.sort=function(n){n=z.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},da.each=function(n){return R(this,function(t,e,r){n.call(t,t.__data__,e,r)})},da.call=function(n){var t=Bo(arguments);return n.apply(t[0]=this,t),this},da.empty=function(){return!this.node()},da.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},da.size=function(){var n=0;return this.each(function(){++n}),n};var ya=[];Xo.selection.enter=D,Xo.selection.enter.prototype=ya,ya.append=da.append,ya.empty=da.empty,ya.node=da.node,ya.call=da.call,ya.size=da.size,ya.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++a<c;){r=(u=this[a]).update,o.push(t=[]),t.parentNode=u.parentNode;for(var s=-1,l=u.length;++s<l;)(i=u[s])?(t.push(r[s]=e=n.call(u.parentNode,i.__data__,s,a)),e.__data__=i.__data__):t.push(null)}return x(o)},ya.insert=function(n,t){return arguments.length<2&&(t=P(this)),da.insert.call(this,n,t)},da.transition=function(){for(var n,t,e=ks||++Ls,r=[],u=Es||{time:Date.now(),ease:yu,delay:0,duration:250},i=-1,o=this.length;++i<o;){r.push(n=[]);for(var a=this[i],c=-1,s=a.length;++c<s;)(t=a[c])&&jo(t,c,e,u),n.push(t)}return Do(r,e)},da.interrupt=function(){return this.each(U)},Xo.select=function(n){var t=["string"==typeof n?ha(n,Wo):n];return t.parentNode=Jo,x([t])},Xo.selectAll=function(n){var t=Bo("string"==typeof n?ga(n,Wo):n);return t.parentNode=Jo,x([t])};var xa=Xo.select(Jo);da.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(j(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(j(n,t,e))};var Ma=Xo.map({mouseenter:"mouseover",mouseleave:"mouseout"});Ma.forEach(function(n){"on"+n in Wo&&Ma.remove(n)});var _a="onselectstart"in Wo?null:h(Jo.style,"userSelect"),ba=0;Xo.mouse=function(n){return Y(n,m())};var wa=/WebKit/.test(Go.navigator.userAgent)?-1:0;Xo.touches=function(n,t){return arguments.length<2&&(t=m().touches),t?Bo(t).map(function(t){var e=Y(n,t);return e.identifier=t.identifier,e}):[]},Xo.behavior.drag=function(){function n(){this.on("mousedown.drag",o).on("touchstart.drag",a)}function t(){return Xo.event.changedTouches[0].identifier}function e(n,t){return Xo.touches(n).filter(function(n){return n.identifier===t})[0]}function r(n,t,e,r){return function(){function o(){var n=t(l,g),e=n[0]-v[0],r=n[1]-v[1];d|=e|r,v=n,f({type:"drag",x:n[0]+c[0],y:n[1]+c[1],dx:e,dy:r})}function a(){m.on(e+"."+p,null).on(r+"."+p,null),y(d&&Xo.event.target===h),f({type:"dragend"})}var c,s=this,l=s.parentNode,f=u.of(s,arguments),h=Xo.event.target,g=n(),p=null==g?"drag":"drag-"+g,v=t(l,g),d=0,m=Xo.select(Go).on(e+"."+p,o).on(r+"."+p,a),y=O();i?(c=i.apply(s,arguments),c=[c.x-v[0],c.y-v[1]]):c=[0,0],f({type:"dragstart"})}}var u=y(n,"drag","dragstart","dragend"),i=null,o=r(g,Xo.mouse,"mousemove","mouseup"),a=r(t,e,"touchmove","touchend");return n.origin=function(t){return arguments.length?(i=t,n):i},Xo.rebind(n,u,"on")};var Sa=Math.PI,ka=2*Sa,Ea=Sa/2,Aa=1e-6,Ca=Aa*Aa,Na=Sa/180,La=180/Sa,Ta=Math.SQRT2,qa=2,za=4;Xo.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=B(v),o=i/(qa*h)*(e*W(Ta*t+v)-$(v));return[r+o*s,u+o*l,i*e/B(Ta*t+v)]}return[r+n*s,u+n*l,i*Math.exp(Ta*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],s=o-r,l=a-u,f=s*s+l*l,h=Math.sqrt(f),g=(c*c-i*i+za*f)/(2*i*qa*h),p=(c*c-i*i-za*f)/(2*c*qa*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Ta;return e.duration=1e3*y,e},Xo.behavior.zoom=function(){function n(n){n.on(A,s).on(Pa+".zoom",f).on(C,h).on("dblclick.zoom",g).on(L,l)}function t(n){return[(n[0]-S.x)/S.k,(n[1]-S.y)/S.k]}function e(n){return[n[0]*S.k+S.x,n[1]*S.k+S.y]}function r(n){S.k=Math.max(E[0],Math.min(E[1],n))}function u(n,t){t=e(t),S.x+=n[0]-t[0],S.y+=n[1]-t[1]}function i(){_&&_.domain(M.range().map(function(n){return(n-S.x)/S.k}).map(M.invert)),w&&w.domain(b.range().map(function(n){return(n-S.y)/S.k}).map(b.invert))}function o(n){n({type:"zoomstart"})}function a(n){i(),n({type:"zoom",scale:S.k,translate:[S.x,S.y]})}function c(n){n({type:"zoomend"})}function s(){function n(){l=1,u(Xo.mouse(r),g),a(i)}function e(){f.on(C,Go===r?h:null).on(N,null),p(l&&Xo.event.target===s),c(i)}var r=this,i=T.of(r,arguments),s=Xo.event.target,l=0,f=Xo.select(Go).on(C,n).on(N,e),g=t(Xo.mouse(r)),p=O();U.call(r),o(i)}function l(){function n(){var n=Xo.touches(g);return h=S.k,n.forEach(function(n){n.identifier in v&&(v[n.identifier]=t(n))}),n}function e(){for(var t=Xo.event.changedTouches,e=0,i=t.length;i>e;++e)v[t[e].identifier]=null;var o=n(),c=Date.now();if(1===o.length){if(500>c-x){var s=o[0],l=v[s.identifier];r(2*S.k),u(s,l),d(),a(p)}x=c}else if(o.length>1){var s=o[0],f=o[1],h=s[0]-f[0],g=s[1]-f[1];m=h*h+g*g}}function i(){for(var n,t,e,i,o=Xo.touches(g),c=0,s=o.length;s>c;++c,i=null)if(e=o[c],i=v[e.identifier]){if(t)break;n=e,t=i}if(i){var l=(l=e[0]-n[0])*l+(l=e[1]-n[1])*l,f=m&&Math.sqrt(l/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+i[0])/2,(t[1]+i[1])/2],r(f*h)}x=null,u(n,t),a(p)}function f(){if(Xo.event.touches.length){for(var t=Xo.event.changedTouches,e=0,r=t.length;r>e;++e)delete v[t[e].identifier];for(var u in v)return void n()}b.on(M,null).on(_,null),w.on(A,s).on(L,l),k(),c(p)}var h,g=this,p=T.of(g,arguments),v={},m=0,y=Xo.event.changedTouches[0].identifier,M="touchmove.zoom-"+y,_="touchend.zoom-"+y,b=Xo.select(Go).on(M,i).on(_,f),w=Xo.select(g).on(A,null).on(L,e),k=O();U.call(g),e(),o(p)}function f(){var n=T.of(this,arguments);m?clearTimeout(m):(U.call(this),o(n)),m=setTimeout(function(){m=null,c(n)},50),d();var e=v||Xo.mouse(this);p||(p=t(e)),r(Math.pow(2,.002*Ra())*S.k),u(e,p),a(n)}function h(){p=null}function g(){var n=T.of(this,arguments),e=Xo.mouse(this),i=t(e),s=Math.log(S.k)/Math.LN2;o(n),r(Math.pow(2,Xo.event.shiftKey?Math.ceil(s)-1:Math.floor(s)+1)),u(e,i),a(n),c(n)}var p,v,m,x,M,_,b,w,S={x:0,y:0,k:1},k=[960,500],E=Da,A="mousedown.zoom",C="mousemove.zoom",N="mouseup.zoom",L="touchstart.zoom",T=y(n,"zoomstart","zoom","zoomend");return n.event=function(n){n.each(function(){var n=T.of(this,arguments),t=S;ks?Xo.select(this).transition().each("start.zoom",function(){S=this.__chart__||{x:0,y:0,k:1},o(n)}).tween("zoom:zoom",function(){var e=k[0],r=k[1],u=e/2,i=r/2,o=Xo.interpolateZoom([(u-S.x)/S.k,(i-S.y)/S.k,e/S.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),c=e/r[2];this.__chart__=S={x:u-r[0]*c,y:i-r[1]*c,k:c},a(n)}}).each("end.zoom",function(){c(n)}):(this.__chart__=S,o(n),a(n),c(n))})},n.translate=function(t){return arguments.length?(S={x:+t[0],y:+t[1],k:S.k},i(),n):[S.x,S.y]},n.scale=function(t){return arguments.length?(S={x:S.x,y:S.y,k:+t},i(),n):S.k},n.scaleExtent=function(t){return arguments.length?(E=null==t?Da:[+t[0],+t[1]],n):E},n.center=function(t){return arguments.length?(v=t&&[+t[0],+t[1]],n):v},n.size=function(t){return arguments.length?(k=t&&[+t[0],+t[1]],n):k},n.x=function(t){return arguments.length?(_=t,M=t.copy(),S={x:0,y:0,k:1},n):_},n.y=function(t){return arguments.length?(w=t,b=t.copy(),S={x:0,y:0,k:1},n):w},Xo.rebind(n,T,"on")};var Ra,Da=[0,1/0],Pa="onwheel"in Wo?(Ra=function(){return-Xo.event.deltaY*(Xo.event.deltaMode?120:1)},"wheel"):"onmousewheel"in Wo?(Ra=function(){return Xo.event.wheelDelta},"mousewheel"):(Ra=function(){return-Xo.event.detail},"MozMousePixelScroll");G.prototype.toString=function(){return this.rgb()+""},Xo.hsl=function(n,t,e){return 1===arguments.length?n instanceof Q?K(n.h,n.s,n.l):dt(""+n,mt,K):K(+n,+t,+e)};var Ua=Q.prototype=new G;Ua.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),K(this.h,this.s,this.l/n)},Ua.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),K(this.h,this.s,n*this.l)},Ua.rgb=function(){return nt(this.h,this.s,this.l)},Xo.hcl=function(n,t,e){return 1===arguments.length?n instanceof et?tt(n.h,n.c,n.l):n instanceof it?at(n.l,n.a,n.b):at((n=yt((n=Xo.rgb(n)).r,n.g,n.b)).l,n.a,n.b):tt(+n,+t,+e)};var ja=et.prototype=new G;ja.brighter=function(n){return tt(this.h,this.c,Math.min(100,this.l+Ha*(arguments.length?n:1)))},ja.darker=function(n){return tt(this.h,this.c,Math.max(0,this.l-Ha*(arguments.length?n:1)))},ja.rgb=function(){return rt(this.h,this.c,this.l).rgb()},Xo.lab=function(n,t,e){return 1===arguments.length?n instanceof it?ut(n.l,n.a,n.b):n instanceof et?rt(n.l,n.c,n.h):yt((n=Xo.rgb(n)).r,n.g,n.b):ut(+n,+t,+e)};var Ha=18,Fa=.95047,Oa=1,Ya=1.08883,Ia=it.prototype=new G;Ia.brighter=function(n){return ut(Math.min(100,this.l+Ha*(arguments.length?n:1)),this.a,this.b)},Ia.darker=function(n){return ut(Math.max(0,this.l-Ha*(arguments.length?n:1)),this.a,this.b)},Ia.rgb=function(){return ot(this.l,this.a,this.b)},Xo.rgb=function(n,t,e){return 1===arguments.length?n instanceof pt?gt(n.r,n.g,n.b):dt(""+n,gt,nt):gt(~~n,~~t,~~e)};var Za=pt.prototype=new G;Za.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),gt(Math.min(255,~~(t/n)),Math.min(255,~~(e/n)),Math.min(255,~~(r/n)))):gt(u,u,u)},Za.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),gt(~~(n*this.r),~~(n*this.g),~~(n*this.b))},Za.hsl=function(){return mt(this.r,this.g,this.b)},Za.toString=function(){return"#"+vt(this.r)+vt(this.g)+vt(this.b)};var Va=Xo.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});Va.forEach(function(n,t){Va.set(n,ft(t))}),Xo.functor=_t,Xo.xhr=wt(bt),Xo.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=St(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(l>=s)return o;if(u)return u=!1,i;var t=l;if(34===n.charCodeAt(t)){for(var e=t;e++<s;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}l=e+2;var r=n.charCodeAt(e+1);return 13===r?(u=!0,10===n.charCodeAt(e+2)&&++l):10===r&&(u=!0),n.substring(t+1,e).replace(/""/g,'"')}for(;s>l;){var r=n.charCodeAt(l++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(l)&&(++l,++a);else if(r!==c)continue;return n.substring(t,l-a)}return n.substring(t)}for(var r,u,i={},o={},a=[],s=n.length,l=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();(!t||(h=t(h,f++)))&&a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new l,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},Xo.csv=Xo.dsv(",","text/csv"),Xo.tsv=Xo.dsv("	","text/tab-separated-values");var Xa,$a,Ba,Wa,Ja,Ga=Go[h(Go,"requestAnimationFrame")]||function(n){setTimeout(n,17)};Xo.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};$a?$a.n=i:Xa=i,$a=i,Ba||(Wa=clearTimeout(Wa),Ba=1,Ga(Et))},Xo.timer.flush=function(){At(),Ct()},Xo.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var Ka=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Lt);Xo.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=Xo.round(n,Nt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((0>=e?e+1:e-1)/3)))),Ka[8+e/3]};var Qa=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,nc=Xo.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=Xo.round(n,Nt(n,t))).toFixed(Math.max(0,Math.min(20,Nt(n*(1+1e-15),t))))}}),tc=Xo.time={},ec=Date;zt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){rc.setUTCDate.apply(this._,arguments)},setDay:function(){rc.setUTCDay.apply(this._,arguments)},setFullYear:function(){rc.setUTCFullYear.apply(this._,arguments)},setHours:function(){rc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){rc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){rc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){rc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){rc.setUTCSeconds.apply(this._,arguments)},setTime:function(){rc.setTime.apply(this._,arguments)}};var rc=Date.prototype;tc.year=Rt(function(n){return n=tc.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),tc.years=tc.year.range,tc.years.utc=tc.year.utc.range,tc.day=Rt(function(n){var t=new ec(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),tc.days=tc.day.range,tc.days.utc=tc.day.utc.range,tc.dayOfYear=function(n){var t=tc.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=tc[n]=Rt(function(n){return(n=tc.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=tc.year(n).getDay();return Math.floor((tc.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});tc[n+"s"]=e.range,tc[n+"s"].utc=e.utc.range,tc[n+"OfYear"]=function(n){var e=tc.year(n).getDay();return Math.floor((tc.dayOfYear(n)+(e+t)%7)/7)}}),tc.week=tc.sunday,tc.weeks=tc.sunday.range,tc.weeks.utc=tc.sunday.utc.range,tc.weekOfYear=tc.sundayOfYear;var uc={"-":"",_:" ",0:"0"},ic=/^\s*\d+/,oc=/^%/;Xo.locale=function(n){return{numberFormat:Tt(n),timeFormat:Pt(n)}};var ac=Xo.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});Xo.format=ac.numberFormat,Xo.geo={},re.prototype={s:0,t:0,add:function(n){ue(n,this.t,cc),ue(cc.s,this.s,this),this.s?this.t+=cc.t:this.s=cc.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var cc=new re;Xo.geo.stream=function(n,t){n&&sc.hasOwnProperty(n.type)?sc[n.type](n,t):ie(n,t)};var sc={Feature:function(n,t){ie(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++r<u;)ie(e[r].geometry,t)}},lc={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){oe(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)oe(e[r],t,0)},Polygon:function(n,t){ae(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)ae(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,u=e.length;++r<u;)ie(e[r],t)}};Xo.geo.area=function(n){return fc=0,Xo.geo.stream(n,gc),fc};var fc,hc=new re,gc={sphere:function(){fc+=4*Sa},point:g,lineStart:g,lineEnd:g,polygonStart:function(){hc.reset(),gc.lineStart=ce},polygonEnd:function(){var n=2*hc;fc+=0>n?4*Sa+n:n,gc.lineStart=gc.lineEnd=gc.point=g}};Xo.geo.bounds=function(){function n(n,t){x.push(M=[l=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=se([t*Na,e*Na]);if(m){var u=fe(m,r),i=[u[1],-u[0],0],o=fe(i,u);pe(o),o=ve(o);var c=t-p,s=c>0?1:-1,v=o[0]*La*s,d=oa(c)>180;if(d^(v>s*p&&s*t>v)){var y=o[1]*La;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>s*p&&s*t>v)){var y=-o[1]*La;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t):h>=l?(l>t&&(l=t),t>h&&(h=t)):t>p?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t)}else n(t,e);m=r,p=t}function e(){_.point=t}function r(){M[0]=l,M[1]=h,_.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=oa(r)>180?r+(r>0?360:-360):r}else v=n,d=e;gc.point(n,e),t(n,e)}function i(){gc.lineStart()}function o(){u(v,d),gc.lineEnd(),oa(y)>Aa&&(l=-(h=180)),M[0]=l,M[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function s(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var l,f,h,g,p,v,d,m,y,x,M,_={point:n,lineStart:e,lineEnd:r,polygonStart:function(){_.point=u,_.lineStart=i,_.lineEnd=o,y=0,gc.polygonStart()},polygonEnd:function(){gc.polygonEnd(),_.point=n,_.lineStart=e,_.lineEnd=r,0>hc?(l=-(h=180),f=-(g=90)):y>Aa?g=90:-Aa>y&&(f=-90),M[0]=l,M[1]=h}};return function(n){g=h=-(l=f=1/0),x=[],Xo.geo.stream(n,_);var t=x.length;if(t){x.sort(c);for(var e,r=1,u=x[0],i=[u];t>r;++r)e=x[r],s(e[0],u)||s(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,l=e[0],h=u[1])}return x=M=null,1/0===l||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[l,f],[h,g]]}}(),Xo.geo.centroid=function(n){pc=vc=dc=mc=yc=xc=Mc=_c=bc=wc=Sc=0,Xo.geo.stream(n,kc);var t=bc,e=wc,r=Sc,u=t*t+e*e+r*r;return Ca>u&&(t=xc,e=Mc,r=_c,Aa>vc&&(t=dc,e=mc,r=yc),u=t*t+e*e+r*r,Ca>u)?[0/0,0/0]:[Math.atan2(e,t)*La,X(r/Math.sqrt(u))*La]};var pc,vc,dc,mc,yc,xc,Mc,_c,bc,wc,Sc,kc={sphere:g,point:me,lineStart:xe,lineEnd:Me,polygonStart:function(){kc.lineStart=_e},polygonEnd:function(){kc.lineStart=xe}},Ec=Ee(be,Te,ze,[-Sa,-Sa/2]),Ac=1e9;Xo.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Pe(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(Xo.geo.conicEqualArea=function(){return je(He)}).raw=He,Xo.geo.albers=function(){return Xo.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},Xo.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=Xo.geo.albers(),o=Xo.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=Xo.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var s=i.scale(),l=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[l-.455*s,f-.238*s],[l+.455*s,f+.238*s]]).stream(c).point,r=o.translate([l-.307*s,f+.201*s]).clipExtent([[l-.425*s+Aa,f+.12*s+Aa],[l-.214*s-Aa,f+.234*s-Aa]]).stream(c).point,u=a.translate([l-.205*s,f+.212*s]).clipExtent([[l-.214*s+Aa,f+.166*s+Aa],[l-.115*s-Aa,f+.234*s-Aa]]).stream(c).point,n},n.scale(1070)};var Cc,Nc,Lc,Tc,qc,zc,Rc={point:g,lineStart:g,lineEnd:g,polygonStart:function(){Nc=0,Rc.lineStart=Fe},polygonEnd:function(){Rc.lineStart=Rc.lineEnd=Rc.point=g,Cc+=oa(Nc/2)}},Dc={point:Oe,lineStart:g,lineEnd:g,polygonStart:g,polygonEnd:g},Pc={point:Ze,lineStart:Ve,lineEnd:Xe,polygonStart:function(){Pc.lineStart=$e},polygonEnd:function(){Pc.point=Ze,Pc.lineStart=Ve,Pc.lineEnd=Xe}};Xo.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),Xo.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Cc=0,Xo.geo.stream(n,u(Rc)),Cc},n.centroid=function(n){return dc=mc=yc=xc=Mc=_c=bc=wc=Sc=0,Xo.geo.stream(n,u(Pc)),Sc?[bc/Sc,wc/Sc]:_c?[xc/_c,Mc/_c]:yc?[dc/yc,mc/yc]:[0/0,0/0]},n.bounds=function(n){return qc=zc=-(Lc=Tc=1/0),Xo.geo.stream(n,u(Dc)),[[Lc,Tc],[qc,zc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||Je(n):bt,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new Ye:new Be(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(Xo.geo.albersUsa()).context(null)},Xo.geo.transform=function(n){return{stream:function(t){var e=new Ge(t);for(var r in n)e[r]=n[r];return e}}},Ge.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},Xo.geo.projection=Qe,Xo.geo.projectionMutator=nr,(Xo.geo.equirectangular=function(){return Qe(er)}).raw=er.invert=er,Xo.geo.rotation=function(n){function t(t){return t=n(t[0]*Na,t[1]*Na),t[0]*=La,t[1]*=La,t}return n=ur(n[0]%360*Na,n[1]*Na,n.length>2?n[2]*Na:0),t.invert=function(t){return t=n.invert(t[0]*Na,t[1]*Na),t[0]*=La,t[1]*=La,t},t},rr.invert=er,Xo.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=ur(-n[0]*Na,-n[1]*Na,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=La,n[1]*=La}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=cr((t=+r)*Na,u*Na),n):t},n.precision=function(r){return arguments.length?(e=cr(t*Na,(u=+r)*Na),n):u},n.angle(90)},Xo.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Na,u=n[1]*Na,i=t[1]*Na,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),s=Math.cos(u),l=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=s*l-c*f*a)*e),c*l+s*f*a)},Xo.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return Xo.range(Math.ceil(i/d)*d,u,d).map(h).concat(Xo.range(Math.ceil(s/m)*m,c,m).map(g)).concat(Xo.range(Math.ceil(r/p)*p,e,p).filter(function(n){return oa(n%d)>Aa}).map(l)).concat(Xo.range(Math.ceil(a/v)*v,o,v).filter(function(n){return oa(n%m)>Aa}).map(f))}var e,r,u,i,o,a,c,s,l,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(s).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],s=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),s>c&&(t=s,s=c,c=t),n.precision(y)):[[i,s],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,l=lr(a,o,90),f=fr(r,e,y),h=lr(s,c,90),g=fr(i,u,y),n):y},n.majorExtent([[-180,-90+Aa],[180,90-Aa]]).minorExtent([[-180,-80-Aa],[180,80+Aa]])},Xo.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=hr,u=gr;return n.distance=function(){return Xo.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},Xo.geo.interpolate=function(n,t){return pr(n[0]*Na,n[1]*Na,t[0]*Na,t[1]*Na)},Xo.geo.length=function(n){return Uc=0,Xo.geo.stream(n,jc),Uc};var Uc,jc={sphere:g,point:g,lineStart:vr,lineEnd:g,polygonStart:g,polygonEnd:g},Hc=dr(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(Xo.geo.azimuthalEqualArea=function(){return Qe(Hc)}).raw=Hc;var Fc=dr(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},bt);(Xo.geo.azimuthalEquidistant=function(){return Qe(Fc)}).raw=Fc,(Xo.geo.conicConformal=function(){return je(mr)}).raw=mr,(Xo.geo.conicEquidistant=function(){return je(yr)}).raw=yr;var Oc=dr(function(n){return 1/n},Math.atan);(Xo.geo.gnomonic=function(){return Qe(Oc)}).raw=Oc,xr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Ea]},(Xo.geo.mercator=function(){return Mr(xr)}).raw=xr;var Yc=dr(function(){return 1},Math.asin);(Xo.geo.orthographic=function(){return Qe(Yc)}).raw=Yc;var Ic=dr(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(Xo.geo.stereographic=function(){return Qe(Ic)}).raw=Ic,_r.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Ea]},(Xo.geo.transverseMercator=function(){var n=Mr(_r),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[-n[1],n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},n.rotate([0,0])}).raw=_r,Xo.geom={},Xo.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=_t(e),i=_t(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(kr),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var s=Sr(a),l=Sr(c),f=l[0]===s[0],h=l[l.length-1]===s[s.length-1],g=[];for(t=s.length-1;t>=0;--t)g.push(n[a[s[t]][2]]);for(t=+f;t<l.length-h;++t)g.push(n[a[l[t]][2]]);return g}var e=br,r=wr;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},Xo.geom.polygon=function(n){return fa(n,Zc),n};var Zc=Xo.geom.polygon.prototype=[];Zc.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],u=0;++t<e;)n=r,r=this[t],u+=n[1]*r[0]-n[0]*r[1];return.5*u},Zc.centroid=function(n){var t,e,r=-1,u=this.length,i=0,o=0,a=this[u-1];for(arguments.length||(n=-1/(6*this.area()));++r<u;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],i+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[i*n,o*n]},Zc.clip=function(n){for(var t,e,r,u,i,o,a=Cr(n),c=-1,s=this.length-Cr(this),l=this[s-1];++c<s;){for(t=n.slice(),n.length=0,u=this[c],i=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],Er(o,l,u)?(Er(i,l,u)||n.push(Ar(i,o,l,u)),n.push(o)):Er(i,l,u)&&n.push(Ar(i,o,l,u)),i=o;a&&n.push(n[0]),l=u}return n};var Vc,Xc,$c,Bc,Wc,Jc=[],Gc=[];Pr.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(jr),t.length},Br.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},Wr.prototype={insert:function(n,t){var e,r,u;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=Qr(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(u=r.R,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.R&&(Gr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Kr(this,r))):(u=r.L,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.L&&(Kr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Gr(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,u=n.U,i=n.L,o=n.R;if(e=i?o?Qr(o):i:o,u?u.L===n?u.L=e:u.R=e:this._=e,i&&o?(r=e.C,e.C=n.C,e.L=i,i.U=e,e!==o?(u=e.U,e.U=n.U,n=e.R,u.L=n,e.R=o,o.U=e):(e.U=u,u=e,n=e.R)):(r=n.C,n=e),n&&(n.U=u),!r){if(n&&n.C)return n.C=!1,void 0;do{if(n===this._)break;if(n===u.L){if(t=u.R,t.C&&(t.C=!1,u.C=!0,Gr(this,u),t=u.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,Kr(this,t),t=u.R),t.C=u.C,u.C=t.R.C=!1,Gr(this,u),n=this._;break}}else if(t=u.L,t.C&&(t.C=!1,u.C=!0,Kr(this,u),t=u.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,Gr(this,t),t=u.L),t.C=u.C,u.C=t.L.C=!1,Kr(this,u),n=this._;break}t.C=!0,n=u,u=u.U}while(!n.C);n&&(n.C=!1)}}},Xo.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],u=a[0][1],i=a[1][0],o=a[1][1];return nu(e(n),a).cells.forEach(function(e,a){var c=e.edges,s=e.site,l=t[a]=c.length?c.map(function(n){var t=n.start();return[t.x,t.y]}):s.x>=r&&s.x<=i&&s.y>=u&&s.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];l.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Aa)*Aa,y:Math.round(o(n,t)/Aa)*Aa,i:t}})}var r=br,u=wr,i=r,o=u,a=Kc;return n?t(n):(t.links=function(n){return nu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return nu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(jr),c=-1,s=a.length,l=a[s-1].edge,f=l.l===o?l.r:l.l;++c<s;)u=l,i=f,l=a[c].edge,f=l.l===o?l.r:l.l,r<i.i&&r<f.i&&eu(o,i,f)<0&&t.push([n[r],n[i.i],n[f.i]])}),t},t.x=function(n){return arguments.length?(i=_t(r=n),t):r},t.y=function(n){return arguments.length?(o=_t(u=n),t):u},t.clipExtent=function(n){return arguments.length?(a=null==n?Kc:n,t):a===Kc?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===Kc?null:a&&a[1]},t)};var Kc=[[-1e6,-1e6],[1e6,1e6]];Xo.geom.delaunay=function(n){return Xo.geom.voronoi().triangles(n)},Xo.geom.quadtree=function(n,t,e,r,u){function i(n){function i(n,t,e,r,u,i,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var c=n.x,l=n.y;if(null!=c)if(oa(c-e)+oa(l-r)<.01)s(n,t,e,r,u,i,o,a);else{var f=n.point;n.x=n.y=n.point=null,s(n,f,c,l,u,i,o,a),s(n,t,e,r,u,i,o,a)}else n.x=e,n.y=r,n.point=t}else s(n,t,e,r,u,i,o,a)}function s(n,t,e,r,u,o,a,c){var s=.5*(u+a),l=.5*(o+c),f=e>=s,h=r>=l,g=(h<<1)+f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=iu()),f?u=s:a=s,h?o=l:c=l,i(n,t,e,r,u,o,a,c)}var l,f,h,g,p,v,d,m,y,x=_t(a),M=_t(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)l=n[g],l.x<v&&(v=l.x),l.y<d&&(d=l.y),l.x>m&&(m=l.x),l.y>y&&(y=l.y),f.push(l.x),h.push(l.y);else for(g=0;p>g;++g){var _=+x(l=n[g],g),b=+M(l,g);v>_&&(v=_),d>b&&(d=b),_>m&&(m=_),b>y&&(y=b),f.push(_),h.push(b)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=iu();if(k.add=function(n){i(k,n,+x(n,++g),+M(n,g),v,d,m,y)},k.visit=function(n){ou(n,k,v,d,m,y)},g=-1,null==t){for(;++g<p;)i(k,n[g],f[g],h[g],v,d,m,y);--g}else n.forEach(k.add);return f=h=n=l=null,k}var o,a=br,c=wr;return(o=arguments.length)?(a=ru,c=uu,3===o&&(u=e,r=t,e=t=0),i(n)):(i.x=function(n){return arguments.length?(a=n,i):a},i.y=function(n){return arguments.length?(c=n,i):c},i.extent=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],u=+n[1][1]),i):null==t?null:[[t,e],[r,u]]},i.size=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=e=0,r=+n[0],u=+n[1]),i):null==t?null:[r-t,u-e]},i)},Xo.interpolateRgb=au,Xo.interpolateObject=cu,Xo.interpolateNumber=su,Xo.interpolateString=lu;var Qc=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g;Xo.interpolate=fu,Xo.interpolators=[function(n,t){var e=typeof t;return("string"===e?Va.has(t)||/^(#|rgb\(|hsl\()/.test(t)?au:lu:t instanceof G?au:"object"===e?Array.isArray(t)?hu:cu:su)(n,t)}],Xo.interpolateArray=hu;var ns=function(){return bt},ts=Xo.map({linear:ns,poly:xu,quad:function(){return du},cubic:function(){return mu},sin:function(){return Mu},exp:function(){return _u},circle:function(){return bu},elastic:wu,back:Su,bounce:function(){return ku}}),es=Xo.map({"in":bt,out:pu,"in-out":vu,"out-in":function(n){return vu(pu(n))}});Xo.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.substring(0,t):n,r=t>=0?n.substring(t+1):"in";return e=ts.get(e)||ns,r=es.get(r)||bt,gu(r(e.apply(null,$o.call(arguments,1))))},Xo.interpolateHcl=Eu,Xo.interpolateHsl=Au,Xo.interpolateLab=Cu,Xo.interpolateRound=Nu,Xo.transform=function(n){var t=Wo.createElementNS(Xo.ns.prefix.svg,"g");return(Xo.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Lu(e?e.matrix:rs)})(n)},Lu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var rs={a:1,b:0,c:0,d:1,e:0,f:0};Xo.interpolateTransform=Ru,Xo.layout={},Xo.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(Uu(n[e]));return t}},Xo.layout.chord=function(){function n(){var n,s,f,h,g,p={},v=[],d=Xo.range(i),m=[];for(e=[],r=[],n=0,h=-1;++h<i;){for(s=0,g=-1;++g<i;)s+=u[h][g];v.push(s),m.push(Xo.range(i)),n+=s}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&m.forEach(function(n,t){n.sort(function(n,e){return a(u[t][n],u[t][e])})}),n=(ka-l*i)/n,s=0,h=-1;++h<i;){for(f=s,g=-1;++g<i;){var y=d[h],x=m[y][g],M=u[y][x],_=s,b=s+=M*n;p[y+"-"+x]={index:y,subindex:x,startAngle:_,endAngle:b,value:M}}r[y]={index:y,startAngle:f,endAngle:s,value:(s-f)/n},s+=l}for(h=-1;++h<i;)for(g=h-1;++g<i;){var w=p[h+"-"+g],S=p[g+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}c&&t()}function t(){e.sort(function(n,t){return c((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,u,i,o,a,c,s={},l=0;return s.matrix=function(n){return arguments.length?(i=(u=n)&&u.length,e=r=null,s):u},s.padding=function(n){return arguments.length?(l=n,e=r=null,s):l},s.sortGroups=function(n){return arguments.length?(o=n,e=r=null,s):o},s.sortSubgroups=function(n){return arguments.length?(a=n,e=null,s):a},s.sortChords=function(n){return arguments.length?(c=n,e&&t(),s):c},s.chords=function(){return e||n(),e},s.groups=function(){return r||n(),r},s},Xo.layout.force=function(){function n(n){return function(t,e,r,u){if(t.point!==n){var i=t.cx-n.x,o=t.cy-n.y,a=u-e,c=i*i+o*o;if(c>a*a/d){if(p>c){var s=t.charge/c;n.px-=i*s,n.py-=o*s}return!0}if(t.point&&c&&p>c){var s=t.pointCharge/c;n.px-=i*s,n.py-=o*s}}return!t.charge}}function t(n){n.px=Xo.event.x,n.py=Xo.event.y,a.resume()}var e,r,u,i,o,a={},c=Xo.dispatch("start","tick","end"),s=[1,1],l=.9,f=us,h=is,g=-30,p=os,v=.1,d=.64,m=[],y=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,x,M,_=m.length,b=y.length;for(e=0;b>e;++e)a=y[e],f=a.source,h=a.target,x=h.x-f.x,M=h.y-f.y,(p=x*x+M*M)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,x*=p,M*=p,h.x-=x*(d=f.weight/(h.weight+f.weight)),h.y-=M*d,f.x+=x*(d=1-d),f.y+=M*d);if((d=r*v)&&(x=s[0]/2,M=s[1]/2,e=-1,d))for(;++e<_;)a=m[e],a.x+=(x-a.x)*d,a.y+=(M-a.y)*d;if(g)for(Zu(t=Xo.geom.quadtree(m),r,o),e=-1;++e<_;)(a=m[e]).fixed||t.visit(n(a));for(e=-1;++e<_;)a=m[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*l,a.y-=(a.py-(a.py=a.y))*l);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(m=n,a):m},a.links=function(n){return arguments.length?(y=n,a):y},a.size=function(n){return arguments.length?(s=n,a):s},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(l=+n,a):l},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.chargeDistance=function(n){return arguments.length?(p=n*n,a):Math.sqrt(p)},a.gravity=function(n){return arguments.length?(v=+n,a):v},a.theta=function(n){return arguments.length?(d=n*n,a):Math.sqrt(d)},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),Xo.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=y[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,s=o.length;++a<s;)if(!isNaN(i=o[a][n]))return i;return Math.random()*r}var t,e,r,c=m.length,l=y.length,p=s[0],v=s[1];for(t=0;c>t;++t)(r=m[t]).index=t,r.weight=0;for(t=0;l>t;++t)r=y[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;l>t;++t)u[t]=+f.call(this,y[t],t);else for(t=0;l>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;l>t;++t)i[t]=+h.call(this,y[t],t);else for(t=0;l>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=Xo.behavior.drag().origin(bt).on("dragstart.force",Fu).on("drag.force",t).on("dragend.force",Ou)),arguments.length?(this.on("mouseover.force",Yu).on("mouseout.force",Iu).call(e),void 0):e},Xo.rebind(a,c,"on")};var us=20,is=1,os=1/0;Xo.layout.hierarchy=function(){function n(t,o,a){var c=u.call(e,t,o);if(t.depth=o,a.push(t),c&&(s=c.length)){for(var s,l,f=-1,h=t.children=new Array(s),g=0,p=o+1;++f<s;)l=h[f]=n(c[f],p,a),l.parent=t,g+=l.value;r&&h.sort(r),i&&(t.value=g)}else delete t.children,i&&(t.value=+i.call(e,t,o)||0);return t}function t(n,r){var u=n.children,o=0;if(u&&(a=u.length))for(var a,c=-1,s=r+1;++c<a;)o+=t(u[c],s);else i&&(o=+i.call(e,n,r)||0);return i&&(n.value=o),o}function e(t){var e=[];return n(t,0,e),e}var r=Bu,u=Xu,i=$u;return e.sort=function(n){return arguments.length?(r=n,e):r},e.children=function(n){return arguments.length?(u=n,e):u},e.value=function(n){return arguments.length?(i=n,e):i},e.revalue=function(n){return t(n,0),n},e},Xo.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,s=-1;for(r=t.value?r/t.value:0;++s<o;)n(a=i[s],e,c=a.value*r,u),e+=c}}function t(n){var e=n.children,r=0;if(e&&(u=e.length))for(var u,i=-1;++i<u;)r=Math.max(r,t(e[i]));return 1+r}function e(e,i){var o=r.call(this,e,i);return n(o[0],0,u[0],u[1]/t(o[0])),o}var r=Xo.layout.hierarchy(),u=[1,1];return e.size=function(n){return arguments.length?(u=n,e):u},Vu(e,r)},Xo.layout.pie=function(){function n(i){var o=i.map(function(e,r){return+t.call(n,e,r)}),a=+("function"==typeof r?r.apply(this,arguments):r),c=(("function"==typeof u?u.apply(this,arguments):u)-a)/Xo.sum(o),s=Xo.range(i.length);null!=e&&s.sort(e===as?function(n,t){return o[t]-o[n]}:function(n,t){return e(i[n],i[t])});var l=[];return s.forEach(function(n){var t;l[n]={data:i[n],value:t=o[n],startAngle:a,endAngle:a+=t*c}}),l}var t=Number,e=as,r=0,u=ka;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n};var as={};Xo.layout.stack=function(){function n(a,c){var s=a.map(function(e,r){return t.call(n,e,r)}),l=s.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,l,c);s=Xo.permute(s,f),l=Xo.permute(l,f);var h,g,p,v=r.call(n,l,c),d=s.length,m=s[0].length;for(g=0;m>g;++g)for(u.call(n,s[0][g],p=v[g],l[0][g][1]),h=1;d>h;++h)u.call(n,s[h][g],p+=l[h-1][g][1],l[h][g][1]);return a}var t=bt,e=Qu,r=ni,u=Ku,i=Ju,o=Gu;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:cs.get(t)||Qu,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:ss.get(t)||ni,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var cs=Xo.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(ti),i=n.map(ei),o=Xo.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,s=[],l=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],s.push(e)):(c+=i[e],l.push(e));return l.reverse().concat(s)},reverse:function(n){return Xo.range(n.length).reverse()},"default":Qu}),ss=Xo.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,s,l=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=s=0,e=1;h>e;++e){for(t=0,u=0;l>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];l>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,s>c&&(s=c)}for(e=0;h>e;++e)g[e]-=s;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ni});Xo.layout.histogram=function(){function n(n,i){for(var o,a,c=[],s=n.map(e,this),l=r.call(this,s,i),f=u.call(this,l,s,i),i=-1,h=s.length,g=f.length-1,p=t?1:1/h;++i<g;)o=c[i]=[],o.dx=f[i+1]-(o.x=f[i]),o.y=0;if(g>0)for(i=-1;++i<h;)a=s[i],a>=l[0]&&a<=l[1]&&(o=c[Xo.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=oi,u=ui;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=_t(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return ii(n,t)}:_t(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},Xo.layout.tree=function(){function n(n,i){function o(n,t){var r=n.children,u=n._tree;if(r&&(i=r.length)){for(var i,a,s,l=r[0],f=l,h=-1;++h<i;)s=r[h],o(s,a),f=c(s,a,f),a=s;vi(n);var g=.5*(l._tree.prelim+s._tree.prelim);t?(u.prelim=t._tree.prelim+e(n,t),u.mod=u.prelim-g):u.prelim=g}else t&&(u.prelim=t._tree.prelim+e(n,t))}function a(n,t){n.x=n._tree.prelim+t;var e=n.children;if(e&&(r=e.length)){var r,u=-1;for(t+=n._tree.mod;++u<r;)a(e[u],t)}}function c(n,t,r){if(t){for(var u,i=n,o=n,a=t,c=n.parent.children[0],s=i._tree.mod,l=o._tree.mod,f=a._tree.mod,h=c._tree.mod;a=si(a),i=ci(i),a&&i;)c=ci(c),o=si(o),o._tree.ancestor=n,u=a._tree.prelim+f-i._tree.prelim-s+e(a,i),u>0&&(di(mi(a,n,r),n,u),s+=u,l+=u),f+=a._tree.mod,s+=i._tree.mod,h+=c._tree.mod,l+=o._tree.mod;a&&!si(o)&&(o._tree.thread=a,o._tree.mod+=f-l),i&&!ci(c)&&(c._tree.thread=i,c._tree.mod+=s-h,r=n)}return r}var s=t.call(this,n,i),l=s[0];pi(l,function(n,t){n._tree={ancestor:n,prelim:0,mod:0,change:0,shift:0,number:t?t._tree.number+1:0}}),o(l),a(l,-l._tree.prelim);var f=li(l,hi),h=li(l,fi),g=li(l,gi),p=f.x-e(f,h)/2,v=h.x+e(h,f)/2,d=g.depth||1;return pi(l,u?function(n){n.x*=r[0],n.y=n.depth*r[1],delete n._tree}:function(n){n.x=(n.x-p)/(v-p)*r[0],n.y=n.depth/d*r[1],delete n._tree}),s}var t=Xo.layout.hierarchy().sort(null).value(null),e=ai,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Vu(n,t)},Xo.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],s=u[1],l=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,pi(a,function(n){n.r=+l(n.value)}),pi(a,bi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/s))/2;pi(a,function(n){n.r+=f}),pi(a,bi),pi(a,function(n){n.r-=f})}return ki(a,c/2,s/2,t?1:1/Math.max(2*a.r/c,2*a.r/s)),o}var t,e=Xo.layout.hierarchy().sort(yi),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Vu(n,e)},Xo.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],s=0;pi(c,function(n){var t=n.children;t&&t.length?(n.x=Ci(t),n.y=Ai(t)):(n.x=o?s+=e(n,o):0,n.y=0,o=n)});var l=Ni(c),f=Li(c),h=l.x-e(l,f)/2,g=f.x+e(f,l)/2;return pi(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=Xo.layout.hierarchy().sort(null).value(null),e=ai,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Vu(n,t)},Xo.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++u<i;)r=(e=n[u]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,s=f(e),l=[],h=i.slice(),p=1/0,v="slice"===g?s.dx:"dice"===g?s.dy:"slice-dice"===g?1&e.depth?s.dy:s.dx:Math.min(s.dx,s.dy);for(n(h,s.dx*s.dy/e.value),l.area=0;(c=h.length)>0;)l.push(o=h[c-1]),l.area+=o.area,"squarify"!==g||(a=r(l,v))<=p?(h.pop(),p=a):(l.area-=l.pop().area,u(l,v,s,!1),v=Math.min(s.dx,s.dy),l.length=l.area=0,p=1/0);l.length&&(u(l,v,s,!0),l.length=l.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(i>e&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,s=e.y,l=t?c(n.area/t):0;if(t==e.dx){for((r||l>e.dy)&&(l=e.dy);++i<o;)u=n[i],u.x=a,u.y=s,u.dy=l,a+=u.dx=Math.min(e.x+e.dx-a,l?c(u.area/l):0);u.z=!0,u.dx+=e.x+e.dx-a,e.y+=l,e.dy-=l}else{for((r||l>e.dx)&&(l=e.dx);++i<o;)u=n[i],u.x=a,u.y=s,u.dx=l,s+=u.dy=Math.min(e.y+e.dy-s,l?c(u.area/l):0);u.z=!1,u.dy+=e.y+e.dy-s,e.x+=l,e.dx-=l}}function i(r){var u=o||a(r),i=u[0];return i.x=0,i.y=0,i.dx=s[0],i.dy=s[1],o&&a.revalue(i),n([i],i.dx*i.dy/i.value),(o?e:t)(i),h&&(o=u),u}var o,a=Xo.layout.hierarchy(),c=Math.round,s=[1,1],l=null,f=Ti,h=!1,g="squarify",p=.5*(1+Math.sqrt(5));return i.size=function(n){return arguments.length?(s=n,i):s},i.padding=function(n){function t(t){var e=n.call(i,t,t.depth);return null==e?Ti(t):qi(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return qi(t,n)}if(!arguments.length)return l;var r;return f=null==(l=n)?Ti:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,i},i.round=function(n){return arguments.length?(c=n?Math.round:Number,i):c!=Number},i.sticky=function(n){return arguments.length?(h=n,o=null,i):h},i.ratio=function(n){return arguments.length?(p=n,i):p},i.mode=function(n){return arguments.length?(g=n+"",i):g},Vu(i,a)},Xo.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=Xo.random.normal.apply(Xo,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=Xo.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},Xo.scale={};var ls={floor:bt,ceil:bt};Xo.scale.linear=function(){return Hi([0,1],[0,1],fu,!1)};var fs={s:1,g:1,p:1,r:1,e:1};Xo.scale.log=function(){return $i(Xo.scale.linear().domain([0,1]),10,!0,[1,10])};var hs=Xo.format(".0e"),gs={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};Xo.scale.pow=function(){return Bi(Xo.scale.linear(),1,[0,1])},Xo.scale.sqrt=function(){return Xo.scale.pow().exponent(.5)},Xo.scale.ordinal=function(){return Ji([],{t:"range",a:[[]]})},Xo.scale.category10=function(){return Xo.scale.ordinal().range(ps)},Xo.scale.category20=function(){return Xo.scale.ordinal().range(vs)},Xo.scale.category20b=function(){return Xo.scale.ordinal().range(ds)},Xo.scale.category20c=function(){return Xo.scale.ordinal().range(ms)};var ps=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(ht),vs=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(ht),ds=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(ht),ms=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(ht);Xo.scale.quantile=function(){return Gi([],[])},Xo.scale.quantize=function(){return Ki(0,1,[0,1])},Xo.scale.threshold=function(){return Qi([.5],[0,1])},Xo.scale.identity=function(){return no([0,1])},Xo.svg={},Xo.svg.arc=function(){function n(){var n=t.apply(this,arguments),i=e.apply(this,arguments),o=r.apply(this,arguments)+ys,a=u.apply(this,arguments)+ys,c=(o>a&&(c=o,o=a,a=c),a-o),s=Sa>c?"0":"1",l=Math.cos(o),f=Math.sin(o),h=Math.cos(a),g=Math.sin(a);return c>=xs?n?"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"M0,"+n+"A"+n+","+n+" 0 1,0 0,"+-n+"A"+n+","+n+" 0 1,0 0,"+n+"Z":"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"Z":n?"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L"+n*h+","+n*g+"A"+n+","+n+" 0 "+s+",0 "+n*l+","+n*f+"Z":"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L0,0"+"Z"}var t=to,e=eo,r=ro,u=uo;return n.innerRadius=function(e){return arguments.length?(t=_t(e),n):t},n.outerRadius=function(t){return arguments.length?(e=_t(t),n):e},n.startAngle=function(t){return arguments.length?(r=_t(t),n):r},n.endAngle=function(t){return arguments.length?(u=_t(t),n):u},n.centroid=function(){var n=(t.apply(this,arguments)+e.apply(this,arguments))/2,i=(r.apply(this,arguments)+u.apply(this,arguments))/2+ys;return[Math.cos(i)*n,Math.sin(i)*n]},n};var ys=-Ea,xs=ka-Aa;Xo.svg.line=function(){return io(bt)};var Ms=Xo.map({linear:oo,"linear-closed":ao,step:co,"step-before":so,"step-after":lo,basis:mo,"basis-open":yo,"basis-closed":xo,bundle:Mo,cardinal:go,"cardinal-open":fo,"cardinal-closed":ho,monotone:Eo});Ms.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var _s=[0,2/3,1/3,0],bs=[0,1/3,2/3,0],ws=[0,1/6,2/3,1/6];Xo.svg.line.radial=function(){var n=io(Ao);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},so.reverse=lo,lo.reverse=so,Xo.svg.area=function(){return Co(bt)},Xo.svg.area.radial=function(){var n=Co(Ao);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},Xo.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),s=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,s)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,s.r,s.p0)+r(s.r,s.p1,s.a1-s.a0)+u(s.r,s.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)+ys,l=s.call(n,u,r)+ys;return{r:i,a0:o,a1:l,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(l),i*Math.sin(l)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Sa)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=hr,o=gr,a=No,c=ro,s=uo;return n.radius=function(t){return arguments.length?(a=_t(t),n):a},n.source=function(t){return arguments.length?(i=_t(t),n):i},n.target=function(t){return arguments.length?(o=_t(t),n):o},n.startAngle=function(t){return arguments.length?(c=_t(t),n):c},n.endAngle=function(t){return arguments.length?(s=_t(t),n):s},n},Xo.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=hr,e=gr,r=Lo;return n.source=function(e){return arguments.length?(t=_t(e),n):t},n.target=function(t){return arguments.length?(e=_t(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},Xo.svg.diagonal.radial=function(){var n=Xo.svg.diagonal(),t=Lo,e=n.projection;return n.projection=function(n){return arguments.length?e(To(t=n)):t},n},Xo.svg.symbol=function(){function n(n,r){return(Ss.get(t.call(this,n,r))||Ro)(e.call(this,n,r))}var t=zo,e=qo;return n.type=function(e){return arguments.length?(t=_t(e),n):t},n.size=function(t){return arguments.length?(e=_t(t),n):e},n};var Ss=Xo.map({circle:Ro,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Cs)),e=t*Cs;return"M0,"+-t+"L"+e+",0"+" 0,"+t+" "+-e+",0"+"Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/As),e=t*As/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/As),e=t*As/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});Xo.svg.symbolTypes=Ss.keys();var ks,Es,As=Math.sqrt(3),Cs=Math.tan(30*Na),Ns=[],Ls=0;Ns.call=da.call,Ns.empty=da.empty,Ns.node=da.node,Ns.size=da.size,Xo.transition=function(n){return arguments.length?ks?n.transition():n:xa.transition()},Xo.transition.prototype=Ns,Ns.select=function(n){var t,e,r,u=this.id,i=[];n=M(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]);for(var c=this[o],s=-1,l=c.length;++s<l;)(r=c[s])&&(e=n.call(r,r.__data__,s,o))?("__data__"in r&&(e.__data__=r.__data__),jo(e,s,u,r.__transition__[u]),t.push(e)):t.push(null)}return Do(i,u)},Ns.selectAll=function(n){var t,e,r,u,i,o=this.id,a=[];n=_(n);for(var c=-1,s=this.length;++c<s;)for(var l=this[c],f=-1,h=l.length;++f<h;)if(r=l[f]){i=r.__transition__[o],e=n.call(r,r.__data__,f,c),a.push(t=[]);for(var g=-1,p=e.length;++g<p;)(u=e[g])&&jo(u,g,o,i),t.push(u)}return Do(a,o)},Ns.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=q(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return Do(u,this.id)},Ns.tween=function(n,t){var e=this.id;return arguments.length<2?this.node().__transition__[e].tween.get(n):R(this,null==t?function(t){t.__transition__[e].tween.remove(n)}:function(r){r.__transition__[e].tween.set(n,t)})},Ns.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Ru:fu,a=Xo.ns.qualify(n);return Po(this,"attr."+n,t,a.local?i:u)},Ns.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=Xo.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Ns.style=function(n,t,e){function r(){this.style.removeProperty(n)}function u(t){return null==t?r:(t+="",function(){var r,u=Go.getComputedStyle(this,null).getPropertyValue(n);return u!==t&&(r=fu(u,t),function(t){this.style.setProperty(n,r(t),e)})})}var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(t="");for(e in n)this.style(e,n[e],t);return this}e=""}return Po(this,"style."+n,t,u)},Ns.styleTween=function(n,t,e){function r(r,u){var i=t.call(this,r,u,Go.getComputedStyle(this,null).getPropertyValue(n));return i&&function(t){this.style.setProperty(n,i(t),e)}}return arguments.length<3&&(e=""),this.tween("style."+n,r)},Ns.text=function(n){return Po(this,"text",n,Uo)},Ns.remove=function(){return this.each("end.transition",function(){var n;this.__transition__.count<2&&(n=this.parentNode)&&n.removeChild(this)})},Ns.ease=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].ease:("function"!=typeof n&&(n=Xo.ease.apply(Xo,arguments)),R(this,function(e){e.__transition__[t].ease=n}))},Ns.delay=function(n){var t=this.id;return R(this,"function"==typeof n?function(e,r,u){e.__transition__[t].delay=+n.call(e,e.__data__,r,u)}:(n=+n,function(e){e.__transition__[t].delay=n}))},Ns.duration=function(n){var t=this.id;return R(this,"function"==typeof n?function(e,r,u){e.__transition__[t].duration=Math.max(1,n.call(e,e.__data__,r,u))}:(n=Math.max(1,n),function(e){e.__transition__[t].duration=n}))},Ns.each=function(n,t){var e=this.id;if(arguments.length<2){var r=Es,u=ks;ks=e,R(this,function(t,r,u){Es=t.__transition__[e],n.call(t,t.__data__,r,u)}),Es=r,ks=u}else R(this,function(r){var u=r.__transition__[e];(u.event||(u.event=Xo.dispatch("start","end"))).on(n,t)});return this},Ns.transition=function(){for(var n,t,e,r,u=this.id,i=++Ls,o=[],a=0,c=this.length;c>a;a++){o.push(n=[]);for(var t=this[a],s=0,l=t.length;l>s;s++)(e=t[s])&&(r=Object.create(e.__transition__[u]),r.delay+=r.duration,jo(e,s,i,r)),n.push(e)}return Do(o,i)},Xo.svg.axis=function(){function n(n){n.each(function(){var n,s=Xo.select(this),l=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):bt:t,p=s.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Aa),d=Xo.transition(p.exit()).style("opacity",Aa).remove(),m=Xo.transition(p).style("opacity",1),y=Ri(f),x=s.selectAll(".domain").data([0]),M=(x.enter().append("path").attr("class","domain"),Xo.transition(x));v.append("line"),v.append("text");var _=v.select("line"),b=m.select("line"),w=p.select("text").text(g),S=v.select("text"),k=m.select("text");switch(r){case"bottom":n=Ho,_.attr("y2",u),S.attr("y",Math.max(u,0)+o),b.attr("x2",0).attr("y2",u),k.attr("x",0).attr("y",Math.max(u,0)+o),w.attr("dy",".71em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+i+"V0H"+y[1]+"V"+i);break;case"top":n=Ho,_.attr("y2",-u),S.attr("y",-(Math.max(u,0)+o)),b.attr("x2",0).attr("y2",-u),k.attr("x",0).attr("y",-(Math.max(u,0)+o)),w.attr("dy","0em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+-i+"V0H"+y[1]+"V"+-i);break;case"left":n=Fo,_.attr("x2",-u),S.attr("x",-(Math.max(u,0)+o)),b.attr("x2",-u).attr("y2",0),k.attr("x",-(Math.max(u,0)+o)).attr("y",0),w.attr("dy",".32em").style("text-anchor","end"),M.attr("d","M"+-i+","+y[0]+"H0V"+y[1]+"H"+-i);break;case"right":n=Fo,_.attr("x2",u),S.attr("x",Math.max(u,0)+o),b.attr("x2",u).attr("y2",0),k.attr("x",Math.max(u,0)+o).attr("y",0),w.attr("dy",".32em").style("text-anchor","start"),M.attr("d","M"+i+","+y[0]+"H0V"+y[1]+"H"+i)}if(f.rangeBand){var E=f,A=E.rangeBand()/2;l=f=function(n){return E(n)+A}}else l.rangeBand?l=f:d.call(n,f);v.call(n,l),m.call(n,f)})}var t,e=Xo.scale.linear(),r=Ts,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in qs?t+"":Ts,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Ts="bottom",qs={top:1,right:1,bottom:1,left:1};Xo.svg.brush=function(){function n(i){i.each(function(){var i=Xo.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=i.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),i.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=i.selectAll(".resize").data(p,bt);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return zs[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,f=Xo.transition(i),h=Xo.transition(o);c&&(l=Ri(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),e(f)),s&&(l=Ri(s),h.attr("y",l[0]).attr("height",l[1]-l[0]),r(f)),t(f)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+l[+/e$/.test(n)]+","+f[+/^s/.test(n)]+")"})}function e(n){n.select(".extent").attr("x",l[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",l[1]-l[0])}function r(n){n.select(".extent").attr("y",f[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",f[1]-f[0])}function u(){function u(){32==Xo.event.keyCode&&(C||(x=null,L[0]-=l[1],L[1]-=f[1],C=2),d())}function p(){32==Xo.event.keyCode&&2==C&&(L[0]+=l[1],L[1]+=f[1],C=0,d())}function v(){var n=Xo.mouse(_),u=!1;M&&(n[0]+=M[0],n[1]+=M[1]),C||(Xo.event.altKey?(x||(x=[(l[0]+l[1])/2,(f[0]+f[1])/2]),L[0]=l[+(n[0]<x[0])],L[1]=f[+(n[1]<x[1])]):x=null),E&&m(n,c,0)&&(e(S),u=!0),A&&m(n,s,1)&&(r(S),u=!0),u&&(t(S),w({type:"brush",mode:C?"move":"resize"}))}function m(n,t,e){var r,u,a=Ri(t),c=a[0],s=a[1],p=L[e],v=e?f:l,d=v[1]-v[0];return C&&(c-=p,s-=d+p),r=(e?g:h)?Math.max(c,Math.min(s,n[e])):n[e],C?u=(r+=p)+d:(x&&(p=Math.max(c,Math.min(s,2*x[e]-r))),r>p?(u=r,r=p):u=p),v[0]!=r||v[1]!=u?(e?o=null:i=null,v[0]=r,v[1]=u,!0):void 0}function y(){v(),S.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),Xo.select("body").style("cursor",null),T.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),N(),w({type:"brushend"})}var x,M,_=this,b=Xo.select(Xo.event.target),w=a.of(_,arguments),S=Xo.select(_),k=b.datum(),E=!/^(n|s)$/.test(k)&&c,A=!/^(e|w)$/.test(k)&&s,C=b.classed("extent"),N=O(),L=Xo.mouse(_),T=Xo.select(Go).on("keydown.brush",u).on("keyup.brush",p);if(Xo.event.changedTouches?T.on("touchmove.brush",v).on("touchend.brush",y):T.on("mousemove.brush",v).on("mouseup.brush",y),S.interrupt().selectAll("*").interrupt(),C)L[0]=l[0]-L[0],L[1]=f[0]-L[1];else if(k){var q=+/w$/.test(k),z=+/^n/.test(k);M=[l[1-q]-L[0],f[1-z]-L[1]],L[0]=l[q],L[1]=f[z]}else Xo.event.altKey&&(x=L.slice());S.style("pointer-events","none").selectAll(".resize").style("display",null),Xo.select("body").style("cursor",b.style("cursor")),w({type:"brushstart"}),v()}var i,o,a=y(n,"brushstart","brush","brushend"),c=null,s=null,l=[0,0],f=[0,0],h=!0,g=!0,p=Rs[0];return n.event=function(n){n.each(function(){var n=a.of(this,arguments),t={x:l,y:f,i:i,j:o},e=this.__chart__||t;this.__chart__=t,ks?Xo.select(this).transition().each("start.brush",function(){i=e.i,o=e.j,l=e.x,f=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=hu(l,t.x),r=hu(f,t.y);return i=o=null,function(u){l=t.x=e(u),f=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){i=t.i,o=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,p=Rs[!c<<1|!s],n):c},n.y=function(t){return arguments.length?(s=t,p=Rs[!c<<1|!s],n):s},n.clamp=function(t){return arguments.length?(c&&s?(h=!!t[0],g=!!t[1]):c?h=!!t:s&&(g=!!t),n):c&&s?[h,g]:c?h:s?g:null},n.extent=function(t){var e,r,u,a,h;return arguments.length?(c&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),i=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(h=e,e=r,r=h),(e!=l[0]||r!=l[1])&&(l=[e,r])),s&&(u=t[0],a=t[1],c&&(u=u[1],a=a[1]),o=[u,a],s.invert&&(u=s(u),a=s(a)),u>a&&(h=u,u=a,a=h),(u!=f[0]||a!=f[1])&&(f=[u,a])),n):(c&&(i?(e=i[0],r=i[1]):(e=l[0],r=l[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(h=e,e=r,r=h))),s&&(o?(u=o[0],a=o[1]):(u=f[0],a=f[1],s.invert&&(u=s.invert(u),a=s.invert(a)),u>a&&(h=u,u=a,a=h))),c&&s?[[e,u],[r,a]]:c?[e,r]:s&&[u,a])},n.clear=function(){return n.empty()||(l=[0,0],f=[0,0],i=o=null),n},n.empty=function(){return!!c&&l[0]==l[1]||!!s&&f[0]==f[1]},Xo.rebind(n,a,"on")};var zs={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Rs=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Ds=tc.format=ac.timeFormat,Ps=Ds.utc,Us=Ps("%Y-%m-%dT%H:%M:%S.%LZ");Ds.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Oo:Us,Oo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Oo.toString=Us.toString,tc.second=Rt(function(n){return new ec(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),tc.seconds=tc.second.range,tc.seconds.utc=tc.second.utc.range,tc.minute=Rt(function(n){return new ec(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),tc.minutes=tc.minute.range,tc.minutes.utc=tc.minute.utc.range,tc.hour=Rt(function(n){var t=n.getTimezoneOffset()/60;return new ec(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),tc.hours=tc.hour.range,tc.hours.utc=tc.hour.utc.range,tc.month=Rt(function(n){return n=tc.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),tc.months=tc.month.range,tc.months.utc=tc.month.utc.range;var js=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Hs=[[tc.second,1],[tc.second,5],[tc.second,15],[tc.second,30],[tc.minute,1],[tc.minute,5],[tc.minute,15],[tc.minute,30],[tc.hour,1],[tc.hour,3],[tc.hour,6],[tc.hour,12],[tc.day,1],[tc.day,2],[tc.week,1],[tc.month,1],[tc.month,3],[tc.year,1]],Fs=Ds.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",be]]),Os={range:function(n,t,e){return Xo.range(Math.ceil(n/e)*e,+t,e).map(Io)},floor:bt,ceil:bt};Hs.year=tc.year,tc.scale=function(){return Yo(Xo.scale.linear(),Hs,Fs)};var Ys=Hs.map(function(n){return[n[0].utc,n[1]]}),Is=Ps.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",be]]);Ys.year=tc.year.utc,tc.scale.utc=function(){return Yo(Xo.scale.linear(),Ys,Is)},Xo.text=wt(function(n){return n.responseText}),Xo.json=function(n,t){return St(n,"application/json",Zo,t)},Xo.html=function(n,t){return St(n,"text/html",Vo,t)},Xo.xml=wt(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(Xo):"object"==typeof module&&module.exports?module.exports=Xo:this.d3=Xo}();'use strict';tr.exportTo('tr.ui.b',function(){var THIS_DOC=document.currentScript.ownerDocument;var svgNS='http://www.w3.org/2000/svg';var ColorScheme=tr.b.ColorScheme;function getColorOfKey(key,selected){var id=ColorScheme.getColorIdForGeneralPurposeString(key);if(selected)
+id+=ColorScheme.properties.brightenedOffsets[0];return ColorScheme.colorsAsStrings[id];}
+var ChartBase=tr.ui.b.define('svg',undefined,svgNS);ChartBase.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.classList.add('chart-base');this.chartTitle_=undefined;this.seriesKeys_=undefined;this.width_=400;this.height_=300;var template=THIS_DOC.querySelector('#chart-base-template');var svgEl=template.content.querySelector('svg');for(var i=0;i<svgEl.children.length;i++)
+this.appendChild(svgEl.children[i].cloneNode(true));Object.defineProperty(this,'width',{get:function(){return this.width_;},set:function(width){this.width_=width;this.updateContents_();}});Object.defineProperty(this,'height',{get:function(){return this.height_;},set:function(height){this.height_=height;this.updateContents_();}});},get chartTitle(){return this.chartTitle_;},set chartTitle(chartTitle){this.chartTitle_=chartTitle;this.updateContents_();},get chartAreaElement(){return this.querySelector('#chart-area');},setSize:function(size){this.width_=size.width;this.height_=size.height;this.updateContents_();},getMargin_:function(){var margin={top:20,right:20,bottom:30,left:50};if(this.chartTitle_)
+margin.top+=20;return margin;},get margin(){return this.getMargin_();},get chartAreaSize(){var margin=this.margin;return{width:this.width_-margin.left-margin.right,height:this.height_-margin.top-margin.bottom};},getLegendKeys_:function(){throw new Error('Not implemented');},updateScales_:function(){throw new Error('Not implemented');},updateContents_:function(){var margin=this.margin;var thisSel=d3.select(this);thisSel.attr('width',this.width_);thisSel.attr('height',this.height_);var chartAreaSel=d3.select(this.chartAreaElement);chartAreaSel.attr('transform','translate('+margin.left+','+margin.top+')');this.updateScales_();this.updateTitle_(chartAreaSel);this.updateLegend_();},updateTitle_:function(chartAreaSel){var titleSel=chartAreaSel.select('#title');if(!this.chartTitle_){titleSel.style('display','none');return;}
+var width=this.chartAreaSize.width;titleSel.attr('transform','translate('+width*0.5+',-5)').style('display',undefined).style('text-anchor','middle').attr('class','title').attr('width',width).text(this.chartTitle_);},updateLegend_:function(){var keys=this.getLegendKeys_();if(keys===undefined)
+return;var chartAreaSel=d3.select(this.chartAreaElement);var chartAreaSize=this.chartAreaSize;var legendEntriesSel=chartAreaSel.selectAll('.legend').data(keys.slice().reverse());legendEntriesSel.enter().append('g').attr('class','legend').attr('transform',function(d,i){return'translate(0,'+i*20+')';}).append('text').text(function(key){return key;});legendEntriesSel.exit().remove();legendEntriesSel.attr('x',chartAreaSize.width-18).attr('width',18).attr('height',18).style('fill',function(key){var selected=this.currentHighlightedLegendKey===key;return getColorOfKey(key,selected);}.bind(this));legendEntriesSel.selectAll('text').attr('x',chartAreaSize.width-24).attr('y',9).attr('dy','.35em').style('text-anchor','end').text(function(d){return d;});},get highlightedLegendKey(){return this.highlightedLegendKey_;},set highlightedLegendKey(highlightedLegendKey){this.highlightedLegendKey_=highlightedLegendKey;this.updateHighlight_();},get currentHighlightedLegendKey(){if(this.tempHighlightedLegendKey_)
+return this.tempHighlightedLegendKey_;return this.highlightedLegendKey_;},pushTempHighlightedLegendKey:function(key){if(this.tempHighlightedLegendKey_)
+throw new Error('push cannot nest');this.tempHighlightedLegendKey_=key;this.updateHighlight_();},popTempHighlightedLegendKey:function(key){if(this.tempHighlightedLegendKey_!=key)
+throw new Error('pop cannot happen');this.tempHighlightedLegendKey_=undefined;this.updateHighlight_();},updateHighlight_:function(){var chartAreaSel=d3.select(this.chartAreaElement);var legendEntriesSel=chartAreaSel.selectAll('.legend');var that=this;legendEntriesSel.each(function(key){var highlighted=key==that.currentHighlightedLegendKey;var color=getColorOfKey(key,highlighted);this.style.fill=color;if(highlighted)
+this.style.fontWeight='bold';else
+this.style.fontWeight='';});}};return{getColorOfKey:getColorOfKey,ChartBase:ChartBase};});'use strict';tr.exportTo('tr.ui.b',function(){function MouseTracker(opt_targetElement){this.onMouseDown_=this.onMouseDown_.bind(this);this.onMouseMove_=this.onMouseMove_.bind(this);this.onMouseUp_=this.onMouseUp_.bind(this);this.targetElement=opt_targetElement;}
+MouseTracker.prototype={get targetElement(){return this.targetElement_;},set targetElement(targetElement){if(this.targetElement_)
+this.targetElement_.removeEventListener('mousedown',this.onMouseDown_);this.targetElement_=targetElement;if(this.targetElement_)
+this.targetElement_.addEventListener('mousedown',this.onMouseDown_);},onMouseDown_:function(e){if(e.button!==0)
+return true;e=this.remakeEvent_(e,'mouse-tracker-start');this.targetElement_.dispatchEvent(e);document.addEventListener('mousemove',this.onMouseMove_);document.addEventListener('mouseup',this.onMouseUp_);this.targetElement_.addEventListener('blur',this.onMouseUp_);this.savePreviousUserSelect_=document.body.style['-webkit-user-select'];document.body.style['-webkit-user-select']='none';e.preventDefault();return true;},onMouseMove_:function(e){e=this.remakeEvent_(e,'mouse-tracker-move');this.targetElement_.dispatchEvent(e);},onMouseUp_:function(e){document.removeEventListener('mousemove',this.onMouseMove_);document.removeEventListener('mouseup',this.onMouseUp_);this.targetElement_.removeEventListener('blur',this.onMouseUp_);document.body.style['-webkit-user-select']=this.savePreviousUserSelect_;e=this.remakeEvent_(e,'mouse-tracker-end');this.targetElement_.dispatchEvent(e);},remakeEvent_:function(e,newType){var remade=new tr.b.Event(newType,true,true);remade.x=e.x;remade.y=e.y;remade.offsetX=e.offsetX;remade.offsetY=e.offsetY;remade.clientX=e.clientX;remade.clientY=e.clientY;return remade;}};function trackMouseMovesUntilMouseUp(mouseMoveHandler,opt_mouseUpHandler,opt_keyUpHandler){function cleanupAndDispatchToMouseUp(e){document.removeEventListener('mousemove',mouseMoveHandler);if(opt_keyUpHandler)
+document.removeEventListener('keyup',opt_keyUpHandler);document.removeEventListener('mouseup',cleanupAndDispatchToMouseUp);if(opt_mouseUpHandler)
+opt_mouseUpHandler(e);}
+document.addEventListener('mousemove',mouseMoveHandler);if(opt_keyUpHandler)
+document.addEventListener('keyup',opt_keyUpHandler);document.addEventListener('mouseup',cleanupAndDispatchToMouseUp);}
+return{MouseTracker:MouseTracker,trackMouseMovesUntilMouseUp:trackMouseMovesUntilMouseUp};});'use strict';tr.exportTo('tr.ui.b',function(){var ChartBase=tr.ui.b.ChartBase;var ChartBase2D=tr.ui.b.define('chart-base-2d',ChartBase);ChartBase2D.prototype={__proto__:ChartBase.prototype,decorate:function(){ChartBase.prototype.decorate.call(this);this.classList.add('chart-base-2d');this.xScale_=d3.scale.linear();this.yScale_=d3.scale.linear();this.data_=[];this.seriesKeys_=[];this.leftMargin_=50;d3.select(this.chartAreaElement).append('g').attr('id','brushes');d3.select(this.chartAreaElement).append('g').attr('id','series');this.addEventListener('mousedown',this.onMouseDown_.bind(this));},get data(){return this.data_;},set data(data){if(data===undefined)
+throw new Error('data must be an Array');this.data_=data;this.updateSeriesKeys_();this.updateContents_();},getSampleWidth_:function(data,index,leftSide){var leftIndex,rightIndex;if(leftSide){leftIndex=Math.max(index-1,0);rightIndex=index;}else{leftIndex=index;rightIndex=Math.min(index+1,data.length-1);}
+var leftWidth=this.getXForDatum_(data[index],index)-
+this.getXForDatum_(data[leftIndex],leftIndex);var rightWidth=this.getXForDatum_(data[rightIndex],rightIndex)-
+this.getXForDatum_(data[index],index);return leftWidth*0.5+rightWidth*0.5;},getLegendKeys_:function(){if(this.seriesKeys_&&this.seriesKeys_.length>1)
+return this.seriesKeys_.slice();return[];},updateSeriesKeys_:function(){var keySet={};this.data_.forEach(function(datum){Object.keys(datum).forEach(function(key){if(this.isDatumFieldSeries_(key))
+keySet[key]=true;},this);},this);this.seriesKeys_=Object.keys(keySet);},isDatumFieldSeries_:function(fieldName){throw new Error('Not implemented');},getXForDatum_:function(datum,index){throw new Error('Not implemented');},updateScales_:function(){if(this.data_.length===0)
+return;var width=this.chartAreaSize.width;var height=this.chartAreaSize.height;this.xScale_.range([0,width]);this.xScale_.domain(d3.extent(this.data_,this.getXForDatum_.bind(this)));var yRange=new tr.b.Range();this.data_.forEach(function(datum){this.seriesKeys_.forEach(function(key){if(datum[key]!==undefined)
+yRange.addValue(datum[key]);});},this);this.yScale_.range([height,0]);this.yScale_.domain([yRange.min,yRange.max]);},updateBrushContents_:function(brushSel){brushSel.selectAll('*').remove();},updateXAxis_:function(xAxis){xAxis.selectAll('*').remove();xAxis[0][0].style.opacity=0;xAxis.attr('transform','translate(0,'+this.chartAreaSize.height+')').call(d3.svg.axis().scale(this.xScale_).orient('bottom'));window.requestAnimationFrame(function(){var previousRight=undefined;xAxis.selectAll('.tick')[0].forEach(function(tick){var currentLeft=tick.transform.baseVal[0].matrix.e;if((previousRight===undefined)||(currentLeft>(previousRight+3))){var currentWidth=tick.getBBox().width;previousRight=currentLeft+currentWidth;}else{tick.style.opacity=0;}});xAxis[0][0].style.opacity=1;});},getMargin_:function(){var margin=ChartBase.prototype.getMargin_.call(this);margin.left=this.leftMargin_;return margin;},updateYAxis_:function(yAxis){yAxis.selectAll('*').remove();yAxis[0][0].style.opacity=0;yAxis.call(d3.svg.axis().scale(this.yScale_).orient('left'));window.requestAnimationFrame(function(){var previousTop=undefined;var leftMargin=0;yAxis.selectAll('.tick')[0].forEach(function(tick){var bbox=tick.getBBox();leftMargin=Math.max(leftMargin,bbox.width);var currentTop=tick.transform.baseVal[0].matrix.f;var currentBottom=currentTop+bbox.height;if((previousTop===undefined)||(previousTop>(currentBottom+3))){previousTop=currentTop;}else{tick.style.opacity=0;}});if(leftMargin>this.leftMargin_){this.leftMargin_=leftMargin;this.updateContents_();}else{yAxis[0][0].style.opacity=1;}}.bind(this));},updateContents_:function(){ChartBase.prototype.updateContents_.call(this);var chartAreaSel=d3.select(this.chartAreaElement);this.updateXAxis_(chartAreaSel.select('.x.axis'));this.updateYAxis_(chartAreaSel.select('.y.axis'));this.updateBrushContents_(chartAreaSel.select('#brushes'));this.updateDataContents_(chartAreaSel.select('#series'));},updateDataContents_:function(seriesSel){throw new Error('Not implemented');},getDataBySeriesKey_:function(){var dataBySeriesKey={};this.seriesKeys_.forEach(function(seriesKey){dataBySeriesKey[seriesKey]=[];});this.data_.forEach(function(multiSeriesDatum,index){var x=this.getXForDatum_(multiSeriesDatum,index);d3.keys(multiSeriesDatum).forEach(function(seriesKey){if(seriesKey==='x')
+return;if(multiSeriesDatum[seriesKey]===undefined)
+return;var singleSeriesDatum={x:x};singleSeriesDatum[seriesKey]=multiSeriesDatum[seriesKey];dataBySeriesKey[seriesKey].push(singleSeriesDatum);});},this);return dataBySeriesKey;},getDataPointAtClientPoint_:function(clientX,clientY){var rect=this.getBoundingClientRect();var margin=this.margin;var x=clientX-rect.left-margin.left;var y=clientY-rect.top-margin.top;x=this.xScale_.invert(x);y=this.yScale_.invert(y);x=tr.b.clamp(x,this.xScale_.domain()[0],this.xScale_.domain()[1]);y=tr.b.clamp(y,this.yScale_.domain()[0],this.yScale_.domain()[1]);return{x:x,y:y};},prepareDataEvent_:function(mouseEvent,dataEvent){var dataPoint=this.getDataPointAtClientPoint_(mouseEvent.clientX,mouseEvent.clientY);dataEvent.x=dataPoint.x;dataEvent.y=dataPoint.y;},onMouseDown_:function(mouseEvent){tr.ui.b.trackMouseMovesUntilMouseUp(this.onMouseMove_.bind(this,mouseEvent.button),this.onMouseUp_.bind(this,mouseEvent.button));mouseEvent.preventDefault();mouseEvent.stopPropagation();var dataEvent=new tr.b.Event('item-mousedown');dataEvent.button=mouseEvent.button;this.classList.add('updating-brushing-state');this.prepareDataEvent_(mouseEvent,dataEvent);this.dispatchEvent(dataEvent);},onMouseMove_:function(button,mouseEvent){if(mouseEvent.buttons!==undefined){mouseEvent.preventDefault();mouseEvent.stopPropagation();}
+var dataEvent=new tr.b.Event('item-mousemove');dataEvent.button=button;this.prepareDataEvent_(mouseEvent,dataEvent);this.dispatchEvent(dataEvent);},onMouseUp_:function(button,mouseEvent){mouseEvent.preventDefault();mouseEvent.stopPropagation();var dataEvent=new tr.b.Event('item-mouseup');dataEvent.button=button;this.prepareDataEvent_(mouseEvent,dataEvent);this.dispatchEvent(dataEvent);this.classList.remove('updating-brushing-state');}};return{ChartBase2D:ChartBase2D};});'use strict';tr.exportTo('tr.ui.b',function(){var ChartBase2D=tr.ui.b.ChartBase2D;var ChartBase2DBrushX=tr.ui.b.define('chart-base-2d-brush-1d',ChartBase2D);ChartBase2DBrushX.prototype={__proto__:ChartBase2D.prototype,decorate:function(){ChartBase2D.prototype.decorate.call(this);this.brushedRange_=new tr.b.Range();},set brushedRange(range){this.brushedRange_.reset();this.brushedRange_.addRange(range);this.updateContents_();},computeBrushRangeFromIndices:function(indexA,indexB){indexA=tr.b.clamp(indexA,0,this.data_.length-1);indexB=tr.b.clamp(indexB,0,this.data_.length-1);var leftIndex=Math.min(indexA,indexB);var rightIndex=Math.max(indexA,indexB);var r=new tr.b.Range();r.addValue(this.getXForDatum_(this.data_[leftIndex],leftIndex)-
+this.getSampleWidth_(this.data_,leftIndex,true));r.addValue(this.getXForDatum_(this.data_[rightIndex],rightIndex)+
+this.getSampleWidth_(this.data_,rightIndex,false));return r;},getDataIndex_:function(dataX){if(!this.data_)
+return undefined;var bisect=d3.bisector(this.getXForDatum_.bind(this)).right;return bisect(this.data_,dataX)-1;},prepareDataEvent_:function(mouseEvent,dataEvent){ChartBase2D.prototype.prepareDataEvent_.call(this,mouseEvent,dataEvent);dataEvent.index=this.getDataIndex_(dataEvent.x);if(dataEvent.index!==undefined)
+dataEvent.data=this.data_[dataEvent.index];},updateBrushContents_:function(brushSel){brushSel.selectAll('*').remove();var brushes=this.brushedRange_.isEmpty?[]:[this.brushedRange_];var brushRectsSel=brushSel.selectAll('rect').data(brushes);brushRectsSel.enter().append('rect');brushRectsSel.exit().remove();brushRectsSel.attr('x',function(d){return this.xScale_(d.min);}.bind(this)).attr('y',0).attr('width',function(d){return this.xScale_(d.max)-this.xScale_(d.min);}.bind(this)).attr('height',this.chartAreaSize.height);}};return{ChartBase2DBrushX:ChartBase2DBrushX};});'use strict';tr.exportTo('tr.ui.b',function(){var ChartBase2DBrushX=tr.ui.b.ChartBase2DBrushX;var LineChart=tr.ui.b.define('line-chart',ChartBase2DBrushX);LineChart.prototype={__proto__:ChartBase2DBrushX.prototype,decorate:function(){ChartBase2DBrushX.prototype.decorate.call(this);this.classList.add('line-chart');},isDatumFieldSeries_:function(fieldName){return fieldName!='x';},getXForDatum_:function(datum,index){return datum.x;},updateDataContents_:function(dataSel){dataSel.selectAll('*').remove();var dataBySeriesKey=this.getDataBySeriesKey_();var pathsSel=dataSel.selectAll('path').data(this.seriesKeys_);pathsSel.enter().append('path').attr('class','line').style('stroke',function(key){return tr.ui.b.getColorOfKey(key);}).attr('d',function(key){var line=d3.svg.line().x(function(d){return this.xScale_(d.x);}.bind(this)).y(function(d){return this.yScale_(d[key]);}.bind(this));return line(dataBySeriesKey[key]);}.bind(this));pathsSel.exit().remove();}};return{LineChart:LineChart};});'use strict';var EventSet=tr.model.EventSet;var CHART_TITLE='Power (in mW) by ms since vertical sync';var CHART_WIDTH_FRACTION_OF_BODY=0.5;Polymer('tr-ui-a-frame-power-usage-chart',{ready:function(){this.chart_=undefined;this.samples_=new EventSet();this.vSyncTimestamps_=[];},get chart(){return this.chart_;},get samples(){return this.samples_;},get vSyncTimestamps(){return this.vSyncTimestamps_;},setData:function(samples,vSyncTimestamps){this.samples_=(samples===undefined)?new EventSet():samples;this.vSyncTimestamps_=(vSyncTimestamps===undefined)?[]:vSyncTimestamps;this.updateContents_();},updateContents_:function(){this.clearChart_();var data=this.getDataForLineChart_();if(data.length===0)
+return;this.chart_=this.createChart_(data);this.$.content.appendChild(this.chart_);},createChart_:function(data){var chart=new tr.ui.b.LineChart();var width=document.body.clientWidth*CHART_WIDTH_FRACTION_OF_BODY;chart.setSize({width:width,height:chart.height});chart.chartTitle=CHART_TITLE;chart.data=data;return chart;},clearChart_:function(){var content=this.$.content;while(content.firstChild)
+content.removeChild(content.firstChild);this.chart_=undefined;},getDataForLineChart_:function(){var sortedSamples=this.sortSamplesByTimestampAscending_(this.samples);var vSyncTimestamps=this.vSyncTimestamps.slice();var lastVSyncTimestamp=undefined;var points=[];var frameNumber=0;sortedSamples.forEach(function(sample){while(vSyncTimestamps.length>0&&vSyncTimestamps[0]<=sample.start){lastVSyncTimestamp=vSyncTimestamps.shift();frameNumber++;}
+if(lastVSyncTimestamp===undefined)
+return;var point={x:sample.start-lastVSyncTimestamp};point['f'+frameNumber]=sample.power;points.push(point);});return points;},sortSamplesByTimestampAscending_:function(samples){return samples.toArray().sort(function(smpl1,smpl2){return smpl1.start-smpl2.start;});}});'use strict';Polymer('tr-ui-a-power-sample-summary-table',{ready:function(){this.$.table.tableColumns=[{title:'Min power',width:'100px',value:function(row){return tr.b.u.Units.powerInWatts.format(row.min/1000.0);}},{title:'Max power',width:'100px',value:function(row){return tr.b.u.Units.powerInWatts.format(row.max/1000.0);}},{title:'Time-weighted average',width:'100px',value:function(row){return tr.b.u.Units.powerInWatts.format(row.timeWeightedAverage/1000.0);}},{title:'Energy consumed',width:'100px',value:function(row){return tr.b.u.Units.energyInJoules.format(row.energyConsumed);}},{title:'Sample count',width:'100%',value:function(row){return row.sampleCount;}}];this.samples=new tr.model.EventSet();},get samples(){return this.samples_;},set samples(samples){if(samples===this.samples)
+return;this.samples_=(samples===undefined)?new tr.model.EventSet():samples;this.updateContents_();},updateContents_:function(){if(this.samples.length===0){this.$.table.tableRows=[];}else{this.$.table.tableRows=[{min:this.getMin(),max:this.getMax(),timeWeightedAverage:this.getTimeWeightedAverage(),energyConsumed:this.getEnergyConsumed(),sampleCount:this.samples.length}];}
+this.$.table.rebuild();},getMin:function(){return Math.min.apply(null,this.samples.map(function(sample){return sample.power;}));},getMax:function(){return Math.max.apply(null,this.samples.map(function(sample){return sample.power;}));},getTimeWeightedAverage:function(){var energyConsumed=this.getEnergyConsumed();if(energyConsumed==='N/A')
+return'N/A';return this.getEnergyConsumed()/this.samples.bounds.duration*1000;},getEnergyConsumed:function(){if(this.samples.length<2)
+return'N/A';var bounds=this.samples.bounds;return this.samples[0].series.getEnergyConsumed(bounds.min,bounds.max);}});'use strict';Polymer('tr-ui-a-multi-power-sample-sub-view',{ready:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},updateContents_:function(){var samples=this.selection;var vSyncTimestamps=(this.selection===undefined)?[]:this.selection[0].series.device.vSyncTimestamps;this.$.summaryTable.samples=samples;this.$.samplesTable.samples=samples;this.$.chart.setData(this.selection,vSyncTimestamps);}});'use strict';(function(){var EventRegistry=tr.model.EventRegistry;Polymer('tr-ui-a-analysis-view',{ready:function(){this.tabView_=document.createElement('tr-ui-a-tab-view');this.tabView_.style.flex='1 1 auto';this.appendChild(this.tabView_);this.brushingStateController_=undefined;this.onSelectedTabChange_=this.onSelectedTabChange_.bind(this);this.onSelectionChanged_=this.onSelectionChanged_.bind(this);this.lastSeenSelection_=new tr.model.EventSet();},set tallMode(value){if(value)
+this.classList.add('tall-mode');else
+this.classList.remove('tall-mode');},get tallMode(){return this.classList.contains('tall-mode');},get tabView(){return this.tabView_;},get brushingStateController(){return this.brushingStateController_;},set brushingStateController(brushingStateController){if(this.brushingStateController){this.brushingStateController_.removeEventListener('change',this.onSelectionChanged_);}
+this.brushingStateController_=brushingStateController;if(this.brushingStateController){this.brushingStateController_.addEventListener('change',this.onSelectionChanged_);}
+this.onSelectionChanged_();},get selection(){return this.brushingStateController_.selection;},onSelectionChanged_:function(e){var selection=this.brushingStateController_.selection;var selectionHasSameValue=this.lastSeenSelection_.equals(selection);this.lastSeenSelection_=selection;if(selectionHasSameValue)
+return;var lastSelectedTabTagName;var lastSelectedTabTypeName;if(this.tabView_.selectedTab){lastSelectedTabTagName=this.tabView_.selectedTab.tagName;lastSelectedTabTypeName=this.tabView_.selectedTab._eventTypeName;}
+this.tallMode=false;var previouslySelectedTab=this.tabView_.selectedTab;this.tabView_.removeEventListener('selected-tab-change',this.onSelectedTabChange_);var previousSubViews={};for(var i=0;i<this.tabView_.children.length;i++){var previousSubView=this.tabView_.children[i];previousSubViews[previousSubView._eventTypeName]=previousSubView;}
+this.tabView_.saveTabStates();this.tabView_.textContent='';if(selection.length==0){this.tabView_.tabStripHeadingText='Nothing selected. Tap stuff.';}else if(selection.length==1){this.tabView_.tabStripHeadingText='1 item selected: ';}else{this.tabView_.tabStripHeadingText=selection.length+' items selected: ';}
+var eventsByBaseTypeName=selection.getEventsOrganizedByBaseType(true);var numBaseTypesToAnalyze=tr.b.dictionaryLength(eventsByBaseTypeName);for(var eventTypeName in eventsByBaseTypeName){var subSelection=eventsByBaseTypeName[eventTypeName];var subView=this.createSubViewForSelection_(eventTypeName,subSelection,previousSubViews[eventTypeName]);subView._eventTypeName=eventTypeName;this.tabView_.appendChild(subView);subView.selection=subSelection;}
+var tab;if(lastSelectedTabTagName)
+tab=this.tabView_.querySelector(lastSelectedTabTagName);if(!tab&&lastSelectedTabTypeName){var tab=tr.b.findFirstInArray(this.tabView_.children,function(tab){return tab._eventTypeName===lastSelectedTabTypeName;});}
+if(!tab)
+tab=this.tabView_.firstChild;this.tabView_.selectedTab=tab;this.onSelectedTabChange_();this.tabView_.addEventListener('selected-tab-change',this.onSelectedTabChange_);},createSubViewForSelection_:function(eventTypeName,subSelection,previousSubView){var eventTypeInfo=EventRegistry.getEventTypeInfoByTypeName(eventTypeName);var singleMode=subSelection.length==1;var tagName;if(subSelection.length===1)
+tagName=eventTypeInfo.metadata.singleViewElementName;else
+tagName=eventTypeInfo.metadata.multiViewElementName;if(!tr.ui.b.getPolymerElementNamed(tagName))
+throw new Error('Element not registered: '+tagName);var subView;if(previousSubView&&previousSubView.tagName===tagName.toUpperCase())
+subView=previousSubView;else
+subView=document.createElement(tagName);var camelLabel;if(subSelection.length===1)
+camelLabel=EventRegistry.getUserFriendlySingularName(eventTypeName);else
+camelLabel=EventRegistry.getUserFriendlyPluralName(eventTypeName);subView.tabLabel=camelLabel+' ('+subSelection.length+')';return subView;},onSelectedTabChange_:function(){var brushingStateController=this.brushingStateController_;if(this.tabView_.selectedTab){var selectedTab=this.tabView_.selectedTab;this.tallMode=selectedTab.requiresTallView;if(brushingStateController){var rlth=selectedTab.relatedEventsToHighlight;brushingStateController.changeAnalysisViewRelatedEvents(rlth);}}else{this.tallMode=false;if(brushingStateController)
+brushingStateController.changeAnalysisViewRelatedEvents(undefined);}}});})();'use strict';tr.exportTo('tr.ui.b',function(){var DragHandle=tr.ui.b.define('x-drag-handle');DragHandle.prototype={__proto__:HTMLDivElement.prototype,decorate:function(){this.lastMousePos_=0;this.onMouseMove_=this.onMouseMove_.bind(this);this.onMouseUp_=this.onMouseUp_.bind(this);this.addEventListener('mousedown',this.onMouseDown_);this.target_=undefined;this.horizontal=true;this.observer_=new WebKitMutationObserver(this.didTargetMutate_.bind(this));this.targetSizesByModeKey_={};},get modeKey_(){return this.target_.className==''?'.':this.target_.className;},get target(){return this.target_;},set target(target){this.observer_.disconnect();this.target_=target;if(!this.target_)
+return;this.observer_.observe(this.target_,{attributes:true,attributeFilter:['class']});},get horizontal(){return this.horizontal_;},set horizontal(h){this.horizontal_=h;if(this.horizontal_)
+this.className='horizontal-drag-handle';else
+this.className='vertical-drag-handle';},get vertical(){return!this.horizontal_;},set vertical(v){this.horizontal=!v;},forceMutationObserverFlush_:function(){var records=this.observer_.takeRecords();if(records.length)
+this.didTargetMutate_(records);},didTargetMutate_:function(e){var modeSize=this.targetSizesByModeKey_[this.modeKey_];if(modeSize!==undefined){this.setTargetSize_(modeSize);return;}
+this.target_.style[this.targetStyleKey_]='';},get targetStyleKey_(){return this.horizontal_?'height':'width';},getTargetSize_:function(){var targetStyleKey=this.targetStyleKey_;if(!this.target_.style[targetStyleKey]){this.target_.style[targetStyleKey]=window.getComputedStyle(this.target_)[targetStyleKey];}
+var size=parseInt(this.target_.style[targetStyleKey]);this.targetSizesByModeKey_[this.modeKey_]=size;return size;},setTargetSize_:function(s){this.target_.style[this.targetStyleKey_]=s+'px';this.targetSizesByModeKey_[this.modeKey_]=s;},applyDelta_:function(delta){var curSize=this.getTargetSize_();var newSize;if(this.target_===this.nextElementSibling){newSize=curSize+delta;}else{newSize=curSize-delta;}
+this.setTargetSize_(newSize);},onMouseMove_:function(e){var curMousePos=this.horizontal_?e.clientY:e.clientX;var delta=this.lastMousePos_-curMousePos;this.applyDelta_(delta);this.lastMousePos_=curMousePos;e.preventDefault();return true;},onMouseDown_:function(e){if(!this.target_)
+return;this.forceMutationObserverFlush_();this.lastMousePos_=this.horizontal_?e.clientY:e.clientX;document.addEventListener('mousemove',this.onMouseMove_);document.addEventListener('mouseup',this.onMouseUp_);e.preventDefault();return true;},onMouseUp_:function(e){document.removeEventListener('mousemove',this.onMouseMove_);document.removeEventListener('mouseup',this.onMouseUp_);e.preventDefault();}};return{DragHandle:DragHandle};});'use strict';Polymer('tr-ui-b-dropdown',{ready:function(){this.$.outer.tabIndex=0;},get iconElement(){return this.$.icon;},onOuterKeyDown_:function(e){if(e.keyCode===' '.charCodeAt(0)){this.toggle_();e.preventDefault();e.stopPropagation();}},onOuterClick_:function(e){var or=this.$.outer.getBoundingClientRect();var inside=true;inside&=e.clientX>=or.left;inside&=e.clientX<or.right;inside&=e.clientY>=or.top;inside&=e.clientY<or.bottom;if(!inside)
+return;e.preventDefault();this.toggle_();},toggle_:function(){if(!this.isOpen)
+this.show();else
+this.close();},show:function(){if(this.isOpen)
+return;this.$.outer.classList.add('open');var ddr=this.$.outer.getBoundingClientRect();var rW=Math.max(ddr.width,150);this.$.dialog.style.minWidth=rW+'px';this.$.dialog.showModal();var ddw=this.$.outer.getBoundingClientRect().width;var w=this.$.dialog.getBoundingClientRect().width;this.$.dialog.style.top=ddr.bottom-1+'px';this.$.dialog.style.left=ddr.left+'px';},onDialogClick_:function(e){if(!this.isOpen)
+return;if(e.srcElement!==this.$.dialog)
+return;e.preventDefault();this.close();},onDialogCancel_:function(e){e.preventDefault();this.close();},close:function(){if(!this.isOpen)
+return;this.$.dialog.close();this.$.outer.classList.remove('open');this.$.outer.focus();},get isOpen(){return this.$.dialog.hasAttribute('open');}});'use strict';tr.exportTo('tr.ui.b',function(){var FaviconsByHue={blue:'data:image/vndmicrosofticon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjj8xAGArIgqOPzE8nUY3dqJJOJeiSTiXnUY3do4/MTxhKyIKjkAxAAAAAAAAAAAAAAAAAAAAAABQJBwAAAAAAZJBMzSoSzqlsU8+6bRQP/21UT//tVE//7RQP/2wTz3ppko6pY9AMjQAAAABTyMbAAAAAAB7e3sAAP//AKFSRE+wTz3dtVE//7VRP/+1UT//tVE//7VRP/+zUD7/sE89/7BOPf+qTDvdl0M0TwAAAABWJx4A+fn5ANjd3TnIiX7ftVA9/7VRP/+1UT//tVE//7VRP/+xTz3/rE08/6xMO/+sTDv/rE08/6dKOt+SQTM5q0w7ALO0tA3v8fGu05uR/7NMOf+0Tzz/tE88/7RPPv+uTT3/p0o7/6ZJOv+mSTr/pkk6/6ZJOv+mSjr/n0Y4rnIwKg3h4eFK9/j48N2zrP/FeGr/xnps/8Z6bP/AaUv/tlw1/7RbNf+1WzX/tFs1/7RbNf+0WzX/tFs1/7NbNPCqWy1K7e3tjPn5+f/49vX/9vLy//by8v/28vH/8bZv/+6RH//ukyP/7pMj/+6SI//ukiP/7pMj/+2SIv/qjyL/34kfjPHx8bL5+fn/+fn5//n5+f/5+fr/+fn5//W7cP/zlB3/85Yh//OWIf/zliH/85Yh//GVIf/rkR//6ZAf/+KLHrLz8/O2+fn5//n5+f/5+fn/+fn5//n5+f/1unD/85Qd//OWIf/zliH/85Yh//CUIP/mjh//44we/+OMHv/diR628vLymfn5+f/5+fn/+fn5//n5+f/5+fn/9bx0//OXI//zmCb/85gm/++VIv/hjB//3Yoe/92KHv/dih7/2IYdmfHx8Vz4+Pj3+fn5//n5+f/5+fn/+fn5//jo0//33bv/9929//bbtf/euDX/06oJ/9OrC//Tqwv/06oM98yfD1zr6+sY9/f3xvn5+f/5+fn/+fn5//n5+f/5+vv/+fv8//n7/f/3+PH/3Ms6/9O8AP/UvQD/1L0A/9K8AMbItAAY////APT09Fb4+Pjy+fn5//n5+f/5+fn/+fn5//n5+f/5+fr/9/bu/9zKOf/TuwD/1LwA/9S8APLQuABW3cQAAOzs7ADm5uYF9vb2ePn5+fT5+fn/+fn5//n5+f/5+fn/+fn6//f27v/cyTn/07sA/9S8APTRugB4w60ABcmyAAAAAAAA8PDwAOzs7Ab29vZd+Pj40vn5+fz5+fn/+fn5//n5+f/49/H/5Ndu/NjEIdLSugBdybIABsy1AAAAAAAAAAAAAAAAAADn5+cAqKioAPT09CH39/dy+Pj4tvj4+NX4+PjV+Pj4tvX063Lt6MMhOQAAAM+/RAAAAAAAAAAAAPAPAADAAwAAwAMAAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAACAAQAAwAMAAPAPAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCwUEDDgZExxWJx4tYiwiN2IsIjdWJx4tOBkTHAsFBAwAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAbDAkKZS0jMYs+MWydRjeipko6x6tMO9utTTzjrU0846tMO9umSjrHnUY3oos+MWxlLSMxGwwJCv///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgZFAAPBwUHcjMoPJtFNpqsTTzhs1A+/LVRP/+2UT//tVE//7VRP/+1UT//tVE//7ZRP/+1UT//s1A+/KxNPOGbRTaacTInPA8HBQc4GRMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/yp4AUCQcGZVDNICtTjzktVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+0UT//s1A+/7JQPv+rTDvkkkEzgE8jGxn/xZoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAA////AGswJSqiSTivs1A++7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tFA+/7FPPf+xTz3/sU89/7FPPf+vTj37nkc3r2guJCr///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAP/DogB/VEwsqE09v7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7NQPv+vTj3/r049/69OPf+vTj3/r049/69OPf+uTjz/oUg4v20xJiz/nnsAAgEBAAAAAAAAAAAAAAAAAAAAAAD19fUAkp2fHdK2sbW5W0r/tVA+/7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+yUD7/rU08/6xNPP+tTTz/rU08/61NPP+tTTz/rU08/61NPP+sTTz/nkY3tWAqIR2pSzsAAAAAAAAAAAAAAAAAeXl5ADY2Ngnd39+O6tbT/blbSv+1UD7/tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//slA+/6xNPP+rTDv/q0w7/6tMO/+rTDv/q0w7/6tMO/+rTDv/q0w7/6tMO/+qTDv9lkM0jiUQDQlSJR0AAAAAAAAAAAD///8AxMTES/X29u3s2NX/uVtK/7VQPv+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7FPPv+qTDv/qEs6/6hLOv+oSzr/qEs6/6hLOv+oSzr/qEs6/6hLOv+oSzr/qEs6/6lLOv+lSTnthDsuS/+TcgAAAAAAm5ubAHBwcA/o6Oix+vv8/+zY1P+5W0r/tVA+/7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+xTz3/qEs6/6ZKOv+mSjr/pko6/6ZKOv+mSjr/pko6/6ZKOv+mSjr/pko6/6ZKOv+mSjr/pko6/6ZKOv+bRTaxSiEaD2cuJAD///8AycnJRfX19fD6+/z/69fU/7hYR/+0Tjv/tE48/7ROPP+0Tjz/tE48/7ROPP+0Tz3/r04+/6VJOv+jSDn/o0g5/6NIOf+jSDn/o0g5/6NIOf+jSDn/o0g5/6NIOf+jSDr/o0g5/6NIOf+jSDn/o0g6/6BHOfCCOS9F0FxKAAAAAALk5OSN+fn5//n6+v/y5+X/05uS/9CTiP/QlIn/0JSJ/9CUif/QlIn/0JSK/8yGb//AaDb/vWc0/71nNf+9ZzT/vWc0/71nNP+9ZjT/vWY0/71mNP+9ZjT/vGY0/7xmNP+8ZjT/vGY0/7xmNP+8ZjT/u2U0/7FiLY0AAAACk5OTFu/v78X5+fn/+fn5//n5+f/5+vr/+fn5//n5+f/5+fn/+fn5//n5+f/5+/3/99iy//KWI//ylSH/8ZUh//GVIf/xlSH/8ZUh//GVIf/xlSH/8ZUh//GVIf/xlSH/8ZUh//GVIf/xlSH/8ZUh//CUIf/vkyD/5Y0fxY1XExbDw8Mz9PT05fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n7/f/32LL/85cj//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/wlCD/7pIg/+6SIP/pjx/lunIZM9XV1VD39/f0+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fv9//fYsv/zlyP/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/75Mg/+uRH//qkB//6pAf/+iPH/TIfBtQ3d3dYfj4+Pn5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+/3/99iy//OXI//zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh/+6TIP/ojx//548f/+ePH//njx//5o4f+c1/HGHh4eFl+Pj4+vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n7/f/32LL/85cj//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/tkiD/5Y0f/+SNH//ljR//5Y0f/+WNH//kjB/6zn8cZeDg4Fr4+Pj3+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fv9//fYsv/zlyP/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/65Eg/+KMHv/iix7/4ose/+KLHv/iix7/4ose/+CLHvfLfRta3NzcQvf39+/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+/3/99iy//OXI//zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh/+qRIP/gih7/34oe/9+KHv/fih7/34oe/9+KHv/fih7/3Yge78V6GkLS0tIj9fX12fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n7/f/32LH/85Yg//OVHv/zlR7/85Ue//OVHv/zlR7/85Ue//OVIf/pjyH/3ogf/92HH//dhx//3Ycf/92HH//dhx//3Ycf/92HH//ahh7ZunMZI56engjy8vKu+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fr7//jr2f/2ypL/9smP//bJkP/2yZD/9smQ//bJkP/2yZD/5rNI/9OeFP/SnhX/0p4V/9KeFf/SnhX/0Z0V/9GdFf/RnRX/0Z0V/8yWFq6KVBcI////AO3t7Wr5+fn++fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn6//n6/P/5+vz/+fr8//n6/P/5+vz/+fr8//n6/P/h013/0rsA/9O8AP/TvAD/07wA/9O8AP/TvAD/07wA/9O8AP/SvAD+yLMAav/mAADr6+sA4eHhJPb29tv5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/+LSW//TuwD/1LwA/9S8AP/UvAD/1LwA/9S8AP/UvAD/1LwA/9K6ANu/qgAkyLEAALu7uwAAAAAA8vLygfn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/4tJb/9O7AP/UvAD/1LwA/9S8AP/UvAD/1LwA/9S8AP/UvAD/zrYAgQAAAACfjQAAAAAAAOzs7ADk5OQe9vb2zPn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/i0lv/07sA/9S8AP/UvAD/1LwA/9S8AP/UvAD/1LwA/9K6AMzCrAAeybIAAAAAAAAAAAAAsLCwAP///wDv7+9O+Pj47Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/+LSW//TuwD/1LwA/9S8AP/UvAD/1LwA/9S8AP/TuwDsy7QATu7UAACXhQAAAAAAAAAAAAAAAAAA1tbWALS0tAPy8vJv+Pj49Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/4tJb/9O7AP/UvAD/1LwA/9S8AP/UvAD/07wA9M63AG6ZiQADtqIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4uLiANfX1wbz8/Nz+Pj48Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/i0lv/07sA/9S8AP/UvAD/1LwA/9O8APDPuABzuKMABsGrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4+PjANjY2ATy8vJZ+Pj42vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/+HSW//TugD/1LsA/9S8AP/TuwDazrcAWbejAATBqwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1NTUAB8fHwDw8PAr9vb2nPj4+O35+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/7uas/+bZdv/j1mvt2cYznMu0ACsUFAAAtaEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOvr6wDj4+MG8vLyOvb29pD4+PjS+fn58vn5+f35+fn/+fn5//n5+f/5+fn/+fn5/fn5+fL4+frS9/j8kPT1/Trs8v8G8PP/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADh4eEA1tbWAu/v7xv09PRJ9vb2dvb29pf39/eo9/f3qPb29pf29vZ29PT0Se/v7xvW1tYC4eHhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gB///gAH//gAAf/wAAD/4AAAf8AAAD+AAAAfAAAADwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABwAAAA8AAAAPgAAAH4AAAB/AAAA/4AAAf/gAAf/8AAP//wAP/',green:'data:image/vndmicrosofticon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbWJLAEpCMwptYks8eWxTdn1wVpd9cFaXeWxTdm1iSzxKQzMKbWJLAAAAAAAAAAAAAAAAAAAAAAA+OCsAAAAAAXBlTTSBdFmliHpe6Yp8X/2LfWD/i31g/4p8X/2HeV3pf3NYpW5jTDQAAAABPTcqAAAAAAB7e3sAlv//AIB1Xk+HeV3di31g/4t9YP+LfWD/i31g/4t9YP+Je1//h3pd/4d5Xf+DdVrddGhQTwAAAABDPC4A+fn5ANrb3DmupZPfinxf/4t9YP+LfWD/i31g/4t9YP+Iel7/hHdb/4R2W/+Edlv/hHdb/4BzWN9wZU05g3ZaALS0tA3w8PGuu7Sj/4h5W/+Je17/iXte/4t8X/+HeFz/gnNY/4FyWP+Bclj/gXJY/4FyWP+Bclj/fG1Url9NPA3h4eFK9/j48MvFuf+kmoP/ppuF/6abhf+JkHL/c4Rj/3OEY/9zhGP/coNj/3KDY/9yg2P/coNj/3CDYvBgf19K7e3tjPn5+f/39vb/9fTz//X08//09PP/itKw/0m+h/9Mv4n/TL+J/0y/if9Mv4n/TL+J/0y+iP9Lu4b/RrJ/jPHx8bL5+fn/+fn5//n5+f/5+fn/+fn5/4rXtP9Hwon/SsOL/0rDi/9Kw4v/SsOL/0nCiv9HvYb/RruF/0S1gbLz8/O2+fn5//n5+f/5+fn/+fn5//n5+f+K17P/R8KJ/0rDi/9Kw4v/SsOL/0nBif9GuYT/RbaC/0W2gv9Dsn+28vLymfn5+f/5+fn/+fn5//n5+f/5+fn/jdi1/0vDjP9OxI7/TsSO/0rAiv9FtoP/RLKA/0SygP9EsoD/Qq59mfHx8Vz4+Pj3+fn5//n5+f/5+fn/+fn5/9rw5v/H6tn/yOra/8Lp2f9e1b7/O8yz/z3MtP89zLT/Pcuy9zzApVzr6+sY9/f3xvn5+f/5+fn/+fn5//n5+f/7+vr//Pr7//z6+//z+fn/ZuPY/zbczv853c7/Od3O/zjbzcY10sYY////APT09Fb4+Pjy+fn5//n5+f/5+fn/+fn5//n5+f/6+fn/8Pj3/2Xj1/823Mz/OdzN/znczfI42MlWO+XWAOzs7ADm5uYF9vb2ePn5+fT5+fn/+fn5//n5+f/5+fn/+vn5//D49/9j4tf/NdvM/znczfQ42ct4Ncu9BTbRwgAAAAAA8PDwAOzs7Ab29vZd+Pj40vn5+fz5+fn/+fn5//n5+f/z+Pj/jung/FLf0tI42ctdNdHCBjfUxgAAAAAAAAAAAAAAAADn5+cAqKioAPT09CH39/dy+Pj4tvj4+NX4+PjV+Pj4tu329XLO7+whAFQmAGrUygAAAAAAAAAAAPAPAADAAwAAwAMAAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAACAAQAAwAMAAPAPAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCQgGDCsmHRxCOy4tS0M0N0tDNDdCOy4tKyYdHAkIBgwAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAVEg4KTUU1MWtgSmx5bVOigHNYx4N2W9uFd1zjhXdc44N2W9uAc1jHeW1TomtgSmxNRjUxFRMOCv///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACsnHgALCggHWE88PHdrUpqEd1vhiXxf/It9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/iXxf/IR3W+F3a1KaV048PAsKCAcrJx4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///AAPjcqGXJnT4CFeFzki31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+KfWD/iXxf/4l7Xv+DdlrkcGVNgDw2Khn//+sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AFJKOSp9cFavinxf+4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/inxf/4h6Xv+Iel3/iHpd/4h6Xv+GeV37eW1Ur1BINyr///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAP//3gBsZ1osgnVbv4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4l8X/+HeV3/hnlc/4Z5XP+GeVz/hnlc/4Z5XP+GeFz/fG9Vv1RLOiz/9LoAAgIBAAAAAAAAAAAAAAAAAAAAAAD19fUAl5ibHcbCurWShGn/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+Je1//hXhc/4R3W/+Fd1v/hXdb/4V3W/+Fd1v/hXdb/4V3W/+Ed1v/eW1TtUlCMh2CdVkAAAAAAAAAAAAAAAAAeXl5ADY2Ngne3t+O4t/Z/ZKFaf+LfV//i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/iXte/4R3W/+Ddlr/g3Za/4N2Wv+Ddlr/g3Za/4N2Wv+Ddlr/g3Za/4N2Wv+CdVr9c2dPjhwZEwk/OSsAAAAAAAAAAAD///8AxMTES/X19u3k4dv/koRp/4t9X/+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4h6Xv+CdVr/gXRZ/4F0Wf+BdFn/gXRZ/4F0Wf+BdFn/gXRZ/4F0Wf+BdFn/gXRZ/4F0Wf9+clftZVtGS/3jrgAAAAAAm5ubAHBwcA/o6Oix+/v7/+Pg2/+ShGn/i31f/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+Iel7/gXRZ/4BzWP+Ac1j/gHNY/4BzWP+Ac1j/gHNY/4BzWP+Ac1j/gHNY/4BzWP+Ac1j/gHNY/4BzWP93a1KxOTMnD1BHNwD///8AycnJRfX19fD7+/v/4+Da/5CCZ/+Jel3/iXtd/4l7Xf+Je13/iXtd/4l7Xf+Ke17/iHhd/4BxV/9/cFb/f3BW/39wVv9/cFb/f3BW/39wVv9/cFb/f3BW/39wVv9/cFb/f3BW/39wVv9/cFb/f3BW/31uVPBnWURFo45tAAAAAALk5OSN+fn5//r6+v/t7Oj/vLSk/7aunP+3rp3/t66d/7eunf+3rp3/uK+e/6Gmjv9vkG3/bI5r/2yOa/9sjmv/bI5r/2yOa/9sjmv/bI5r/2yOa/9sjmr/bI1q/2yNav9sjWr/bI1q/2uNav9rjWr/a41q/16GZI0AAAACk5OTFu/v78X5+fn/+fn5//n5+f/5+fr/+fn5//n5+f/5+fn/+fn5//n5+f/8+vv/wOfV/0vCi/9Kwor/SsKK/0rCiv9Kwor/SsKK/0rCiv9Kwor/SsKK/0rCiv9Kwor/SsKK/0rCiv9Kwor/SsKK/0nAif9Jv4j/RreCxStxUBbDw8Mz9PT05fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z6+/+/59X/TMSM/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9JwYn/SL6I/0i+iP9GuoXlOJVqM9XV1VD39/f0+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//Pr7/7/n1f9Mw4z/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/ScCJ/0e8hv9HvIb/R7yG/0a6hfQ9oXJQ3d3dYfj4+Pn5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/8+vv/v+fV/0zDjP9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0i/iP9GuoX/RrqE/0a6hP9GuoT/RrmD+T6ldWHh4eFl+Pj4+vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z6+/+/59X/TMOM/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Ivof/RbiD/0W3gv9FuIP/RbiD/0W4g/9Ft4L6PqZ2ZeDg4Fr4+Pj3+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//Pr7/7/n1f9Mw4z/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SL2H/0W2gv9FtYH/RbWB/0W1gf9FtYH/RbWB/0S0gPc+o3Ra3NzcQvf39+/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/8+vv/v+fV/0zDjP9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0e8hv9EtID/RLOA/0SzgP9Es4D/RLOA/0SzgP9Es4D/Q7F/7zyecULS0tIj9fX12fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z6+/+/59X/SsOL/0jCiv9Iwor/SMKK/0jCiv9Iwor/SMKK/0rCiv9HuoT/RLF+/0Owff9EsH3/RLB9/0Swff9EsH3/RLB9/0Swff9CrnzZOJZrI56engjy8vKu+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+vn6/9/x6f+l38X/o9/D/6Tfw/+k38P/pN/D/6Tfw/+k38T/a9Kz/0DBof9BwKH/QcCh/0HAof9BwKD/QcCg/0G/oP9Bv6D/Qb+g/0C4mK4tbU4I////AO3t7Wr5+fn++fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+vn6//v6+//7+vv/+/r7//v6+//7+vv//Pr7//v6+/+B597/NdvN/znczf853M3/OdzN/znczf853M3/OdzN/znczf85283+NtHDakb/+gDr6+sA4eHhJPb29tv5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/3/n3f823Mz/OdzN/znczf853M3/OdzN/znczf853M3/OdzN/zjay9s0x7kkNs/BALu7uwAAAAAA8vLygfn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/f+fd/zbbzP853M3/OdzN/znczf853M3/OdzN/znczf853M3/N9XHgQAAAAAspZoAAAAAAOzs7ADk5OQe9vb2zPn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f9/593/NtvM/znczf853M3/OdzN/znczf853M3/OdzN/zjay8w0yrweNtDCAAAAAAAAAAAAsLCwAP///wDv7+9O+Pj47Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/3/n3f8228z/OdzN/znczf853M3/OdzN/znczf8528zsN9PETkD45gAonJEAAAAAAAAAAAAAAAAA1tbWALS0tAPy8vJv+Pj49Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/f+fd/zbbzP853M3/OdzN/znczf853M3/OdvM9DjWx24qoJUDMb2wAAAAAAAAAAAAAAAAAAAAAAAAAAAA4uLiANfX1wbz8/Nz+Pj48Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f9/593/NtvM/znczf853M3/OdzN/znbzPA418hzMr6xBjTIugAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4+PjANjY2ATy8vJZ+Pj42vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/37m3f8z28z/N9zN/znczf8528zaONbIWTK/sgQ0yLsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1NTUAB8fHwDw8PAr9vb2nPj4+O35+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/vfDr/5Tq4v+L6ODtYODUnDTTxSsAGBsAMrywAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOvr6wDj4+MG8vLyOvb29pD4+PjS+fn58vn5+f35+fn/+fn5//n5+f/5+fn/+fn5/fn5+fL6+PjS+vf3kPv09Tr/6u4G/+/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADh4eEA1tbWAu/v7xv09PRJ9vb2dvb29pf39/eo9/f3qPb29pf29vZ29PT0Se/v7xvW1tYC4eHhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gB///gAH//gAAf/wAAD/4AAAf8AAAD+AAAAfAAAADwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABwAAAA8AAAAPgAAAH4AAAB/AAAA/4AAAf/gAAf/8AAP//wAP/',red:'data:image/vndmicrosofticon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQxmbAC0RagpDGZs8ShysdkwdspdMHbKXShysdkMZmzwuEWoKQxmcAAAAAAAAAAAAAAAAAAAAAAAmDlgAAAAAAUQanzRPHrilUx/B6VQgxf1VIMb/VSDG/1Qgxf1TH8DpTh22pUMZnDQAAAABJQ5XAAAAAAB7ensA//8AAFUrr09SH8DdVSDG/1Ugxv9VIMb/VSDG/1Ugxv9UH8P/Ux/B/1IfwP9QHrrdRxqlTwAAAAAoD14A+fn5ANzf1zmMatPfVB7G/1Ugxv9VIMb/VSDG/1Ugxv9TH8L/UR68/1AevP9QHrz/UR68/04dt99EGaA5UB67ALS0sw3x8u+unYDd/1AZxP9THcX/Ux3F/1Qexf9THr//Tx23/08ctv9PHbb/Tx22/08dtv9PHbb/SxuurjkSfg3h4eFK+Pj38LWf5P97UtL/fVXS/31V0/9fOcz/SSfC/0knwP9JJ8D/SSfA/0knwP9JJ8D/SSfA/0gnv/A/KLNK7e3tjPn5+f/29fj/8vD3//Px9//y8Pf/fILz/zQ/8P83QvD/N0Lw/zdC8P83QvD/N0Lw/zdB7/82QOz/Mz3gjPHx8bL5+fn/+fn5//n6+f/5+vn/+fn5/36G9v8yQPT/NkP0/zZD9P82Q/T/NkP0/zVC8v80QOz/M0Dq/zI+47Lz8/O2+fn5//n5+f/5+fn/+fn5//n5+f99hvb/MkD0/zZD9P82Q/T/NkP0/zVC8f8zP+f/Mj7k/zI+5P8xPd628vLymfn5+f/5+fn/+fn5//n5+f/5+fn/gYn2/zdE9P87R/T/O0f0/zZF8P8yQOP/MT/e/zE/3v8xP97/Lz3ZmfHx8Vz4+Pj3+fn5//n5+f/5+fn/+fn5/9fZ+P/Bxfj/wsb4/7vD+P87j/X/Dnzx/xF98f8RffH/EXzw9xZv5Vzr6+sY9/f3xvn5+f/5+fn/+fn5//n5+f/7+/n//Pz5//38+f/x+Pn/OrD+/wCY//8Amf//AJn//wCZ/cYAlPMY////APT09Fb4+Pjy+fn5//n5+f/5+fn/+fn5//n5+f/6+fn/7vX5/zmu/v8Al///AJj//wCY/vIAlfpWAJ//AOzs7ADm5uYF9vb2ePn5+fT5+fn/+fn5//n5+f/5+fn/+vn5/+71+f85rf7/AJb//wCY//QAlvx4AIzrBQCQ8gAAAAAA8PDwAOzs7Ab29vZd+Pj40vn5+fz5+fn/+fn5//n5+f/x9vn/bsP8/CGk/tIAlvxdAJDyBgCT9QAAAAAAAAAAAAAAAADn5+cAqKioAPT09CH39/dy+Pj4tvj4+NX4+PjV+Pj4tuvy93LD4fUhAAC7AESo6wAAAAAAAAAAAPAPAADAAwAAwAMAAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAACAAQAAwAMAAPAPAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBgIMDBoKPRwoD14tLhFrNy4RazcoD14tGgo9HAYCDAwAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+3/wANBR0KLxJuMUEYmGxKHKyiTh22x1Aeu9tRHr3jUR6941Aeu9tOHbbHShysokEYmGwvEm4xDQUeCv+6/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABoKPgAHAxAHNhR9PEkbqppRHr3hVCDE/FUgxv9VIMf/VSDH/1Ugxv9VIMb/VSDH/1Ugx/9VIMb/VCDE/FEevOFIG6maNRR8PAcDEAcaCj0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADVUP8AJg5YGUYao4BRH77kVSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMX/VB/E/1Qfw/9QHrvkRRmggCUOVhnQTv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEA////ADITdSpMHbKvVCDE+1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VCDE/1Mfwv9TH8H/Ux/B/1Mfwv9SH7/7ShytrzEScSr///8AAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAMto/wBVPoYsUSC3v1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1QfxP9SHsD/Uh6//1Iev/9SHr//Uh6//1Iev/9SHr//SxywvzMTdyymPf8AAQACAAAAAAAAAAAAAAAAAAAAAAD19fUAnaKQHbep1rVfLcn/VB/G/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9UH8P/UR6+/1Eevf9RHr3/UR69/1Eevf9RHr3/UR69/1Eevf9RHr3/ShuttS0RaB1PHrkAAAAAAAAAAAAAAAAAeXl5ADY2Ngnf4NyO18zu/V8tyf9UH8b/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VB/D/1EevP9QHrr/UB67/1Aeu/9QHrv/UB67/1Aeu/9QHrv/UB67/1Aeu/9QHrr9RhqkjhEGKAknDloAAAAAAAAAAAD///8AxMTES/b39O3Zzu//Xy3J/1Qfxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Mfwv9QHbr/Tx24/08duP9PHbj/Tx24/08duP9PHbj/Tx24/08duP9PHbj/Tx24/08duf9NHLTtPheRS5s5/wAAAAAAm5ubAHBwcA/o6Oix+/z6/9jO7/9fLcn/VB/G/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9TH8H/Tx24/04dtv9OHbb/Th22/04dtv9OHbb/Th22/04dtv9OHbb/Th22/04dtv9OHbb/Th22/04dtv9JG6mxIw1RDzAScQD///8AycnJRfX19fD7/Pr/2M3v/1wqyP9SHMX/UhzF/1Icxf9SHMX/UhzF/1Icxf9THcX/Ux7A/04ctf9NHLL/Thyz/04cs/9NHLP/TRyz/00cs/9OHLP/Thyz/04cs/9OHLP/Thyz/04cs/9NHLP/Thyz/0wcsPA/Fo9FYyTkAAAAAALk5OSN+fn5//r6+f/n4vT/noDd/5Z22v+Wdtr/lnba/5Z22v+Wdtr/mHfb/35g1/9KMMr/SC/H/0gvx/9IL8f/SC/H/0gvx/9IL8b/SC/G/0gvxv9HL8b/Ry/G/0cvxv9HL8b/Ry/G/0cvxv9HL8X/Ry7F/z8tuI0AAAACk5OTFu/v78X5+fn/+fn5//n5+f/6+vn/+fr5//n6+f/5+vn/+fr5//n6+f/9/fn/ub73/zhF8v82Q/L/NkPy/zZD8v82Q/L/NkPy/zZD8v82Q/L/NkPy/zZD8v82Q/L/NkPy/zZD8v82Q/L/NkPy/zVC8f81QvD/Mz/mxR8njhbDw8Mz9PT05fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z8+f+5vff/OEX0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P81QvH/NEHv/zRB7/8zQOrlKTO6M9XV1VD39/f0+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//Pz5/7m99/84RfT/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NULw/zRA7P80QOv/NEDr/zNA6fQsN8lQ3d3dYfj4+Pn5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/8/Pn/ub33/zhF9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zVB7/8zQOn/Mz/o/zM/6P8zQOj/Mz/n+S04zmHh4eFl+Pj4+vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z8+f+5vff/OEX0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P80Qe7/Mz/m/zM/5f8zP+b/Mz/m/zM/5v8yP+X6LjnPZeDg4Fr4+Pj3+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//Pz5/7m99/84RfT/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NEHs/zI+4/8yPuP/Mj7j/zI+4/8yPuP/Mj7j/zI+4fctOMxa3NzcQvf39+/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/8/Pn/ub33/zhF9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zRA6/8xPeH/MT3g/zE94P8xPeD/MT3g/zE94P8xPeD/MT3e7ys2xkLS0tIj9fX12fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z8+f+4vff/NkP0/zNB9P80QfT/NEH0/zRB9P80QfT/NEH0/zZC8/81P+n/Mjze/zI73f8yO93/Mjvd/zI73f8yO93/Mjvd/zI73f8xO9rZKTO7I56engjy8vKu+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+/r5/9ze+P+covf/mqD3/5qg9/+aoPf/mqD3/5qg9/+aoPf/UoLz/x1p5/8eaeb/Hmnm/x5p5v8eaeX/Hmnl/x5p5f8eaOX/Hmjl/yBh3a4jJokI////AO3t7Wr5+fn++fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+vr5//z8+f/8/Pn//Pz5//z8+f/8/Pn//Pz5//z8+f9dvfz/AJf+/wCZ/v8Amf7/AJn+/wCZ/v8Amf7/AJn+/wCZ/v8AmP7+AJLxagC4/wDr6+sA4eHhJPb29tv5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/1u8/f8Alv//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCW/NsAieckAI/xALu7uwAAAAAA8vLygfn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/W7z9/wCW//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJP3gQAAAAAAcr8AAAAAAOzs7ADk5OQe9vb2zPn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f9bvP3/AJb//wCY//8AmP//AJj//wCY//8AmP//AJj//wCW/MwAi+oeAJDxAAAAAAAAAAAAsLCwAP///wDv7+9O+Pj47Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/1u8/f8Alv//AJj//wCY//8AmP//AJj//wCY//8Al/7sAJL0TgCr/wAAa7QAAAAAAAAAAAAAAAAA1tbWALS0tAPy8vJv+Pj49Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/W7z9/wCW//8AmP//AJj//wCY//8AmP//AJj+9ACU+G4AbrgDAIPaAAAAAAAAAAAAAAAAAAAAAAAAAAAA4uLiANfX1wbz8/Nz+Pj48Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f9bvP3/AJb//wCY//8AmP//AJj//wCY/vAAlflzAITcBgCK5wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4+PjANjY2ATy8vJZ+Pj42vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/1u7/f8Alf//AJf//wCY//8Al/7aAJT4WQCE3AQAiucAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1NTUAB8fHwDw8PAr9vb2nPj4+O35+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/rNv7/3bG/P9rwfztM6r7nACR9SsAER0AAIPZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOvr6wDj4+MG8vLyOvb29pD4+PjS+fn58vn5+f35+fn/+fn5//n5+f/5+fn/+fn5/fn5+fL6+fjS/Pj2kP338jr/+eIG//fqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADh4eEA1tbWAu/v7xv09PRJ9vb2dvb29pf39/eo9/f3qPb29pf29vZ29PT0Se/v7xvW1tYC4eHhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gB///gAH//gAAf/wAAD/4AAAf8AAAD+AAAAfAAAADwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABwAAAA8AAAAPgAAAH4AAAB/AAAA/4AAAf/gAAf/8AAP//wAP/',yellow:'data:image/vndmicrosofticon;base64,AAABAAIAICAAAAEAIACoEAAAJgAAABAQAAABACAAaAQAAM4QAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAZKhQAOWAiAEV0KgBFdCoAOWAiABkqFAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8ZAAAChAHAEp8JwBvu10AgNeSAInluACN7c4Aj/DXAI/w1wCN7c4AieW4AIDXkgBvu10ASnwnAAoQBwA8ZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbLgAAAAAFAFmWMwB/1YwAj/DXAJX7+QCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJX7+QCP79cAftWMAFmVMwAAAAUAGy4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7v8AAD1mFQB6zXYAkPLdAJf+/gCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP7/AJf+/wCV/P4AjvDdAHjKdgA8ZBUA6f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AABWkCYAh+KoAJb8+QCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJf+/wCV+v8AlPr/AJT6/wCV+v8Akvf5AIPdqABTjCYA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICABb//wAka5wqAozquwCY/v8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCX/f8Ak/j/AJP3/wCT9/8Ak/f/AJP3/wCT9/8Akvb/AIbiuwBZlyoA//8AAAECAAAAAAAAAAAAAAAAAAAAAADz8/MAqJaJHZDD5rQLnP7/AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8Alvz/AJL2/wCR9P8AkfT/AJH0/wCR9P8AkfT/AJH0/wCR9P8AkfT/AITftABQhh0AjO0AAAAAAAAAAAAAAAAAfX19ADw8PAni3tuPuuD5/Quc//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJb8/wCQ8/8Aj/H/AI/x/wCP8f8Aj/H/AI/x/wCP8f8Aj/H/AI/x/wCP8f8AjvD9AH7UjwAiOQkASHkAAAAAAAgICAD///8AxcXFT/j19O+94vv/Cpz//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCV+/8Aj/H/AI3u/wCN7v8Aje7/AI3u/wCN7v8Aje7/AI3u/wCN7v8Aje7/AI3u/wCO7v8AiunvAHC8TwD//wAABQgAqKioAHp6ehHp6em3/fv5/7zh+v8KnP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8Alfr/AI7u/wCM6/8AjOv/AIzr/wCM6/8AjOv/AIzr/wCM6/8AjOv/AIzr/wCM6/8AjOv/AIzr/wCM6/8Ag9y3AERyEQBenQD///8AzMzMTfb29vP9+/n/vOH6/wqb//8Alv//AJb//wCW//8Alv//AJb//wCW//8Al///AJT5/wCL6/8Aiej/AIno/wCJ6P8Aiej/AIno/wCJ6P8Aiej/AIno/wCJ6P8Aiej/AIno/wCJ6P8Aiej/AIno/wCH5fMAb75NAMP/AAAAAAXl5eWX+fn5//v6+f/T6vr/Wbv9/0+3/f9Qt/3/ULf9/1C3/f9Qt/3/Ubj9/zew+/8InO//B5nr/weZ6/8Hmev/B5nq/weZ6v8Hmer/B5nq/weZ6v8Hmer/B5jq/weY6v8HmOn/B5jp/weY6f8HmOn/Bpjp/weP15cBAAAFpKSkHfDw8M/5+fn/+fn5//n5+f/1+Pn/9Pf5//T3+f/09/n/9Pf5//T3+f/4+Pn/o+T6/wq//f8Hv/3/CL/9/wi//f8Iv/3/CL/9/wi//f8Iv/3/CL/8/wi+/P8Ivvz/CL78/wi+/P8Ivvz/CL78/we9+/8HvPr/BrbxzwR9pR3Ly8tA9fX17Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//36+f+l5vv/CcL//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hv/3/Br36/wa9+v8GuvbsBZnLQNra2mD39/f4+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//fr5/6Xm+/8Jwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B778/wa79/8Guvf/Brr3/wa59fgFo9hg4uLidPj4+P35+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/9+vn/peb7/wnB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//we++/8GufX/Brj0/wa49P8GuPT/Brfz/QWm3XTk5OR6+Pj4/fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//36+f+l5vv/CcH//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hvfr/Brfy/wa28f8GtvH/Brbx/wa28f8GtfD9BafdeuXl5W/4+Pj8+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//fr5/6Xm+/8Jwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B7z5/wa17/8GtO7/BrTu/wa07v8GtO7/BrTu/waz7fwFpdtv4eHhVvj4+Pb5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/9+vn/peb7/wnB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//we7+P8Gsu3/BrHr/wax6/8Gsev/BrHr/wax6/8Gsev/BrDq9gWh1Vba2toz9vb25vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//36+f+k5fv/BsH//wPA//8DwP//A8D//wPA//8DwP//A8D//wXA//8Guvb/BrDq/wau6P8Gruj/Bq7o/wau6P8Gruj/Bq7o/wau6P8GreXmBZnLM7+/vxH09PTC+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+/r5/83v+v9x2vz/btn9/2/Z/f9v2f3/b9n9/2/Z/f9v2f3/RdL5/yXG7v8mxOz/JsTs/ybE6/8mxOv/JsTr/yXE6/8lw+v/JcPr/yK95cIQirAR////APDw8IH5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+vn5//r5+f/6+fn/+vn5//r5+f/6+fn/+vn5//r5+f+H8Pz/Oer+/zzq/v886v7/POr+/zzq/v886v7/POr+/zzq/v886v3/OuDzgWz//wD09PQA5+fnNPf39+n5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/4Xw/f846///O+v//zvr//876///O+v//zvr//876///O+v//zvp/ek32+00Ouf6AMrKygCzs7MF8/Pzmvn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/hfD9/zjr//876///O+v//zvr//876///O+v//zvr//876///OuX5miqptwUwv88AAAAAAPPz8wDp6eku9/f33fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f+F8P3/OOv//zvr//876///O+v//zvr//876///O+v//zvp/d033O8uOuX5AAAAAAAAAAAAvr6+AP///wDx8fFl+Pj49fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/4Xw/f846///O+v//zvr//876///O+v//zvr//876v71OeP2ZY7//wAus8IAAAAAAAAAAAAAAAAA4ODgANPT0wj09PSI+fn5+vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/hfD9/zjr//876///O+v//zvr//876///O+v/+jrm+Ygyx9gINdPlAAAAAAAAAAAAAAAAAAAAAAAAAAAA6enpAOHh4Q309PSM+fn5+Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f+F8P3/OOv//zvr//876///O+v//zvr//g65/qMNtXnDTjd7wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6enpAOLi4gr09PRw+Pj45/n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/4Pw/f816///Oev//zvr//876v7nOub5cDbW5wo33O4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ODgANHR0QLx8fE89/f3sfn5+fX5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/t/T7/4Xx/f+A8P31Xez8sTnk9zwuxdUCNtTkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAREREAP///wDo6OgM9PT0Tff396T4+Pjf+fn5+Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+fj5+Pjf9vf3pPL09E3m6OgM7/3/APtbOwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACMjIwD19fUA4uLiBvHx8Sn19fVd9vb2jff396739/e99/f3vff396729vaN9fX1XfHx8Snl4uIG9PX1AFEnIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/wD///gAH//gAAf/wAAD/4AAAf8AAAD+AAAAfAAAADwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABgAAAAcAAAAPgAAAH4AAAB/AAAA/4AAAf/AAAP/8AAP//wAP/KAAAABAAAAAgAAAAAQAgAAAAAAAABAAAEgsAABILAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABorgAAS34IAHTDNQCC22wAh+OMAIfjjACC22wAdMQ1AEx/CABorwAAAAAAAAAAAAAAAAAAAAAAAEBrAAAAAAAAecswAIzsngCU+OUAl/37AJj+/wCY/v8Al/37AJP35QCL6Z4Ad8gwAAAAAAA+aQAAAAAAcXd6AP8AAAAOiNtNAJP32gCY//8AmP//AJj//wCY//8AmP//AJb8/wCU+f8Ak/j/AI7w2gB+1E0AAAAAAEd4APn7/ADc2NU5T7P33gCX//8AmP//AJj//wCY//8AmP//AJX6/wCR8/8AkPL/AJDz/wCQ8/8AjOzeAHrOOQCR9AC3t7cO8e/vsGnA/f8Alf//AJf//wCX//8Al///AJP4/wCN7v8AjOz/AIzs/wCM7P8AjOz/AIzt/wCG4rAAY6oO4uLiT/j39/GIzfz/Mav+/zSs/v80rP7/FaH5/wOV7f8DlOv/A5Tr/wOU6/8DlOv/A5Tr/wOU6/8Dk+jxBIvVT+3t7ZT5+fn/8fb5/+vz+f/r9Pn/6vP5/1nR+/8EvPz/B738/we9/P8Hvfz/B738/we9/P8HvPv/B7r4/wax7ZTy8vK7+fn5//n5+f/6+fn/+vn5//n5+f9e1f3/A8D//wfB//8Hwf//B8H//wfB//8HwP3/Brv3/wa59f8GtO678/Pzwfn5+f/5+fn/+fn5//n5+f/4+fn/XtX9/wPA//8Hwf//B8H//wfB//8Hv/z/Brfz/wa17/8Gte//BrHqwfPz86X5+fn/+fn5//n5+f/5+fn/+Pn5/2DW/f8Gwf//CsL//wrC//8Jv/v/CLXu/wix6f8Isen/CLHp/wet5KXy8vJo+fn5+vn5+f/5+fn/+fn5//n5+f/I7vr/quf7/6zn+/+m5/v/Tdz5/yzV9P8u1fT/LtX0/y7U8/ooyOpo7OzsH/f399D5+fn/+fn5//n5+f/5+fn//Pr5//36+f/++vn/9fn5/2rv/v857P//POz//zzs//886/3QOuLzH////wD09PRh+fn59vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//H4+f9o7v7/OOv//zvr//876//2Ouf6YUH//wDu7u4A6enpB/b29oT5+fn3+fn5//n5+f/5+fn/+fn5//n5+f/x+Pn/Zu7+/zfr//876//3Ouj8hDfc7wc44PMAAAAAAPHx8QDu7u4I9vb2aPj4+Nn5+fn9+fn5//n5+f/5+fn/8/n5/4zx/P1S7P7ZO+n8aDfh9Ag55PcAAAAAAAAAAAAAAAAA6+vrAN/f3wH19fUo9/f3fvj4+MH4+Pje+Pj43vj4+MHq9vh+w/H2KADM5wFk4e8AAAAAAAAAAADwDwAA4AcAAMADAACAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAAgAEAAMADAADgBwAA'};return{FaviconsByHue:FaviconsByHue};});'use strict';tr.exportTo('tr.ui.b',function(){function HotKey(dict){if(dict.eventType===undefined)
+throw new Error('eventType must be given');if(dict.keyCode===undefined&&dict.keyCodes===undefined)
+throw new Error('keyCode or keyCodes must be given');if(dict.keyCode!==undefined&&dict.keyCodes!==undefined)
+throw new Error('Only keyCode or keyCodes can be given');if(dict.callback===undefined)
+throw new Error('callback must be given');this.eventType_=dict.eventType;this.keyCodes_=[];if(dict.keyCode)
+this.pushKeyCode_(dict.keyCode);else if(dict.keyCodes){dict.keyCodes.forEach(this.pushKeyCode_,this);}
+this.useCapture_=!!dict.useCapture;this.callback_=dict.callback;this.thisArg_=dict.thisArg!==undefined?dict.thisArg:undefined;this.helpText_=dict.helpText!==undefined?dict.helpText:undefined;}
+HotKey.prototype={get eventType(){return this.eventType_;},get keyCodes(){return this.keyCodes_;},get helpText(){return this.helpText_;},call:function(e){this.callback_.call(this.thisArg_,e);},pushKeyCode_:function(keyCode){this.keyCodes_.push(keyCode);}};return{HotKey:HotKey};});'use strict';Polymer('tv-ui-b-hotkey-controller',{created:function(){this.globalMode_=false;this.slavedToParentController_=undefined;this.curHost_=undefined;this.childControllers_=[];this.bubblingKeyDownHotKeys_={};this.capturingKeyDownHotKeys_={};this.bubblingKeyPressHotKeys_={};this.capturingKeyPressHotKeys_={};this.onBubblingKeyDown_=this.onKey_.bind(this,false);this.onCapturingKeyDown_=this.onKey_.bind(this,true);this.onBubblingKeyPress_=this.onKey_.bind(this,false);this.onCapturingKeyPress_=this.onKey_.bind(this,true);},attached:function(){var host=this.findHost_();if(host.__hotkeyController)
+throw new Error('Multiple hotkey controllers attached to this host');host.__hotkeyController=this;this.curHost_=host;var parentElement;if(host.parentElement)
+parentElement=host.parentElement;else
+parentElement=host.parentNode.host;var parentController=tr.b.getHotkeyControllerForElement(parentElement);if(parentController){this.slavedToParentController_=parentController;parentController.addChildController_(this);return;}
+host.addEventListener('keydown',this.onBubblingKeyDown_,false);host.addEventListener('keydown',this.onCapturingKeyDown_,true);host.addEventListener('keypress',this.onBubblingKeyPress_,false);host.addEventListener('keypress',this.onCapturingKeyPress_,true);},detached:function(){var host=this.curHost_;if(!host)
+return;delete host.__hotkeyController;this.curHost_=undefined;if(this.slavedToParentController_){this.slavedToParentController_.removeChildController_(this);this.slavedToParentController_=undefined;return;}
+host.removeEventListener('keydown',this.onBubblingKeyDown_,false);host.removeEventListener('keydown',this.onCapturingKeyDown_,true);host.removeEventListener('keypress',this.onBubblingKeyPress_,false);host.removeEventListener('keypress',this.onCapturingKeyPress_,true);},addChildController_:function(controller){var i=this.childControllers_.indexOf(controller);if(i!==-1)
+throw new Error('Controller already registered');this.childControllers_.push(controller);},removeChildController_:function(controller){var i=this.childControllers_.indexOf(controller);if(i===-1)
+throw new Error('Controller not registered');this.childControllers_.splice(i,1);return controller;},getKeyMapForEventType_:function(eventType,useCapture){if(eventType==='keydown'){if(!useCapture)
+return this.bubblingKeyDownHotKeys_;else
+return this.capturingKeyDownHotKeys_;}else if(eventType==='keypress'){if(!useCapture)
+return this.bubblingKeyPressHotKeys_;else
+return this.capturingKeyPressHotKeys_;}else{throw new Error('Unsupported key event');}},addHotKey:function(hotKey){if(!(hotKey instanceof tr.ui.b.HotKey))
+throw new Error('hotKey must be a tr.ui.b.HotKey');var keyMap=this.getKeyMapForEventType_(hotKey.eventType,hotKey.useCapture);for(var i=0;i<hotKey.keyCodes.length;i++){var keyCode=hotKey.keyCodes[i];if(keyMap[keyCode])
+throw new Error('Key is already bound for keyCode='+keyCode);}
+for(var i=0;i<hotKey.keyCodes.length;i++){var keyCode=hotKey.keyCodes[i];keyMap[keyCode]=hotKey;}
+return hotKey;},removeHotKey:function(hotKey){if(!(hotKey instanceof tr.ui.b.HotKey))
+throw new Error('hotKey must be a tr.ui.b.HotKey');var keyMap=this.getKeyMapForEventType_(hotKey.eventType,hotKey.useCapture);for(var i=0;i<hotKey.keyCodes.length;i++){var keyCode=hotKey.keyCodes[i];if(!keyMap[keyCode])
+throw new Error('Key is not bound for keyCode='+keyCode);keyMap[keyCode]=hotKey;}
+for(var i=0;i<hotKey.keyCodes.length;i++){var keyCode=hotKey.keyCodes[i];delete keyMap[keyCode];}
+return hotKey;},get globalMode(){return this.globalMode_;},set globalMode(globalMode){this.detached();this.globalMode_=!!globalMode;this.attached();},get topmostConroller_(){if(this.slavedToParentController_)
+return this.slavedToParentController_.topmostConroller_;return this;},childRequestsGeneralFocus:function(child){var topmost=this.topmostConroller_;if(topmost.curHost_){if(topmost.curHost_.hasAttribute('tabIndex')){topmost.curHost_.focus();}else{if(document.activeElement)
+document.activeElement.blur();}}else{if(document.activeElement)
+document.activeElement.blur();}},childRequestsBlur:function(child){child.blur();var topmost=this.topmostConroller_;if(topmost.curHost_){topmost.curHost_.focus();}},findHost_:function(){if(this.globalMode_){return document.body;}else{if(this.parentElement)
+return this.parentElement;var node=this;while(node.parentNode){node=node.parentNode;}
+return node.host;}},appendMatchingHotKeysTo_:function(matchedHotKeys,useCapture,e){var localKeyMap=this.getKeyMapForEventType_(e.type,useCapture);var localHotKey=localKeyMap[e.keyCode];if(localHotKey)
+matchedHotKeys.push(localHotKey);for(var i=0;i<this.childControllers_.length;i++){var controller=this.childControllers_[i];controller.appendMatchingHotKeysTo_(matchedHotKeys,useCapture,e);}},onKey_:function(useCapture,e){if(useCapture==false&&e.path[0].tagName=='INPUT')
+return;var sortedControllers;var matchedHotKeys=[];this.appendMatchingHotKeysTo_(matchedHotKeys,useCapture,e);if(matchedHotKeys.length===0)
+return false;if(matchedHotKeys.length>1){throw new Error('More than one hotKey is currently unsupported');}
+var hotKey=matchedHotKeys[0];var prevented=0;prevented|=hotKey.call(e);return!prevented&&e.defaultPrevented;}});'use strict';tr.exportTo('tr.b',function(){function getHotkeyControllerForElement(refElement){var curElement=refElement;while(curElement){if(curElement.tagName==='tv-ui-b-hotkey-controller')
+return curElement;if(curElement.__hotkeyController)
+return curElement.__hotkeyController;if(curElement.parentElement){curElement=curElement.parentElement;continue;}
+curElement=findHost(curElement);}
+return undefined;}
+function findHost(initialNode){var node=initialNode;while(node.parentNode){node=node.parentNode;}
+return node.host;}
+return{getHotkeyControllerForElement:getHotkeyControllerForElement};});'use strict';Polymer('tr-ui-b-info-bar',{ready:function(){this.messageEl_=this.$.message;this.buttonsEl_=this.$.buttons;this.message='';this.visible=false;},get message(){return this.messageEl_.textContent;},set message(message){this.messageEl_.textContent=message;},get visible(){return!this.classList.contains('info-bar-hidden');},set visible(visible){if(visible)
+this.classList.remove('info-bar-hidden');else
+this.classList.add('info-bar-hidden');},removeAllButtons:function(){this.buttonsEl_.textContent='';},addButton:function(text,clickCallback){var button=document.createElement('button');button.textContent=text;button.addEventListener('click',clickCallback);this.buttonsEl_.appendChild(button);return button;}});'use strict';Polymer('tr-ui-b-info-bar-group',{ready:function(){this.messages_=[];},clearMessages:function(){this.messages_=[];this.updateContents_();},addMessage:function(text,opt_buttons){opt_buttons=opt_buttons||[];for(var i=0;i<opt_buttons.length;i++){if(opt_buttons[i].buttonText===undefined)
+throw new Error('buttonText must be provided');if(opt_buttons[i].onClick===undefined)
+throw new Error('onClick must be provided');}
+this.messages_.push({text:text,buttons:opt_buttons||[]});this.updateContents_();},updateContents_:function(){this.$.messages.textContent='';this.messages_.forEach(function(message){var bar=document.createElement('tr-ui-b-info-bar');bar.message=message.text;bar.visible=true;message.buttons.forEach(function(button){bar.addButton(button.buttonText,button.onClick);},this);this.$.messages.appendChild(bar);},this);}});'use strict';tr.exportTo('tr.ui',function(){var Task=tr.b.Task;function FindController(brushingStateController){this.brushingStateController_=brushingStateController;this.filterHits_=new tr.model.EventSet();this.currentHitIndex_=-1;this.activePromise_=Promise.resolve();this.activeTask_=undefined;};FindController.prototype={__proto__:Object.prototype,get model(){return this.brushingStateController_.model;},get brushingStateController(){return this.brushingStateController_;},enqueueOperation_:function(operation){var task;if(operation instanceof tr.b.Task)
+task=operation;else
+task=new tr.b.Task(operation,this);if(this.activeTask_){this.activeTask_=this.activeTask_.enqueue(task);}else{this.activeTask_=task;this.activePromise_=Task.RunWhenIdle(this.activeTask_);this.activePromise_.then(function(){this.activePromise_=undefined;this.activeTask_=undefined;}.bind(this));}},startFiltering:function(filterText){var sc=this.brushingStateController_;if(!sc)
+return;this.enqueueOperation_(function(){this.filterHits_=new tr.model.EventSet();this.currentHitIndex_=-1;}.bind(this));var stateFromString;try{stateFromString=sc.uiStateFromString(filterText);}catch(e){this.enqueueOperation_(function(){var overlay=new tr.ui.b.Overlay();overlay.textContent=e.message;overlay.title='UI State Navigation Error';overlay.visible=true;});return this.activePromise_;}
+if(stateFromString!==undefined){this.enqueueOperation_(sc.navToPosition.bind(this,stateFromString,true));}else{if(filterText.length===0){this.enqueueOperation_(sc.findTextCleared.bind(sc));}else{var filter=new tr.c.FullTextFilter(filterText);var filterHits=new tr.model.EventSet();this.enqueueOperation_(sc.addAllEventsMatchingFilterToSelectionAsTask(filter,filterHits));this.enqueueOperation_(function(){this.filterHits_=filterHits;sc.findTextChangedTo(filterHits);}.bind(this));}}
+return this.activePromise_;},get filterHits(){return this.filterHits_;},get currentHitIndex(){return this.currentHitIndex_;},find_:function(dir){var firstHit=this.currentHitIndex_===-1;if(firstHit&&dir<0)
+this.currentHitIndex_=0;var N=this.filterHits.length;this.currentHitIndex_=(this.currentHitIndex_+dir+N)%N;if(!this.brushingStateController_)
+return;this.brushingStateController_.findFocusChangedTo(this.filterHits.subEventSet(this.currentHitIndex_,1));},findNext:function(){this.find_(1);},findPrevious:function(){this.find_(-1);}};return{FindController:FindController};});'use strict';tr.exportTo('tr.ui.b',function(){var MOUSE_SELECTOR_MODE={};MOUSE_SELECTOR_MODE.SELECTION=0x1;MOUSE_SELECTOR_MODE.PANSCAN=0x2;MOUSE_SELECTOR_MODE.ZOOM=0x4;MOUSE_SELECTOR_MODE.TIMING=0x8;MOUSE_SELECTOR_MODE.ROTATE=0x10;MOUSE_SELECTOR_MODE.ALL_MODES=0x1F;var MOUSE_SELECTOR_MODE_INFOS={};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.PANSCAN]={mode:MOUSE_SELECTOR_MODE.PANSCAN,title:'pan',eventNames:{enter:'enterpan',begin:'beginpan',update:'updatepan',end:'endpan',exit:'exitpan'},activeBackgroundPosition:'-30px -10px',defaultBackgroundPosition:'0 -10px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.SELECTION]={mode:MOUSE_SELECTOR_MODE.SELECTION,title:'selection',eventNames:{enter:'enterselection',begin:'beginselection',update:'updateselection',end:'endselection',exit:'exitselection'},activeBackgroundPosition:'-30px -40px',defaultBackgroundPosition:'0 -40px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.ZOOM]={mode:MOUSE_SELECTOR_MODE.ZOOM,title:'zoom',eventNames:{enter:'enterzoom',begin:'beginzoom',update:'updatezoom',end:'endzoom',exit:'exitzoom'},activeBackgroundPosition:'-30px -70px',defaultBackgroundPosition:'0 -70px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.TIMING]={mode:MOUSE_SELECTOR_MODE.TIMING,title:'timing',eventNames:{enter:'entertiming',begin:'begintiming',update:'updatetiming',end:'endtiming',exit:'exittiming'},activeBackgroundPosition:'-30px -100px',defaultBackgroundPosition:'0 -100px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.ROTATE]={mode:MOUSE_SELECTOR_MODE.ROTATE,title:'rotate',eventNames:{enter:'enterrotate',begin:'beginrotate',update:'updaterotate',end:'endrotate',exit:'exitrotate'},activeBackgroundPosition:'-30px -130px',defaultBackgroundPosition:'0 -130px'};return{MOUSE_SELECTOR_MODE_INFOS:MOUSE_SELECTOR_MODE_INFOS,MOUSE_SELECTOR_MODE:MOUSE_SELECTOR_MODE};});'use strict';Polymer('tr-ui-b-mouse-mode-icon',{publish:{modeName:{value:undefined,reflect:true}},created:function(){this.active_=false;this.acceleratorKey_=undefined;},ready:function(){this.updateContents_();},get mode(){return tr.ui.b.MOUSE_SELECTOR_MODE[this.modeName];},set mode(mode){var modeInfo=tr.ui.b.MOUSE_SELECTOR_MODE_INFOS[mode];var modeName=tr.b.findFirstKeyInDictMatching(tr.ui.b.MOUSE_SELECTOR_MODE,function(modeName,candidateMode){return candidateMode===mode;});if(modeName===undefined)
+throw new Error('Unknown mode');this.modeName=modeName;},modeNameChanged:function(){this.updateContents_();},get active(){return this.active_;},set active(active){this.active_=!!active;if(this.active_)
+this.classList.add('active');else
+this.classList.remove('active');this.updateContents_();},get acceleratorKey(){return this.acceleratorKey_;},set acceleratorKey(acceleratorKey){this.acceleratorKey_=acceleratorKey;this.updateContents_();},updateContents_:function(){if(this.modeName===undefined)
+return;var mode=this.mode;if(mode===undefined)
+throw new Error('Invalid mode');var modeInfo=tr.ui.b.MOUSE_SELECTOR_MODE_INFOS[mode];if(!modeInfo)
+throw new Error('Invalid mode');var title=modeInfo.title;if(this.acceleratorKey_)
+title=title+' ('+this.acceleratorKey_+')';this.title=title;var bp;if(this.active_)
+bp=modeInfo.activeBackgroundPosition;else
+bp=modeInfo.defaultBackgroundPosition;this.style.backgroundPosition=bp;}});'use strict';tr.exportTo('tr.ui.b',function(){var MOUSE_SELECTOR_MODE=tr.ui.b.MOUSE_SELECTOR_MODE;var MOUSE_SELECTOR_MODE_INFOS=tr.ui.b.MOUSE_SELECTOR_MODE_INFOS;var MIN_MOUSE_SELECTION_DISTANCE=4;var MODIFIER={SHIFT:0x1,SPACE:0x2,CMD_OR_CTRL:0x4};function isCmdOrCtrlPressed(event){if(tr.isMac)
+return event.metaKey;else
+return event.ctrlKey;}
+Polymer('tr-ui-b-mouse-mode-selector',{__proto__:HTMLDivElement.prototype,created:function(){this.supportedModeMask_=MOUSE_SELECTOR_MODE.ALL_MODES;this.initialRelativeMouseDownPos_={x:0,y:0};this.defaultMode_=MOUSE_SELECTOR_MODE.PANSCAN;this.settingsKey_=undefined;this.mousePos_={x:0,y:0};this.mouseDownPos_={x:0,y:0};this.onMouseDown_=this.onMouseDown_.bind(this);this.onMouseMove_=this.onMouseMove_.bind(this);this.onMouseUp_=this.onMouseUp_.bind(this);this.onKeyDown_=this.onKeyDown_.bind(this);this.onKeyUp_=this.onKeyUp_.bind(this);this.mode_=undefined;this.modeToKeyCodeMap_={};this.modifierToModeMap_={};this.targetElement_=undefined;this.modeBeforeAlternativeModeActivated_=null;this.isInteracting_=false;this.isClick_=false;},ready:function(){this.buttonsEl_=this.shadowRoot.querySelector('.buttons');this.dragHandleEl_=this.shadowRoot.querySelector('.drag-handle');this.supportedModeMask=MOUSE_SELECTOR_MODE.ALL_MODES;this.dragHandleEl_.addEventListener('mousedown',this.onDragHandleMouseDown_.bind(this));this.buttonsEl_.addEventListener('mouseup',this.onButtonMouseUp_);this.buttonsEl_.addEventListener('mousedown',this.onButtonMouseDown_);this.buttonsEl_.addEventListener('click',this.onButtonPress_.bind(this));},attached:function(){document.addEventListener('keydown',this.onKeyDown_);document.addEventListener('keyup',this.onKeyUp_);},detached:function(){document.removeEventListener('keydown',this.onKeyDown_);document.removeEventListener('keyup',this.onKeyUp_);},get targetElement(){return this.targetElement_;},set targetElement(target){if(this.targetElement_)
+this.targetElement_.removeEventListener('mousedown',this.onMouseDown_);this.targetElement_=target;if(this.targetElement_)
+this.targetElement_.addEventListener('mousedown',this.onMouseDown_);},get defaultMode(){return this.defaultMode_;},set defaultMode(defaultMode){this.defaultMode_=defaultMode;},get settingsKey(){return this.settingsKey_;},set settingsKey(settingsKey){this.settingsKey_=settingsKey;if(!this.settingsKey_)
+return;var mode=tr.b.Settings.get(this.settingsKey_+'.mode',undefined);if(MOUSE_SELECTOR_MODE_INFOS[mode]===undefined)
+mode=undefined;if((mode&this.supportedModeMask_)===0)
+mode=undefined;if(!mode)
+mode=this.defaultMode_;this.mode=mode;var pos=tr.b.Settings.get(this.settingsKey_+'.pos',undefined);if(pos)
+this.pos=pos;},get supportedModeMask(){return this.supportedModeMask_;},set supportedModeMask(supportedModeMask){if(this.mode&&(supportedModeMask&this.mode)===0)
+throw new Error('supportedModeMask must include current mode.');function createButtonForMode(mode){return button;}
+this.supportedModeMask_=supportedModeMask;this.buttonsEl_.textContent='';for(var modeName in MOUSE_SELECTOR_MODE){if(modeName=='ALL_MODES')
+continue;var mode=MOUSE_SELECTOR_MODE[modeName];if((this.supportedModeMask_&mode)===0)
+continue;var button=document.createElement('tr-ui-b-mouse-mode-icon');button.mode=mode;button.classList.add('tool-button');this.buttonsEl_.appendChild(button);}},getButtonForMode_:function(mode){for(var i=0;i<this.buttonsEl_.children.length;i++){var buttonEl=this.buttonsEl_.children[i];if(buttonEl.mode===mode)
+return buttonEl;}
+return undefined;},get mode(){return this.currentMode_;},set mode(newMode){if(newMode!==undefined){if(typeof newMode!=='number')
+throw new Error('Mode must be a number');if((newMode&this.supportedModeMask_)===0)
+throw new Error('Cannot switch to this mode, it is not supported');if(MOUSE_SELECTOR_MODE_INFOS[newMode]===undefined)
+throw new Error('Unrecognized mode');}
+var modeInfo;if(this.currentMode_===newMode)
+return;if(this.currentMode_){var buttonEl=this.getButtonForMode_(this.currentMode_);if(buttonEl)
+buttonEl.active=false;if(this.isInteracting_){var mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.end);this.dispatchEvent(mouseEvent);}
+modeInfo=MOUSE_SELECTOR_MODE_INFOS[this.currentMode_];tr.b.dispatchSimpleEvent(this,modeInfo.eventNames.exit,true);}
+this.currentMode_=newMode;if(this.currentMode_){var buttonEl=this.getButtonForMode_(this.currentMode_);if(buttonEl)
+buttonEl.active=true;this.mouseDownPos_.x=this.mousePos_.x;this.mouseDownPos_.y=this.mousePos_.y;modeInfo=MOUSE_SELECTOR_MODE_INFOS[this.currentMode_];if(!this.isInAlternativeMode_)
+tr.b.dispatchSimpleEvent(this,modeInfo.eventNames.enter,true);if(this.isInteracting_){var mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.begin);this.dispatchEvent(mouseEvent);}}
+if(this.settingsKey_&&!this.isInAlternativeMode_)
+tr.b.Settings.set(this.settingsKey_+'.mode',this.mode);},setKeyCodeForMode:function(mode,keyCode){if((mode&this.supportedModeMask_)===0)
+throw new Error('Mode not supported');this.modeToKeyCodeMap_[mode]=keyCode;if(!this.buttonsEl_)
+return;var buttonEl=this.getButtonForMode_(mode);if(buttonEl)
+buttonEl.acceleratorKey=String.fromCharCode(keyCode);},setCurrentMousePosFromEvent_:function(e){this.mousePos_.x=e.clientX;this.mousePos_.y=e.clientY;},createEvent_:function(eventName,sourceEvent){var event=new tr.b.Event(eventName,true);event.clientX=this.mousePos_.x;event.clientY=this.mousePos_.y;event.deltaX=this.mousePos_.x-this.mouseDownPos_.x;event.deltaY=this.mousePos_.y-this.mouseDownPos_.y;event.mouseDownX=this.mouseDownPos_.x;event.mouseDownY=this.mouseDownPos_.y;event.didPreventDefault=false;event.preventDefault=function(){event.didPreventDefault=true;if(sourceEvent)
+sourceEvent.preventDefault();};event.stopPropagation=function(){sourceEvent.stopPropagation();};event.stopImmediatePropagation=function(){throw new Error('Not implemented');};return event;},onMouseDown_:function(e){if(e.button!==0)
+return;this.setCurrentMousePosFromEvent_(e);var mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.begin,e);if(this.mode===MOUSE_SELECTOR_MODE.SELECTION)
+mouseEvent.appendSelection=isCmdOrCtrlPressed(e);this.dispatchEvent(mouseEvent);this.isInteracting_=true;this.isClick_=true;tr.ui.b.trackMouseMovesUntilMouseUp(this.onMouseMove_,this.onMouseUp_);},onMouseMove_:function(e){this.setCurrentMousePosFromEvent_(e);var mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.update,e);this.dispatchEvent(mouseEvent);if(this.isInteracting_)
+this.checkIsClick_(e);},onMouseUp_:function(e){if(e.button!==0)
+return;var mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.end,e);mouseEvent.isClick=this.isClick_;this.dispatchEvent(mouseEvent);if(this.isClick_&&!mouseEvent.didPreventDefault)
+this.dispatchClickEvents_(e);this.isInteracting_=false;this.updateAlternativeModeState_(e);},onButtonMouseDown_:function(e){e.preventDefault();e.stopImmediatePropagation();},onButtonMouseUp_:function(e){e.preventDefault();e.stopImmediatePropagation();},onButtonPress_:function(e){this.modeBeforeAlternativeModeActivated_=undefined;this.mode=e.target.mode;e.preventDefault();},onKeyDown_:function(e){if(e.path[0].tagName=='INPUT')
+return;if(e.keyCode===' '.charCodeAt(0))
+this.spacePressed_=true;this.updateAlternativeModeState_(e);},onKeyUp_:function(e){if(e.path[0].tagName=='INPUT')
+return;if(e.keyCode===' '.charCodeAt(0))
+this.spacePressed_=false;var didHandleKey=false;tr.b.iterItems(this.modeToKeyCodeMap_,function(modeStr,keyCode){if(e.keyCode===keyCode){this.modeBeforeAlternativeModeActivated_=undefined;var mode=parseInt(modeStr);this.mode=mode;didHandleKey=true;}},this);if(didHandleKey){e.preventDefault();e.stopPropagation();return;}
+this.updateAlternativeModeState_(e);},updateAlternativeModeState_:function(e){var shiftPressed=e.shiftKey;var spacePressed=this.spacePressed_;var cmdOrCtrlPressed=isCmdOrCtrlPressed(e);var smm=this.supportedModeMask_;var newMode;var isNewModeAnAlternativeMode=false;if(shiftPressed&&(this.modifierToModeMap_[MODIFIER.SHIFT]&smm)!==0){newMode=this.modifierToModeMap_[MODIFIER.SHIFT];isNewModeAnAlternativeMode=true;}else if(spacePressed&&(this.modifierToModeMap_[MODIFIER.SPACE]&smm)!==0){newMode=this.modifierToModeMap_[MODIFIER.SPACE];isNewModeAnAlternativeMode=true;}else if(cmdOrCtrlPressed&&(this.modifierToModeMap_[MODIFIER.CMD_OR_CTRL]&smm)!==0){newMode=this.modifierToModeMap_[MODIFIER.CMD_OR_CTRL];isNewModeAnAlternativeMode=true;}else{if(this.isInAlternativeMode_){newMode=this.modeBeforeAlternativeModeActivated_;isNewModeAnAlternativeMode=false;}else{newMode=undefined;}}
+if(this.mode===newMode||newMode===undefined)
+return;if(isNewModeAnAlternativeMode)
+this.modeBeforeAlternativeModeActivated_=this.mode;this.mode=newMode;},get isInAlternativeMode_(){return!!this.modeBeforeAlternativeModeActivated_;},setModifierForAlternateMode:function(mode,modifier){this.modifierToModeMap_[modifier]=mode;},get pos(){return{x:parseInt(this.style.left),y:parseInt(this.style.top)};},set pos(pos){pos=this.constrainPositionToBounds_(pos);this.style.left=pos.x+'px';this.style.top=pos.y+'px';if(this.settingsKey_)
+tr.b.Settings.set(this.settingsKey_+'.pos',this.pos);},constrainPositionToBounds_:function(pos){var parent=this.offsetParent||document.body;var parentRect=tr.ui.b.windowRectForElement(parent);var top=0;var bottom=parentRect.height-this.offsetHeight;var left=0;var right=parentRect.width-this.offsetWidth;var res={};res.x=Math.max(pos.x,left);res.x=Math.min(res.x,right);res.y=Math.max(pos.y,top);res.y=Math.min(res.y,bottom);return res;},onDragHandleMouseDown_:function(e){e.preventDefault();e.stopImmediatePropagation();var mouseDownPos={x:e.clientX-this.offsetLeft,y:e.clientY-this.offsetTop};tr.ui.b.trackMouseMovesUntilMouseUp(function(e){var pos={};pos.x=e.clientX-mouseDownPos.x;pos.y=e.clientY-mouseDownPos.y;this.pos=pos;}.bind(this));},checkIsClick_:function(e){if(!this.isInteracting_||!this.isClick_)
+return;var deltaX=this.mousePos_.x-this.mouseDownPos_.x;var deltaY=this.mousePos_.y-this.mouseDownPos_.y;var minDist=MIN_MOUSE_SELECTION_DISTANCE;if(deltaX*deltaX+deltaY*deltaY>minDist*minDist)
+this.isClick_=false;},dispatchClickEvents_:function(e){if(!this.isClick_)
+return;var modeInfo=MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.SELECTION];var eventNames=modeInfo.eventNames;var mouseEvent=this.createEvent_(eventNames.begin);mouseEvent.appendSelection=isCmdOrCtrlPressed(e);this.dispatchEvent(mouseEvent);mouseEvent=this.createEvent_(eventNames.end);this.dispatchEvent(mouseEvent);}});return{MIN_MOUSE_SELECTION_DISTANCE:MIN_MOUSE_SELECTION_DISTANCE,MODIFIER:MODIFIER};});'use strict';tr.exportTo('tr.ui.b',function(){function TimingTool(viewport,targetElement){this.viewport_=viewport;this.onMouseMove_=this.onMouseMove_.bind(this);this.onDblClick_=this.onDblClick_.bind(this);this.targetElement_=targetElement;this.isMovingLeftEdge_=false;};TimingTool.prototype={onEnterTiming:function(e){this.targetElement_.addEventListener('mousemove',this.onMouseMove_);this.targetElement_.addEventListener('dblclick',this.onDblClick_);},onBeginTiming:function(e){if(!this.isTouchPointInsideTrackBounds_(e.clientX,e.clientY))
+return;var pt=this.getSnappedToEventPosition_(e);this.mouseDownAt_(pt.x,pt.y);this.updateSnapIndicators_(pt);},updateSnapIndicators_:function(pt){if(!pt.snapped)
+return;var ir=this.viewport_.interestRange;if(ir.min===pt.x)
+ir.leftSnapIndicator=new tr.ui.SnapIndicator(pt.y,pt.height);if(ir.max===pt.x)
+ir.rightSnapIndicator=new tr.ui.SnapIndicator(pt.y,pt.height);},onUpdateTiming:function(e){var pt=this.getSnappedToEventPosition_(e);this.mouseMoveAt_(pt.x,pt.y,true);this.updateSnapIndicators_(pt);},onEndTiming:function(e){this.mouseUp_();},onExitTiming:function(e){this.targetElement_.removeEventListener('mousemove',this.onMouseMove_);this.targetElement_.removeEventListener('dblclick',this.onDblClick_);},onMouseMove_:function(e){if(e.button)
+return;var worldX=this.getWorldXFromEvent_(e);this.mouseMoveAt_(worldX,e.clientY,false);},onDblClick_:function(e){console.error('not implemented');},isTouchPointInsideTrackBounds_:function(clientX,clientY){if(!this.viewport_||!this.viewport_.modelTrackContainer||!this.viewport_.modelTrackContainer.canvas)
+return false;var canvas=this.viewport_.modelTrackContainer.canvas;var canvasRect=canvas.getBoundingClientRect();if(clientX>=canvasRect.left&&clientX<=canvasRect.right&&clientY>=canvasRect.top&&clientY<=canvasRect.bottom)
+return true;return false;},mouseDownAt_:function(worldX,y){var ir=this.viewport_.interestRange;var dt=this.viewport_.currentDisplayTransform;var pixelRatio=window.devicePixelRatio||1;var nearnessThresholdWorld=dt.xViewVectorToWorld(6*pixelRatio);if(ir.isEmpty){ir.setMinAndMax(worldX,worldX);ir.rightSelected=true;this.isMovingLeftEdge_=false;return;}
+if(Math.abs(worldX-ir.min)<nearnessThresholdWorld){ir.leftSelected=true;ir.min=worldX;this.isMovingLeftEdge_=true;return;}
+if(Math.abs(worldX-ir.max)<nearnessThresholdWorld){ir.rightSelected=true;ir.max=worldX;this.isMovingLeftEdge_=false;return;}
+ir.setMinAndMax(worldX,worldX);ir.rightSelected=true;this.isMovingLeftEdge_=false;},mouseMoveAt_:function(worldX,y,mouseDown){var ir=this.viewport_.interestRange;if(mouseDown){this.updateMovingEdge_(worldX);return;}
+var ir=this.viewport_.interestRange;var dt=this.viewport_.currentDisplayTransform;var pixelRatio=window.devicePixelRatio||1;var nearnessThresholdWorld=dt.xViewVectorToWorld(6*pixelRatio);if(Math.abs(worldX-ir.min)<nearnessThresholdWorld){ir.leftSelected=true;ir.rightSelected=false;return;}
+if(Math.abs(worldX-ir.max)<nearnessThresholdWorld){ir.leftSelected=false;ir.rightSelected=true;return;}
+ir.leftSelected=false;ir.rightSelected=false;return;},updateMovingEdge_:function(newWorldX){var ir=this.viewport_.interestRange;var a=ir.min;var b=ir.max;if(this.isMovingLeftEdge_)
+a=newWorldX;else
+b=newWorldX;if(a<=b)
+ir.setMinAndMax(a,b);else
+ir.setMinAndMax(b,a);if(ir.min==newWorldX){this.isMovingLeftEdge_=true;ir.leftSelected=true;ir.rightSelected=false;}else{this.isMovingLeftEdge_=false;ir.leftSelected=false;ir.rightSelected=true;}},mouseUp_:function(){var dt=this.viewport_.currentDisplayTransform;var ir=this.viewport_.interestRange;ir.leftSelected=false;ir.rightSelected=false;var pixelRatio=window.devicePixelRatio||1;var minWidthValue=dt.xViewVectorToWorld(2*pixelRatio);if(ir.range<minWidthValue)
+ir.reset();},getWorldXFromEvent_:function(e){var pixelRatio=window.devicePixelRatio||1;var canvas=this.viewport_.modelTrackContainer.canvas;var worldOffset=canvas.getBoundingClientRect().left;var viewX=(e.clientX-worldOffset)*pixelRatio;return this.viewport_.currentDisplayTransform.xViewToWorld(viewX);},getSnappedToEventPosition_:function(e){var pixelRatio=window.devicePixelRatio||1;var EVENT_SNAP_RANGE=16*pixelRatio;var modelTrackContainer=this.viewport_.modelTrackContainer;var modelTrackContainerRect=modelTrackContainer.getBoundingClientRect();var viewport=this.viewport_;var dt=viewport.currentDisplayTransform;var worldMaxDist=dt.xViewVectorToWorld(EVENT_SNAP_RANGE);var worldX=this.getWorldXFromEvent_(e);var mouseY=e.clientY;var selection=new tr.model.EventSet();modelTrackContainer.addClosestEventToSelection(worldX,worldMaxDist,mouseY,mouseY,selection);if(!selection.length){modelTrackContainer.addClosestEventToSelection(worldX,worldMaxDist,modelTrackContainerRect.top,modelTrackContainerRect.bottom,selection);}
+var minDistX=worldMaxDist;var minDistY=Infinity;var pixWidth=dt.xViewVectorToWorld(1);var result={x:worldX,y:mouseY-modelTrackContainerRect.top,height:0,snapped:false};var eventBounds=new tr.b.Range();for(var i=0;i<selection.length;i++){var event=selection[i];var track=viewport.trackForEvent(event);var trackRect=track.getBoundingClientRect();eventBounds.reset();event.addBoundsToRange(eventBounds);var eventX;if(Math.abs(eventBounds.min-worldX)<Math.abs(eventBounds.max-worldX)){eventX=eventBounds.min;}else{eventX=eventBounds.max;}
+var distX=eventX-worldX;var eventY=trackRect.top;var eventHeight=trackRect.height;var distY=Math.abs(eventY+eventHeight/2-mouseY);if((distX<=minDistX||Math.abs(distX-minDistX)<pixWidth)&&distY<minDistY){minDistX=distX;minDistY=distY;result.x=eventX;result.y=eventY+
+modelTrackContainer.scrollTop-modelTrackContainerRect.top;result.height=eventHeight;result.snapped=true;}}
+return result;}};return{TimingTool:TimingTool};});'use strict';tr.exportTo('tr.ui',function(){var kDefaultPanAnimatoinDurationMs=100.0;function TimelineDisplayTransformPanAnimation(deltaX,deltaY,opt_durationMs){this.deltaX=deltaX;this.deltaY=deltaY;if(opt_durationMs===undefined)
+this.durationMs=kDefaultPanAnimatoinDurationMs;else
+this.durationMs=opt_durationMs;this.startPanX=undefined;this.startPanY=undefined;this.startTimeMs=undefined;}
+TimelineDisplayTransformPanAnimation.prototype={__proto__:tr.ui.b.Animation.prototype,get affectsPanY(){return this.deltaY!==0;},canTakeOverFor:function(existingAnimation){return existingAnimation instanceof TimelineDisplayTransformPanAnimation;},takeOverFor:function(existing,timestamp,target){var remainingDeltaXOnExisting=existing.goalPanX-target.panX;var remainingDeltaYOnExisting=existing.goalPanY-target.panY;var remainingTimeOnExisting=timestamp-(existing.startTimeMs+existing.durationMs);remainingTimeOnExisting=Math.max(remainingTimeOnExisting,0);this.deltaX+=remainingDeltaXOnExisting;this.deltaY+=remainingDeltaYOnExisting;this.durationMs+=remainingTimeOnExisting;},start:function(timestamp,target){this.startTimeMs=timestamp;this.startPanX=target.panX;this.startPanY=target.panY;},tick:function(timestamp,target){var percentDone=(timestamp-this.startTimeMs)/this.durationMs;percentDone=tr.b.clamp(percentDone,0,1);target.panX=tr.b.lerp(percentDone,this.startPanX,this.goalPanX);if(this.affectsPanY)
+target.panY=tr.b.lerp(percentDone,this.startPanY,this.goalPanY);return timestamp>=this.startTimeMs+this.durationMs;},get goalPanX(){return this.startPanX+this.deltaX;},get goalPanY(){return this.startPanY+this.deltaY;}};function TimelineDisplayTransformZoomToAnimation(goalFocalPointXWorld,goalFocalPointXView,goalFocalPointY,zoomInRatioX,opt_durationMs){this.goalFocalPointXWorld=goalFocalPointXWorld;this.goalFocalPointXView=goalFocalPointXView;this.goalFocalPointY=goalFocalPointY;this.zoomInRatioX=zoomInRatioX;if(opt_durationMs===undefined)
+this.durationMs=kDefaultPanAnimatoinDurationMs;else
+this.durationMs=opt_durationMs;this.startTimeMs=undefined;this.startScaleX=undefined;this.goalScaleX=undefined;this.startPanY=undefined;}
+TimelineDisplayTransformZoomToAnimation.prototype={__proto__:tr.ui.b.Animation.prototype,get affectsPanY(){return this.startPanY!=this.goalFocalPointY;},canTakeOverFor:function(existingAnimation){return false;},takeOverFor:function(existingAnimation,timestamp,target){this.goalScaleX=target.scaleX*this.zoomInRatioX;},start:function(timestamp,target){this.startTimeMs=timestamp;this.startScaleX=target.scaleX;this.goalScaleX=this.zoomInRatioX*target.scaleX;this.startPanY=target.panY;},tick:function(timestamp,target){var percentDone=(timestamp-this.startTimeMs)/this.durationMs;percentDone=tr.b.clamp(percentDone,0,1);target.scaleX=tr.b.lerp(percentDone,this.startScaleX,this.goalScaleX);if(this.affectsPanY){target.panY=tr.b.lerp(percentDone,this.startPanY,this.goalFocalPointY);}
+target.xPanWorldPosToViewPos(this.goalFocalPointXWorld,this.goalFocalPointXView);return timestamp>=this.startTimeMs+this.durationMs;}};return{TimelineDisplayTransformPanAnimation:TimelineDisplayTransformPanAnimation,TimelineDisplayTransformZoomToAnimation:TimelineDisplayTransformZoomToAnimation};});'use strict';tr.exportTo('tr.ui.b',function(){var ContainerThatDecoratesItsChildren=tr.ui.b.define('div');ContainerThatDecoratesItsChildren.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.observer_=new WebKitMutationObserver(this.didMutate_.bind(this));this.observer_.observe(this,{childList:true});Object.defineProperty(this,'textContent',{get:undefined,set:this.onSetTextContent_});},appendChild:function(x){HTMLUnknownElement.prototype.appendChild.call(this,x);this.didMutate_(this.observer_.takeRecords());},insertBefore:function(x,y){HTMLUnknownElement.prototype.insertBefore.call(this,x,y);this.didMutate_(this.observer_.takeRecords());},removeChild:function(x){HTMLUnknownElement.prototype.removeChild.call(this,x);this.didMutate_(this.observer_.takeRecords());},replaceChild:function(x,y){HTMLUnknownElement.prototype.replaceChild.call(this,x,y);this.didMutate_(this.observer_.takeRecords());},onSetTextContent_:function(textContent){if(textContent!='')
+throw new Error('textContent can only be set to \'\'.');this.clear();},clear:function(){while(this.lastChild)
+HTMLUnknownElement.prototype.removeChild.call(this,this.lastChild);this.didMutate_(this.observer_.takeRecords());},didMutate_:function(records){this.beginDecorating_();for(var i=0;i<records.length;i++){var addedNodes=records[i].addedNodes;if(addedNodes){for(var j=0;j<addedNodes.length;j++)
+this.decorateChild_(addedNodes[j]);}
+var removedNodes=records[i].removedNodes;if(removedNodes){for(var j=0;j<removedNodes.length;j++){this.undecorateChild_(removedNodes[j]);}}}
+this.doneDecoratingForNow_();},decorateChild_:function(child){throw new Error('Not implemented');},undecorateChild_:function(child){throw new Error('Not implemented');},beginDecorating_:function(){},doneDecoratingForNow_:function(){}};return{ContainerThatDecoratesItsChildren:ContainerThatDecoratesItsChildren};});'use strict';tr.exportTo('tr.ui.tracks',function(){var Track=tr.ui.b.define('track',tr.ui.b.ContainerThatDecoratesItsChildren);Track.prototype={__proto__:tr.ui.b.ContainerThatDecoratesItsChildren.prototype,decorate:function(viewport){tr.ui.b.ContainerThatDecoratesItsChildren.prototype.decorate.call(this);if(viewport===undefined)
+throw new Error('viewport is required when creating a Track.');this.viewport_=viewport;this.classList.add('track');},get viewport(){return this.viewport_;},get drawingContainer(){var cur=this;while(cur){if(cur instanceof tr.ui.tracks.DrawingContainer)
+return cur;cur=cur.parentElement;}
+return undefined;},get eventContainer(){},invalidateDrawingContainer:function(){var dc=this.drawingContainer;if(dc)
+dc.invalidate();},context:function(){if(!this.parentNode)
+return undefined;if(!this.parentNode.context)
+throw new Error('Parent container does not support context() method.');return this.parentNode.context();},decorateChild_:function(childTrack){},undecorateChild_:function(childTrack){if(childTrack.detach)
+childTrack.detach();},updateContents_:function(){},drawTrack:function(type){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var canvasBounds=ctx.canvas.getBoundingClientRect();ctx.save();ctx.translate(0,pixelRatio*(bounds.top-canvasBounds.top));var dt=this.viewport.currentDisplayTransform;var viewLWorld=dt.xViewToWorld(0);var viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);this.draw(type,viewLWorld,viewRWorld);ctx.restore();},draw:function(type,viewLWorld,viewRWorld){},addEventsToTrackMap:function(eventToTrackMap){},addContainersToTrackMap:function(containerToTrackMap){},addIntersectingEventsInRangeToSelection:function(loVX,hiVX,loVY,hiVY,selection){var pixelRatio=window.devicePixelRatio||1;var dt=this.viewport.currentDisplayTransform;var viewPixWidthWorld=dt.xViewVectorToWorld(1);var loWX=dt.xViewToWorld(loVX*pixelRatio);var hiWX=dt.xViewToWorld(hiVX*pixelRatio);var clientRect=this.getBoundingClientRect();var a=Math.max(loVY,clientRect.top);var b=Math.min(hiVY,clientRect.bottom);if(a>b)
+return;this.addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){},addClosestInstantEventToSelection:function(instantEvents,worldX,worldMaxDist,selection){var instantEvent=tr.b.findClosestElementInSortedArray(instantEvents,function(x){return x.start;},worldX,worldMaxDist);if(!instantEvent)
+return;selection.push(instantEvent);}};return{Track:Track};});'use strict';tr.exportTo('tr.ui.b',function(){var constants={HEADING_WIDTH:250};return{constants:constants};});'use strict';tr.exportTo('tr.ui.tracks',function(){var DrawType={GENERAL_EVENT:1,INSTANT_EVENT:2,BACKGROUND:3,GRID:4,FLOW_ARROWS:5,MARKERS:6,HIGHLIGHTS:7,ANNOTATIONS:8};var DrawingContainer=tr.ui.b.define('drawing-container',tr.ui.tracks.Track);DrawingContainer.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('drawing-container');this.canvas_=document.createElement('canvas');this.canvas_.className='drawing-container-canvas';this.canvas_.style.left=tr.ui.b.constants.HEADING_WIDTH+'px';this.appendChild(this.canvas_);this.ctx_=this.canvas_.getContext('2d');this.viewportChange_=this.viewportChange_.bind(this);this.viewport.addEventListener('change',this.viewportChange_);},get canvas(){return this.canvas_;},context:function(){return this.ctx_;},viewportChange_:function(){this.invalidate();},invalidate:function(){if(this.rafPending_)
+return;this.rafPending_=true;tr.b.requestPreAnimationFrame(this.preDraw_,this);},preDraw_:function(){this.rafPending_=false;this.updateCanvasSizeIfNeeded_();tr.b.requestAnimationFrameInThisFrameIfPossible(this.draw_,this);},draw_:function(){this.ctx_.clearRect(0,0,this.canvas_.width,this.canvas_.height);var typesToDraw=[DrawType.BACKGROUND,DrawType.HIGHLIGHTS,DrawType.GRID,DrawType.INSTANT_EVENT,DrawType.GENERAL_EVENT,DrawType.MARKERS,DrawType.ANNOTATIONS,DrawType.FLOW_ARROWS];for(var idx in typesToDraw){for(var i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track))
+continue;this.children[i].drawTrack(typesToDraw[idx]);}}
+var pixelRatio=window.devicePixelRatio||1;var bounds=this.canvas_.getBoundingClientRect();var dt=this.viewport.currentDisplayTransform;var viewLWorld=dt.xViewToWorld(0);var viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);this.viewport.drawGridLines(this.ctx_,viewLWorld,viewRWorld);},updateCanvasSizeIfNeeded_:function(){var visibleChildTracks=tr.b.asArray(this.children).filter(this.visibleFilter_);var thisBounds=this.getBoundingClientRect();var firstChildTrackBounds=visibleChildTracks[0].getBoundingClientRect();var lastChildTrackBounds=visibleChildTracks[visibleChildTracks.length-1].getBoundingClientRect();var innerWidth=firstChildTrackBounds.width-
+tr.ui.b.constants.HEADING_WIDTH;var innerHeight=lastChildTrackBounds.bottom-firstChildTrackBounds.top;var pixelRatio=window.devicePixelRatio||1;if(this.canvas_.width!=innerWidth*pixelRatio){this.canvas_.width=innerWidth*pixelRatio;this.canvas_.style.width=innerWidth+'px';}
+if(this.canvas_.height!=innerHeight*pixelRatio){this.canvas_.height=innerHeight*pixelRatio;this.canvas_.style.height=innerHeight+'px';}},visibleFilter_:function(element){if(!(element instanceof tr.ui.tracks.Track))
+return false;return window.getComputedStyle(element).display!=='none';},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){for(var i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track))
+continue;var trackClientRect=this.children[i].getBoundingClientRect();var a=Math.max(loY,trackClientRect.top);var b=Math.min(hiY,trackClientRect.bottom);if(a<=b){this.children[i].addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);}}
+tr.ui.tracks.Track.prototype.addClosestEventToSelection.apply(this,arguments);},addEventsToTrackMap:function(eventToTrackMap){for(var i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track))
+continue;this.children[i].addEventsToTrackMap(eventToTrackMap);}}};return{DrawingContainer:DrawingContainer,DrawType:DrawType};});'use strict';tr.exportTo('tr.model',function(){var SelectableItem=tr.model.SelectableItem;var SelectionState=tr.model.SelectionState;function ProxySelectableItem(modelItem){SelectableItem.call(this,modelItem);};ProxySelectableItem.prototype={__proto__:SelectableItem.prototype,get selectionState(){var modelItem=this.modelItem_;if(modelItem===undefined)
+return SelectionState.NONE;return modelItem.selectionState;}};return{ProxySelectableItem:ProxySelectableItem};});'use strict';Polymer('tr-ui-heading',{DOWN_ARROW:String.fromCharCode(0x25BE),RIGHT_ARROW:String.fromCharCode(0x25B8),ready:function(viewport){this.style.width=(tr.ui.b.constants.HEADING_WIDTH-6)+'px';this.heading_='';this.expanded_=true;this.arrowVisible_=false;this.selectionGenerator_=undefined;this.updateContents_();},get heading(){return this.heading_;},set heading(text){if(this.heading_===text)
+return;this.heading_=text;this.updateContents_();},set arrowVisible(val){if(this.arrowVisible_===val)
+return;this.arrowVisible_=!!val;this.updateContents_();},set tooltip(text){this.$.heading.title=text;},set selectionGenerator(generator){if(this.selectionGenerator_===generator)
+return;this.selectionGenerator_=generator;this.updateContents_();},get expanded(){return this.expanded_;},set expanded(expanded){if(this.expanded_===expanded)
+return;this.expanded_=!!expanded;this.updateContents_();},onHeadingDivClicked_:function(){this.dispatchEvent(new tr.b.Event('heading-clicked',{'bubbles':true}));},updateContents_:function(){if(this.arrowVisible_){this.$.arrow.style.display='';}else{this.$.arrow.style.display='none';this.$.heading.style.display=this.expanded_?'':'none';}
+if(this.arrowVisible_){this.$.arrow.textContent=this.expanded_?this.DOWN_ARROW:this.RIGHT_ARROW;}
+this.$.link.style.display='none';this.$.heading_content.style.display='none';if(this.selectionGenerator_){this.$.link.style.display='inline-block';this.$.link.selection=this.selectionGenerator_;this.$.link.textContent=this.heading_;}else{this.$.heading_content.style.display='inline-block';this.$.heading_content.textContent=this.heading_;}}});'use strict';tr.exportTo('tr.ui.tracks',function(){var EventPresenter=tr.ui.b.EventPresenter;var SelectionState=tr.model.SelectionState;var LetterDotTrack=tr.ui.b.define('letter-dot-track',tr.ui.tracks.Track);LetterDotTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('letter-dot-track');this.items_=undefined;this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},get items(){return this.items_;},set items(items){this.items_=items;this.invalidateDrawingContainer();},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},get dumpRadiusView(){return 7*(window.devicePixelRatio||1);},draw:function(type,viewLWorld,viewRWorld){if(this.items_===undefined)
+return;switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawLetterDots_(viewLWorld,viewRWorld);break;}},drawLetterDots_:function(viewLWorld,viewRWorld){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var height=bounds.height*pixelRatio;var halfHeight=height*0.5;var twoPi=Math.PI*2;var dt=this.viewport.currentDisplayTransform;var dumpRadiusView=this.dumpRadiusView;var itemRadiusWorld=dt.xViewVectorToWorld(height);var items=this.items_;var loI=tr.b.findLowIndexInSortedArray(items,function(item){return item.start;},viewLWorld);var oldFont=ctx.font;ctx.font='400 '+Math.floor(9*pixelRatio)+'px Arial';ctx.strokeStyle='rgb(0,0,0)';ctx.textBaseline='middle';ctx.textAlign='center';var drawItems=function(selected){for(var i=loI;i<items.length;++i){var item=items[i];var x=item.start;if(x-itemRadiusWorld>viewRWorld)
+break;if(item.selected!==selected)
+continue;var xView=dt.xWorldToView(x);ctx.fillStyle=EventPresenter.getSelectableItemColorAsString(item);ctx.beginPath();ctx.arc(xView,halfHeight,dumpRadiusView+0.5,0,twoPi);ctx.fill();if(item.selected){ctx.lineWidth=3;ctx.strokeStyle='rgb(100,100,0)';ctx.stroke();ctx.beginPath();ctx.arc(xView,halfHeight,dumpRadiusView,0,twoPi);ctx.lineWidth=1.5;ctx.strokeStyle='rgb(255,255,0)';ctx.stroke();}else{ctx.lineWidth=1;ctx.strokeStyle='rgb(0,0,0)';ctx.stroke();}
+ctx.fillStyle='rgb(255, 255, 255)';ctx.fillText(item.dotLetter,xView,halfHeight);}};drawItems(false);drawItems(true);ctx.lineWidth=1;ctx.font=oldFont;},addEventsToTrackMap:function(eventToTrackMap){if(this.items_===undefined)
+return;this.items_.forEach(function(item){item.addToTrackMap(eventToTrackMap,this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){if(this.items_===undefined)
+return;var itemRadiusWorld=viewPixWidthWorld*this.dumpRadiusView;tr.b.iterateOverIntersectingIntervals(this.items_,function(x){return x.start-itemRadiusWorld;},function(x){return 2*itemRadiusWorld;},loWX,hiWX,function(item){item.addToSelection(selection);}.bind(this));},addEventNearToProvidedEventToSelection:function(event,offset,selection){if(this.items_===undefined)
+return;var items=this.items_;var index=tr.b.findFirstIndexInArray(items,function(item){return item.modelItem===event;});if(index===-1)
+return false;var newIndex=index+offset;if(newIndex>=0&&newIndex<items.length){items[newIndex].addToSelection(selection);return true;}
+return false;},addAllEventsMatchingFilterToSelection:function(filter,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){if(this.items_===undefined)
+return;var item=tr.b.findClosestElementInSortedArray(this.items_,function(x){return x.start;},worldX,worldMaxDist);if(!item)
+return;item.addToSelection(selection);}};function LetterDot(modelItem,dotLetter,colorId,start){tr.model.ProxySelectableItem.call(this,modelItem);this.dotLetter=dotLetter;this.colorId=colorId;this.start=start;};LetterDot.prototype={__proto__:tr.model.ProxySelectableItem.prototype};return{LetterDotTrack:LetterDotTrack,LetterDot:LetterDot};});'use strict';tr.exportTo('tr.ui.tracks',function(){var AlertTrack=tr.ui.b.define('alert-track',tr.ui.tracks.LetterDotTrack);AlertTrack.prototype={__proto__:tr.ui.tracks.LetterDotTrack.prototype,decorate:function(viewport){tr.ui.tracks.LetterDotTrack.prototype.decorate.call(this,viewport);this.heading='Alerts';this.alerts_=undefined;},get alerts(){return this.alerts_;},set alerts(alerts){this.alerts_=alerts;if(alerts===undefined){this.items=undefined;return;}
+this.items=this.alerts_.map(function(alert){return new tr.ui.tracks.LetterDot(alert,String.fromCharCode(9888),alert.colorId,alert.start);});}};return{AlertTrack:AlertTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var Task=tr.b.Task;var ContainerTrack=tr.ui.b.define('container-track',tr.ui.tracks.Track);ContainerTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);},detach:function(){this.textContent='';},get tracks_(){var tracks=[];for(var i=0;i<this.children.length;i++){if(this.children[i]instanceof tr.ui.tracks.Track)
+tracks.push(this.children[i]);}
+return tracks;},drawTrack:function(type){this.tracks_.forEach(function(track){track.drawTrack(type);});},addIntersectingEventsInRangeToSelection:function(loVX,hiVX,loY,hiY,selection){for(var i=0;i<this.tracks_.length;i++){var trackClientRect=this.tracks_[i].getBoundingClientRect();var a=Math.max(loY,trackClientRect.top);var b=Math.min(hiY,trackClientRect.bottom);if(a<=b)
+this.tracks_[i].addIntersectingEventsInRangeToSelection(loVX,hiVX,loY,hiY,selection);}
+tr.ui.tracks.Track.prototype.addIntersectingEventsInRangeToSelection.apply(this,arguments);},addEventsToTrackMap:function(eventToTrackMap){for(var i=0;i<this.children.length;++i)
+this.children[i].addEventsToTrackMap(eventToTrackMap);},addAllEventsMatchingFilterToSelection:function(filter,selection){for(var i=0;i<this.tracks_.length;i++)
+this.tracks_[i].addAllEventsMatchingFilterToSelection(filter,selection);},addAllEventsMatchingFilterToSelectionAsTask:function(filter,selection){var task=new Task();for(var i=0;i<this.tracks_.length;i++){task.subTask(function(i){return function(){this.tracks_[i].addAllEventsMatchingFilterToSelection(filter,selection);}}(i),this);}
+return task;},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){for(var i=0;i<this.tracks_.length;i++){var trackClientRect=this.tracks_[i].getBoundingClientRect();var a=Math.max(loY,trackClientRect.top);var b=Math.min(hiY,trackClientRect.bottom);if(a<=b){this.tracks_[i].addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);}}
+tr.ui.tracks.Track.prototype.addClosestEventToSelection.apply(this,arguments);},addContainersToTrackMap:function(containerToTrackMap){this.tracks_.forEach(function(track){track.addContainersToTrackMap(containerToTrackMap);});},clearTracks_:function(){this.tracks_.forEach(function(track){this.removeChild(track);},this);}};return{ContainerTrack:ContainerTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ChartAxis(opt_min,opt_max){this.guid_=tr.b.GUID.allocate();this.bounds=new tr.b.Range();if(opt_min!==undefined)
+this.bounds.addValue(opt_min);if(opt_max!==undefined)
+this.bounds.addValue(opt_max);};ChartAxis.prototype={get guid(){return this.guid_;},valueToUnitRange:function(value){if(this.bounds.isEmpty)
+throw new Error('Chart axis bounds are empty');var bounds=this.bounds;if(bounds.range===0)
+return 0;return(value-bounds.min)/bounds.range;},autoSetFromSeries:function(series,opt_config){var range=new tr.b.Range();series.forEach(function(s){range.addRange(s.range);},this);this.autoSetFromRange(range,opt_config);},autoSetFromRange:function(range,opt_config){if(range.isEmpty)
+return;var bounds=this.bounds;if(bounds.isEmpty){bounds.addRange(range);return;}
+if(!opt_config)
+return;var useRangeMin=(opt_config.expandMin&&range.min<bounds.min||opt_config.shrinkMin&&range.min>bounds.min);var useRangeMax=(opt_config.expandMax&&range.max>bounds.max||opt_config.shrinkMax&&range.max<bounds.max);if(!useRangeMin&&!useRangeMax)
+return;if(useRangeMin&&useRangeMax){bounds.min=range.min;bounds.max=range.max;return;}
+if(useRangeMin){bounds.min=Math.min(range.min,bounds.max);}else{bounds.max=Math.max(range.max,bounds.min);}}};return{ChartAxis:ChartAxis};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ChartPoint(modelItem,x,y,opt_yBase){tr.model.ProxySelectableItem.call(this,modelItem);this.x=x;this.y=y;this.yBase=opt_yBase;};ChartPoint.prototype={__proto__:tr.model.ProxySelectableItem.prototype};return{ChartPoint:ChartPoint};});'use strict';tr.exportTo('tr.ui.tracks',function(){var EventPresenter=tr.ui.b.EventPresenter;var SelectionState=tr.model.SelectionState;var ChartSeriesType={LINE:0,AREA:1};var DEFAULT_RENDERING_CONFIG={chartType:ChartSeriesType.LINE,selectedPointSize:4,unselectedPointSize:3,colorId:0,lineWidth:1,skipDistance:1,unselectedPointDensityTransparent:0.10,unselectedPointDensityOpaque:0.05,backgroundOpacity:0.5};var LAST_POINT_WIDTH=16;var ChartSeriesComponent={BACKGROUND:0,LINE:1,DOTS:2};function ChartSeries(points,axis,opt_renderingConfig){this.points=points;this.axis=axis;this.useRenderingConfig_(opt_renderingConfig);}
+ChartSeries.prototype={useRenderingConfig_:function(opt_renderingConfig){var config=opt_renderingConfig||{};tr.b.iterItems(DEFAULT_RENDERING_CONFIG,function(key,defaultValue){var value=config[key];if(value===undefined)
+value=defaultValue;this[key+'_']=value;},this);this.topPadding=this.bottomPadding=Math.max(this.selectedPointSize_,this.unselectedPointSize_)/2;},get range(){var range=new tr.b.Range();this.points.forEach(function(point){range.addValue(point.y);},this);return range;},draw:function(ctx,transform,highDetails){if(this.points===undefined||this.points.length===0)
+return;if(this.chartType_===ChartSeriesType.AREA){this.drawComponent_(ctx,transform,ChartSeriesComponent.BACKGROUND,highDetails);}
+if(this.chartType_===ChartSeriesType.LINE||highDetails){this.drawComponent_(ctx,transform,ChartSeriesComponent.LINE,highDetails);}
+this.drawComponent_(ctx,transform,ChartSeriesComponent.DOTS,highDetails);},drawComponent_:function(ctx,transform,component,highDetails){var extraPixels=0;if(component===ChartSeriesComponent.DOTS){extraPixels=Math.max(this.selectedPointSize_,this.unselectedPointSize_);}
+var leftViewX=transform.leftViewX-extraPixels*transform.pixelRatio;var rightViewX=transform.rightViewX+
+extraPixels*transform.pixelRatio;var leftTimestamp=transform.leftTimestamp-extraPixels;var rightTimestamp=transform.rightTimestamp+extraPixels;var firstVisibleIndex=tr.b.findLowIndexInSortedArray(this.points,function(point){return point.x;},leftTimestamp);var lastVisibleIndex=tr.b.findLowIndexInSortedArray(this.points,function(point){return point.x;},rightTimestamp);if(lastVisibleIndex>=this.points.length||this.points[lastVisibleIndex].x>rightTimestamp){lastVisibleIndex--;}
+var viewSkipDistance=this.skipDistance_*transform.pixelRatio;var circleRadius;var squareSize;var squareHalfSize;var squareOpacity;switch(component){case ChartSeriesComponent.DOTS:ctx.strokeStyle=EventPresenter.getCounterSeriesColor(this.colorId_,SelectionState.NONE);ctx.lineWidth=transform.pixelRatio;circleRadius=(this.selectedPointSize_/2)*transform.pixelRatio;squareSize=this.unselectedPointSize_*transform.pixelRatio;squareHalfSize=squareSize/2;if(!highDetails){squareOpacity=0;break;}
+var visibleIndexRange=lastVisibleIndex-firstVisibleIndex;if(visibleIndexRange<=0){squareOpacity=1;break;}
+var visibleViewXRange=transform.worldXToViewX(this.points[lastVisibleIndex].x)-
+transform.worldXToViewX(this.points[firstVisibleIndex].x);if(visibleViewXRange===0){squareOpacity=1;break;}
+var density=visibleIndexRange/visibleViewXRange;var clampedDensity=tr.b.clamp(density,this.unselectedPointDensityOpaque_,this.unselectedPointDensityTransparent_);var densityRange=this.unselectedPointDensityTransparent_-
+this.unselectedPointDensityOpaque_;squareOpacity=(this.unselectedPointDensityTransparent_-clampedDensity)/densityRange;break;case ChartSeriesComponent.LINE:ctx.strokeStyle=EventPresenter.getCounterSeriesColor(this.colorId_,SelectionState.NONE);ctx.lineWidth=this.lineWidth_*transform.pixelRatio;break;case ChartSeriesComponent.BACKGROUND:break;default:throw new Error('Invalid component: '+component);}
+var previousViewX=undefined;var previousViewY=undefined;var previousViewYBase=undefined;var lastSelectionState=undefined;var baseSteps=undefined;var startIndex=Math.max(firstVisibleIndex-1,0);for(var i=startIndex;i<this.points.length;i++){var currentPoint=this.points[i];var currentViewX=transform.worldXToViewX(currentPoint.x);if(currentViewX>rightViewX){if(previousViewX!==undefined){previousViewX=currentViewX=rightViewX;if(component===ChartSeriesComponent.BACKGROUND||component===ChartSeriesComponent.LINE){ctx.lineTo(currentViewX,previousViewY);}}
+break;}
+if(i+1<this.points.length){var nextPoint=this.points[i+1];var nextViewX=transform.worldXToViewX(nextPoint.x);if(previousViewX!==undefined&&nextViewX-previousViewX<=viewSkipDistance&&nextViewX<rightViewX){continue;}
+if(currentViewX<leftViewX){currentViewX=leftViewX;}}
+if(previousViewX!==undefined&&currentViewX-previousViewX<viewSkipDistance){currentViewX=previousViewX+viewSkipDistance;}
+var currentViewY=Math.round(transform.worldYToViewY(currentPoint.y));var currentViewYBase;if(currentPoint.yBase===undefined){currentViewYBase=transform.outerBottomViewY;}else{currentViewYBase=Math.round(transform.worldYToViewY(currentPoint.yBase));}
+var currentSelectionState=currentPoint.selectionState;switch(component){case ChartSeriesComponent.DOTS:if(currentSelectionState!==lastSelectionState){if(currentSelectionState===SelectionState.SELECTED){ctx.fillStyle=EventPresenter.getCounterSeriesColor(this.colorId_,currentSelectionState);}else if(squareOpacity>0){ctx.fillStyle=EventPresenter.getCounterSeriesColor(this.colorId_,currentSelectionState,squareOpacity);}}
+if(currentSelectionState===SelectionState.SELECTED){ctx.beginPath();ctx.arc(currentViewX,currentViewY,circleRadius,0,2*Math.PI);ctx.fill();ctx.stroke();}else if(squareOpacity>0){ctx.fillRect(currentViewX-squareHalfSize,currentViewY-squareHalfSize,squareSize,squareSize);}
+break;case ChartSeriesComponent.LINE:if(previousViewX===undefined){ctx.beginPath();ctx.moveTo(currentViewX,currentViewY);}else{ctx.lineTo(currentViewX,previousViewY);}
+ctx.lineTo(currentViewX,currentViewY);break;case ChartSeriesComponent.BACKGROUND:if(previousViewX!==undefined)
+ctx.lineTo(currentViewX,previousViewY);if(currentSelectionState!==lastSelectionState){if(previousViewX!==undefined){var previousBaseStepViewX=currentViewX;for(var j=baseSteps.length-1;j>=0;j--){var baseStep=baseSteps[j];var baseStepViewX=baseStep.viewX;var baseStepViewY=baseStep.viewY;ctx.lineTo(previousBaseStepViewX,baseStepViewY);ctx.lineTo(baseStepViewX,baseStepViewY);previousBaseStepViewX=baseStepViewX;}
+ctx.closePath();ctx.fill();}
+ctx.beginPath();ctx.fillStyle=EventPresenter.getCounterSeriesColor(this.colorId_,currentSelectionState,this.backgroundOpacity_);ctx.moveTo(currentViewX,currentViewYBase);baseSteps=[];}
+if(currentViewYBase!==previousViewYBase||currentSelectionState!==lastSelectionState){baseSteps.push({viewX:currentViewX,viewY:currentViewYBase});}
+ctx.lineTo(currentViewX,currentViewY);break;default:throw new Error('Not reachable');}
+previousViewX=currentViewX;previousViewY=currentViewY;previousViewYBase=currentViewYBase;lastSelectionState=currentSelectionState;}
+if(previousViewX!==undefined){switch(component){case ChartSeriesComponent.DOTS:break;case ChartSeriesComponent.LINE:ctx.stroke();break;case ChartSeriesComponent.BACKGROUND:var previousBaseStepViewX=currentViewX;for(var j=baseSteps.length-1;j>=0;j--){var baseStep=baseSteps[j];var baseStepViewX=baseStep.viewX;var baseStepViewY=baseStep.viewY;ctx.lineTo(previousBaseStepViewX,baseStepViewY);ctx.lineTo(baseStepViewX,baseStepViewY);previousBaseStepViewX=baseStepViewX;}
+ctx.closePath();ctx.fill();break;default:throw new Error('Not reachable');}}},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){var points=this.points;function getPointWidth(point,i){if(i===points.length-1)
+return LAST_POINT_WIDTH*viewPixWidthWorld;var nextPoint=points[i+1];return nextPoint.x-point.x;}
+function selectPoint(point){point.addToSelection(selection);}
+tr.b.iterateOverIntersectingIntervals(this.points,function(point){return point.x},getPointWidth,loWX,hiWX,selectPoint);},addEventNearToProvidedEventToSelection:function(event,offset,selection){if(this.points===undefined)
+return false;var index=tr.b.findFirstIndexInArray(this.points,function(point){return point.modelItem===event;},this);if(index===-1)
+return false;var newIndex=index+offset;if(newIndex<0||newIndex>=this.points.length)
+return false;this.points[newIndex].addToSelection(selection);return true;},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){if(this.points===undefined)
+return;var item=tr.b.findClosestElementInSortedArray(this.points,function(point){return point.x},worldX,worldMaxDist);if(!item)
+return;item.addToSelection(selection);}};return{ChartSeries:ChartSeries,ChartSeriesType:ChartSeriesType};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ChartTransform(displayTransform,axis,trackWidth,trackHeight,topPadding,bottomPadding,pixelRatio){this.pixelRatio=pixelRatio;this.leftViewX=0;this.rightViewX=trackWidth;this.leftTimestamp=displayTransform.xViewToWorld(this.leftViewX);this.rightTimestamp=displayTransform.xViewToWorld(this.rightViewX);this.displayTransform_=displayTransform;this.outerTopViewY=0;this.innerTopViewY=topPadding;this.innerBottomViewY=trackHeight-bottomPadding;this.outerBottomViewY=trackHeight;this.axis_=axis;this.innerHeight_=this.innerBottomViewY-this.innerTopViewY;};ChartTransform.prototype={worldXToViewX:function(worldX){return this.displayTransform_.xWorldToView(worldX);},viewXToWorldX:function(viewX){return this.displayTransform_.xViewToWorld(viewX);},worldYToViewY:function(worldY){var innerHeightCoefficient=1-this.axis_.valueToUnitRange(worldY);return innerHeightCoefficient*this.innerHeight_+this.innerTopViewY;}};return{ChartTransform:ChartTransform};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ChartTrack=tr.ui.b.define('chart-track',tr.ui.tracks.Track);ChartTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('chart-track');this.series_=undefined;this.axisGuidToAxisData_=undefined;this.topPadding_=undefined;this.bottomPadding_=undefined;this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},get series(){return this.series_;},set series(series){this.series_=series;this.calculateAxisDataAndPadding_();this.invalidateDrawingContainer();},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;this.invalidateDrawingContainer();},get hasVisibleContent(){return!!this.series&&this.series.length>0;},calculateAxisDataAndPadding_:function(){if(!this.series_){this.axisGuidToAxisData_=undefined;this.topPadding_=undefined;this.bottomPadding_=undefined;return;}
+var axisGuidToAxisData={};var topPadding=0;var bottomPadding=0;this.series_.forEach(function(series){var axis=series.axis;var axisGuid=axis.guid;if(!(axisGuid in axisGuidToAxisData)){axisGuidToAxisData[axisGuid]={axis:axis,series:[]};}
+axisGuidToAxisData[axisGuid].series.push(series);topPadding=Math.max(topPadding,series.topPadding);bottomPadding=Math.max(bottomPadding,series.bottomPadding);},this);this.axisGuidToAxisData_=axisGuidToAxisData;this.topPadding_=topPadding;this.bottomPadding_=bottomPadding;},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawChart_(viewLWorld,viewRWorld);break;}},drawChart_:function(viewLWorld,viewRWorld){if(!this.series_)
+return;var ctx=this.context();var displayTransform=this.viewport.currentDisplayTransform;var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var highDetails=this.viewport.highDetails;var width=bounds.width*pixelRatio;var height=bounds.height*pixelRatio;var topPadding=this.topPadding_*pixelRatio;var bottomPadding=this.bottomPadding_*pixelRatio;ctx.save();ctx.beginPath();ctx.rect(0,0,width,height);ctx.clip();this.series_.forEach(function(series){var chartTransform=new tr.ui.tracks.ChartTransform(displayTransform,series.axis,width,height,topPadding,bottomPadding,pixelRatio);series.draw(ctx,chartTransform,highDetails);},this);ctx.restore();},addEventsToTrackMap:function(eventToTrackMap){this.series_.forEach(function(series){series.points.forEach(function(point){point.addToTrackMap(eventToTrackMap,this);},this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){this.series_.forEach(function(series){series.addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection);},this);},addEventNearToProvidedEventToSelection:function(event,offset,selection){var foundItem=false;this.series_.forEach(function(series){foundItem=foundItem||series.addEventNearToProvidedEventToSelection(event,offset,selection);},this);return foundItem;},addAllEventsMatchingFilterToSelection:function(filter,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){this.series_.forEach(function(series){series.addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);},this);},autoSetAllAxes:function(opt_config){tr.b.iterItems(this.axisGuidToAxisData_,function(axisGuid,axisData){var axis=axisData.axis;var series=axisData.series;axis.autoSetFromSeries(series,opt_config);},this);},autoSetAxis:function(axis,opt_config){var series=this.axisGuidToAxisData_[axis.guid].series;axis.autoSetFromSeries(series,opt_config);}};return{ChartTrack:ChartTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ColorScheme=tr.b.ColorScheme;var ChartTrack=tr.ui.tracks.ChartTrack;var PowerSeriesTrack=tr.ui.b.define('power-series-track',ChartTrack);PowerSeriesTrack.prototype={__proto__:ChartTrack.prototype,decorate:function(viewport){ChartTrack.prototype.decorate.call(this,viewport);this.classList.add('power-series-track');this.heading='Power';this.powerSeries_=undefined;},set powerSeries(powerSeries){this.powerSeries_=powerSeries;this.series=this.buildChartSeries_();this.autoSetAllAxes({expandMax:true});},get hasVisibleContent(){return(this.powerSeries_&&this.powerSeries_.samples.length>0);},addContainersToTrackMap:function(containerToTrackMap){containerToTrackMap.addContainer(this.powerSeries_,this);},buildChartSeries_:function(){if(!this.hasVisibleContent)
+return[];var axis=new tr.ui.tracks.ChartAxis(0,undefined);var pts=this.powerSeries_.samples.map(function(smpl){return new tr.ui.tracks.ChartPoint(smpl,smpl.start,smpl.power);});var renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:ColorScheme.getColorIdForGeneralPurposeString(this.heading)};return[new tr.ui.tracks.ChartSeries(pts,axis,renderingConfig)];}};return{PowerSeriesTrack:PowerSeriesTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SpacingTrack=tr.ui.b.define('spacing-track',tr.ui.tracks.Track);SpacingTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('spacing-track');this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},draw:function(type,viewLWorld,viewRWorld){},addAllEventsMatchingFilterToSelection:function(filter,selection){}};return{SpacingTrack:SpacingTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ContainerTrack=tr.ui.tracks.ContainerTrack;var DeviceTrack=tr.ui.b.define('device-track',ContainerTrack);DeviceTrack.prototype={__proto__:ContainerTrack.prototype,decorate:function(viewport){ContainerTrack.prototype.decorate.call(this,viewport);this.classList.add('device-track');this.device_=undefined;this.powerSeriesTrack_=undefined;},get device(){return this.device_;},set device(device){this.device_=device;this.updateContents_();},get powerSeriesTrack(){return this.powerSeriesTrack_;},get hasVisibleContent(){return(this.powerSeriesTrack_&&this.powerSeriesTrack_.hasVisibleContent);},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.ContainerTrack.prototype.addContainersToTrackMap.call(this,containerToTrackMap);containerToTrackMap.addContainer(this.device,this);},addEventsToTrackMap:function(eventToTrackMap){this.tracks_.forEach(function(track){track.addEventsToTrackMap(eventToTrackMap);});},appendPowerSeriesTrack_:function(){this.powerSeriesTrack_=new tr.ui.tracks.PowerSeriesTrack(this.viewport);this.powerSeriesTrack_.powerSeries=this.device.powerSeries;if(this.powerSeriesTrack_.hasVisibleContent){this.appendChild(this.powerSeriesTrack_);this.appendChild(new tr.ui.tracks.SpacingTrack(this.viewport));}},updateContents_:function(){this.clearTracks_();this.appendPowerSeriesTrack_();}};return{DeviceTrack:DeviceTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ColorScheme=tr.b.ColorScheme;var DISPLAYED_SIZE_ATTRIBUTE_NAME=tr.model.MemoryAllocatorDump.DISPLAYED_SIZE_ATTRIBUTE_NAME;function addDictionary(dstDict,srcDict){tr.b.iterItems(srcDict,function(key,value){var existingValue=dstDict[key];if(existingValue===undefined)
+existingValue=0;dstDict[key]=existingValue+value;});}
+function getProcessMemoryDumpAllocatorSizes(processMemoryDump){var allocatorDumps=processMemoryDump.memoryAllocatorDumps;if(allocatorDumps===undefined)
+return{};var allocatorSizes={};allocatorDumps.forEach(function(allocatorDump){if(allocatorDump.fullName==='tracing')
+return;var allocatorSize=allocatorDump.attributes[DISPLAYED_SIZE_ATTRIBUTE_NAME];if(allocatorSize===undefined)
+return;var allocatorSizeValue=allocatorSize.value;if(allocatorSizeValue===undefined)
+return;allocatorSizes[allocatorDump.fullName]=allocatorSizeValue;});return allocatorSizes;};function getGlobalMemoryDumpAllocatorSizes(globalMemoryDump){var globalAllocatorSizes={};tr.b.iterItems(globalMemoryDump.processMemoryDumps,function(pid,processMemoryDump){addDictionary(globalAllocatorSizes,getProcessMemoryDumpAllocatorSizes(processMemoryDump));});return globalAllocatorSizes;}
+function buildAllocatedMemoryChartSeries(memoryDumps,memoryDumpToAllocatorSizesFn){var allocatorNameToPoints={};var dumpsData=memoryDumps.map(function(memoryDump){var allocatorSizes=memoryDumpToAllocatorSizesFn(memoryDump);tr.b.iterItems(allocatorSizes,function(allocatorName){allocatorNameToPoints[allocatorName]=[];});return{dump:memoryDump,sizes:allocatorSizes};});if(Object.keys(allocatorNameToPoints).length===0)
+return undefined;dumpsData.forEach(function(dumpData){var memoryDump=dumpData.dump;var allocatorSizes=dumpData.sizes;tr.b.iterItems(allocatorNameToPoints,function(allocatorName,points){var allocatorSize=allocatorSizes[allocatorName]||0;points.push(new tr.ui.tracks.ChartPoint(memoryDump,memoryDump.start,allocatorSize));});});var axis=new tr.ui.tracks.ChartAxis(0);var series=[];tr.b.iterItems(allocatorNameToPoints,function(allocatorName,points){var colorId=ColorScheme.getColorIdForGeneralPurposeString(allocatorName);var renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.LINE,colorId:colorId};series.push(new tr.ui.tracks.ChartSeries(points,axis,renderingConfig));});return series;}
+function buildMemoryLetterDots(memoryDumps){var lightMemoryColorId=ColorScheme.getColorIdForReservedName('light_memory_dump');var detailedMemoryColorId=ColorScheme.getColorIdForReservedName('detailed_memory_dump');return memoryDumps.map(function(memoryDump){var memoryColorId;switch(memoryDump.levelOfDetail){case'detailed':memoryColorId=detailedMemoryColorId;break;case'light':default:memoryColorId=lightMemoryColorId;}
+return new tr.ui.tracks.LetterDot(memoryDump,'M',memoryColorId,memoryDump.start);});}
+function buildGlobalUsedMemoryChartSeries(globalMemoryDumps){var containsVmRegions=globalMemoryDumps.some(function(globalDump){for(var pid in globalDump.processMemoryDumps)
+if(globalDump.processMemoryDumps[pid].mostRecentVmRegions)
+return true;return false;});if(!containsVmRegions)
+return undefined;var pidToProcess={};globalMemoryDumps.forEach(function(globalDump){tr.b.iterItems(globalDump.processMemoryDumps,function(pid,processDump){pidToProcess[pid]=processDump.process;});});var pidToPoints={};tr.b.iterItems(pidToProcess,function(pid,process){pidToPoints[pid]=[];});globalMemoryDumps.forEach(function(globalDump){var pssBase=0;tr.b.iterItems(pidToPoints,function(pid,points){var processMemoryDump=globalDump.processMemoryDumps[pid];var pss;if(processMemoryDump===undefined){pss=0;}else{pss=processMemoryDump.getMostRecentTotalVmRegionStat('proportionalResident');if(pss===undefined){pss=0;}}
+var cumulativePss=pssBase+pss;points.push(new tr.ui.tracks.ChartPoint(globalDump,globalDump.start,cumulativePss,pssBase));pssBase=cumulativePss;});});var axis=new tr.ui.tracks.ChartAxis(0);var series=[];tr.b.iterItems(pidToPoints,function(pid,points){var process=pidToProcess[pid];var colorId=ColorScheme.getColorIdForGeneralPurposeString(process.userFriendlyName);var renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:colorId,backgroundOpacity:0.8};series.push(new tr.ui.tracks.ChartSeries(points,axis,renderingConfig));});series.reverse();return series;}
+function buildProcessAllocatedMemoryChartSeries(processMemoryDumps){return buildAllocatedMemoryChartSeries(processMemoryDumps,getProcessMemoryDumpAllocatorSizes);}
+function buildGlobalAllocatedMemoryChartSeries(globalMemoryDumps){return buildAllocatedMemoryChartSeries(globalMemoryDumps,getGlobalMemoryDumpAllocatorSizes);}
+return{buildMemoryLetterDots:buildMemoryLetterDots,buildGlobalUsedMemoryChartSeries:buildGlobalUsedMemoryChartSeries,buildProcessAllocatedMemoryChartSeries:buildProcessAllocatedMemoryChartSeries,buildGlobalAllocatedMemoryChartSeries:buildGlobalAllocatedMemoryChartSeries};});'use strict';tr.exportTo('tr.ui.tracks',function(){var USED_MEMORY_TRACK_HEIGHT=50;var ALLOCATED_MEMORY_TRACK_HEIGHT=50;var GlobalMemoryDumpTrack=tr.ui.b.define('global-memory-dump-track',tr.ui.tracks.ContainerTrack);GlobalMemoryDumpTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.memoryDumps_=undefined;},get memoryDumps(){return this.memoryDumps_;},set memoryDumps(memoryDumps){this.memoryDumps_=memoryDumps;this.updateContents_();},updateContents_:function(){this.clearTracks_();if(!this.memoryDumps_||!this.memoryDumps_.length)
+return;this.appendDumpDotsTrack_();this.appendUsedMemoryTrack_();this.appendAllocatedMemoryTrack_();},appendDumpDotsTrack_:function(){var items=tr.ui.tracks.buildMemoryLetterDots(this.memoryDumps_);if(!items)
+return;var track=new tr.ui.tracks.LetterDotTrack(this.viewport);track.heading='Memory Dumps';track.items=items;this.appendChild(track);},appendUsedMemoryTrack_:function(){var series=tr.ui.tracks.buildGlobalUsedMemoryChartSeries(this.memoryDumps_);if(!series)
+return;var track=new tr.ui.tracks.ChartTrack(this.viewport);track.heading='Memory per process';track.height=USED_MEMORY_TRACK_HEIGHT+'px';track.series=series;track.autoSetAllAxes({expandMax:true});this.appendChild(track);},appendAllocatedMemoryTrack_:function(){var series=tr.ui.tracks.buildGlobalAllocatedMemoryChartSeries(this.memoryDumps_);if(!series)
+return;var track=new tr.ui.tracks.ChartTrack(this.viewport);track.heading='Memory per component';track.height=ALLOCATED_MEMORY_TRACK_HEIGHT+'px';track.series=series;track.autoSetAllAxes({expandMax:true});this.appendChild(track);}};return{GlobalMemoryDumpTrack:GlobalMemoryDumpTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){function Highlighter(viewport){if(viewport===undefined){throw new Error('viewport must be provided');}
+this.viewport_=viewport;};Highlighter.prototype={__proto__:Object.prototype,processModel:function(model){throw new Error('processModel implementation missing');},drawHighlight:function(ctx,dt,viewLWorld,viewRWorld,viewHeight){throw new Error('drawHighlight implementation missing');}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Highlighter;tr.b.decorateExtensionRegistry(Highlighter,options);return{Highlighter:Highlighter};});'use strict';tr.exportTo('tr.ui.tracks',function(){var CounterTrack=tr.ui.b.define('counter-track',tr.ui.tracks.ChartTrack);CounterTrack.prototype={__proto__:tr.ui.tracks.ChartTrack.prototype,decorate:function(viewport){tr.ui.tracks.ChartTrack.prototype.decorate.call(this,viewport);this.classList.add('counter-track');},get counter(){return this.chart;},set counter(counter){this.heading=counter.name+': ';this.series=CounterTrack.buildChartSeriesFromCounter(counter);this.autoSetAllAxes({expandMax:true});},getModelEventFromItem:function(chartValue){return chartValue;}};CounterTrack.buildChartSeriesFromCounter=function(counter){var numSeries=counter.series.length;var totals=counter.totals;var chartAxis=new tr.ui.tracks.ChartAxis(0,undefined);var chartSeries=counter.series.map(function(series,seriesIndex){var chartPoints=series.samples.map(function(sample,sampleIndex){var total=totals[sampleIndex*numSeries+seriesIndex];return new tr.ui.tracks.ChartPoint(sample,sample.timestamp,total);});var renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:series.color};return new tr.ui.tracks.ChartSeries(chartPoints,chartAxis,renderingConfig);});chartSeries.reverse();return chartSeries;};return{CounterTrack:CounterTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var startCompare=function(x,y){return x.start-y.start;}
+var FrameTrack=tr.ui.b.define('frame-track',tr.ui.tracks.LetterDotTrack);FrameTrack.prototype={__proto__:tr.ui.tracks.LetterDotTrack.prototype,decorate:function(viewport){tr.ui.tracks.LetterDotTrack.prototype.decorate.call(this,viewport);this.heading='Frames';this.frames_=undefined;this.items=undefined;},get frames(){return this.frames_;},set frames(frames){this.frames_=frames;if(frames===undefined)
+return;this.frames_=this.frames_.slice();this.frames_.sort(startCompare);this.items=this.frames_.map(function(frame){return new FrameDot(frame);});}};function FrameDot(frame){tr.ui.tracks.LetterDot.call(this,frame,'F',frame.colorId,frame.start);}
+FrameDot.prototype={__proto__:tr.ui.tracks.LetterDot.prototype};return{FrameTrack:FrameTrack};});'use strict';tr.exportTo('tr.model',function(){var Settings=tr.b.Settings;function ModelSettings(model){this.model=model;this.objectsByKey_=[];this.nonuniqueKeys_=[];this.buildObjectsByKeyMap_();this.removeNonuniqueKeysFromSettings_();this.ephemeralSettingsByGUID_={};}
+ModelSettings.prototype={buildObjectsByKeyMap_:function(){var objects=[];this.model.iterateAllPersistableObjects(function(o){objects.push(o);});var objectsByKey={};var NONUNIQUE_KEY='nonuniqueKey';for(var i=0;i<objects.length;i++){var object=objects[i];var objectKey=object.getSettingsKey();if(!objectKey)
+continue;if(objectsByKey[objectKey]===undefined){objectsByKey[objectKey]=object;continue;}
+objectsByKey[objectKey]=NONUNIQUE_KEY;}
+var nonuniqueKeys={};tr.b.dictionaryKeys(objectsByKey).forEach(function(objectKey){if(objectsByKey[objectKey]!==NONUNIQUE_KEY)
+return;delete objectsByKey[objectKey];nonuniqueKeys[objectKey]=true;});this.nonuniqueKeys=nonuniqueKeys;this.objectsByKey_=objectsByKey;},removeNonuniqueKeysFromSettings_:function(){var settings=Settings.get('trace_model_settings',{});var settingsChanged=false;tr.b.dictionaryKeys(settings).forEach(function(objectKey){if(!this.nonuniqueKeys[objectKey])
+return;settingsChanged=true;delete settings[objectKey];},this);if(settingsChanged)
+Settings.set('trace_model_settings',settings);},hasUniqueSettingKey:function(object){var objectKey=object.getSettingsKey();if(!objectKey)
+return false;return this.objectsByKey_[objectKey]!==undefined;},getSettingFor:function(object,objectLevelKey,defaultValue){var objectKey=object.getSettingsKey();if(!objectKey||!this.objectsByKey_[objectKey]){var settings=this.getEphemeralSettingsFor_(object);var ephemeralValue=settings[objectLevelKey];if(ephemeralValue!==undefined)
+return ephemeralValue;return defaultValue;}
+var settings=Settings.get('trace_model_settings',{});if(!settings[objectKey])
+settings[objectKey]={};var value=settings[objectKey][objectLevelKey];if(value!==undefined)
+return value;return defaultValue;},setSettingFor:function(object,objectLevelKey,value){var objectKey=object.getSettingsKey();if(!objectKey||!this.objectsByKey_[objectKey]){this.getEphemeralSettingsFor_(object)[objectLevelKey]=value;return;}
+var settings=Settings.get('trace_model_settings',{});if(!settings[objectKey])
+settings[objectKey]={};if(settings[objectKey][objectLevelKey]===value)
+return;settings[objectKey][objectLevelKey]=value;Settings.set('trace_model_settings',settings);},getEphemeralSettingsFor_:function(object){if(object.guid===undefined)
+throw new Error('Only objects with GUIDs can be persisted');if(this.ephemeralSettingsByGUID_[object.guid]===undefined)
+this.ephemeralSettingsByGUID_[object.guid]={};return this.ephemeralSettingsByGUID_[object.guid];}};return{ModelSettings:ModelSettings};});'use strict';tr.exportTo('tr.ui.tracks',function(){var MultiRowTrack=tr.ui.b.define('multi-row-track',tr.ui.tracks.ContainerTrack);MultiRowTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.tooltip_='';this.heading_='';this.groupingSource_=undefined;this.itemsToGroup_=undefined;this.defaultToCollapsedWhenSubRowCountMoreThan=1;this.itemsGroupedOnLastUpdateContents_=undefined;this.currentSubRows_=[];this.expanded_=true;},get itemsToGroup(){return this.itemsToGroup_;},setItemsToGroup:function(itemsToGroup,opt_groupingSource){this.itemsToGroup_=itemsToGroup;this.groupingSource_=opt_groupingSource;this.updateContents_();this.updateExpandedStateFromGroupingSource_();},get heading(){return this.heading_;},set heading(h){this.heading_=h;this.updateContents_();},get tooltip(){return this.tooltip_;},set tooltip(t){this.tooltip_=t;this.updateContents_();},get subRows(){return this.currentSubRows_;},get hasVisibleContent(){return this.children.length>0;},get expanded(){return this.expanded_;},set expanded(expanded){if(this.expanded_==expanded)
+return;this.expanded_=expanded;this.expandedStateChanged_();},onHeadingClicked_:function(e){if(this.subRows.length<=1)
+return;this.expanded=!this.expanded;if(this.groupingSource_){var modelSettings=new tr.model.ModelSettings(this.groupingSource_.model);modelSettings.setSettingFor(this.groupingSource_,'expanded',this.expanded);}
+e.stopPropagation();},updateExpandedStateFromGroupingSource_:function(){if(this.groupingSource_){var numSubRows=this.subRows.length;var modelSettings=new tr.model.ModelSettings(this.groupingSource_.model);if(numSubRows>1){var defaultExpanded;if(numSubRows>this.defaultToCollapsedWhenSubRowCountMoreThan){defaultExpanded=false;}else{defaultExpanded=true;}
+this.expanded=modelSettings.getSettingFor(this.groupingSource_,'expanded',defaultExpanded);}else{this.expanded=undefined;}}},expandedStateChanged_:function(){var minH=Math.max(2,Math.ceil(18/this.children.length));var h=(this.expanded_?18:minH)+'px';for(var i=0;i<this.children.length;i++){this.children[i].height=h;if(i===0)
+this.children[i].arrowVisible=true;this.children[i].expanded=this.expanded;}
+if(this.children.length===1){this.children[0].expanded=true;this.children[0].arrowVisible=false;}},updateContents_:function(){tr.ui.tracks.ContainerTrack.prototype.updateContents_.call(this);if(!this.itemsToGroup_){this.updateHeadingAndTooltip_();this.currentSubRows_=[];return;}
+if(this.areArrayContentsSame_(this.itemsGroupedOnLastUpdateContents_,this.itemsToGroup_)){this.updateHeadingAndTooltip_();return;}
+this.itemsGroupedOnLastUpdateContents_=this.itemsToGroup_;this.detach();if(!this.itemsToGroup_.length){this.currentSubRows_=[];return;}
+var subRows=this.buildSubRows_(this.itemsToGroup_);this.currentSubRows_=subRows;for(var srI=0;srI<subRows.length;srI++){var subRow=subRows[srI];if(!subRow.length)
+continue;var track=this.addSubTrack_(subRow);track.addEventListener('heading-clicked',this.onHeadingClicked_.bind(this));}
+this.updateHeadingAndTooltip_();this.expandedStateChanged_();},updateHeadingAndTooltip_:function(){if(!this.firstChild)
+return;this.firstChild.heading=this.heading_;this.firstChild.tooltip=this.tooltip_;},buildSubRows_:function(itemsToGroup){throw new Error('Not implemented');},addSubTrack_:function(subRowItems){throw new Error('Not implemented');},areArrayContentsSame_:function(a,b){if(!a||!b)
+return false;if(!a.length||!b.length)
+return false;if(a.length!=b.length)
+return false;for(var i=0;i<a.length;++i){if(a[i]!=b[i])
+return false;}
+return true;}};return{MultiRowTrack:MultiRowTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SelectionState=tr.model.SelectionState;var EventPresenter=tr.ui.b.EventPresenter;var ObjectInstanceTrack=tr.ui.b.define('object-instance-track',tr.ui.tracks.Track);ObjectInstanceTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('object-instance-track');this.objectInstances_=[];this.objectSnapshots_=[];this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},get objectInstances(){return this.objectInstances_;},set objectInstances(objectInstances){if(!objectInstances||objectInstances.length==0){this.heading='';this.objectInstances_=[];this.objectSnapshots_=[];return;}
+this.heading=objectInstances[0].typeName;this.objectInstances_=objectInstances;this.objectSnapshots_=[];this.objectInstances_.forEach(function(instance){this.objectSnapshots_.push.apply(this.objectSnapshots_,instance.snapshots);},this);this.objectSnapshots_.sort(function(a,b){return a.ts-b.ts;});},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},get snapshotRadiusView(){return 7*(window.devicePixelRatio||1);},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawLetterDots_(viewLWorld,viewRWorld);break;}},drawLetterDots_:function(viewLWorld,viewRWorld){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var height=bounds.height*pixelRatio;var halfHeight=height*0.5;var twoPi=Math.PI*2;var dt=this.viewport.currentDisplayTransform;var snapshotRadiusView=this.snapshotRadiusView;var snapshotRadiusWorld=dt.xViewVectorToWorld(height);var loI;ctx.save();dt.applyTransformToCanvas(ctx);var objectInstances=this.objectInstances_;var loI=tr.b.findLowIndexInSortedArray(objectInstances,function(instance){return instance.deletionTs;},viewLWorld);ctx.strokeStyle='rgb(0,0,0)';for(var i=loI;i<objectInstances.length;++i){var instance=objectInstances[i];var x=instance.creationTs;if(x>viewRWorld)
+break;var right=instance.deletionTs==Number.MAX_VALUE?viewRWorld:instance.deletionTs;ctx.fillStyle=EventPresenter.getObjectInstanceColor(instance);ctx.fillRect(x,pixelRatio,right-x,height-2*pixelRatio);}
+ctx.restore();var objectSnapshots=this.objectSnapshots_;loI=tr.b.findLowIndexInSortedArray(objectSnapshots,function(snapshot){return snapshot.ts+snapshotRadiusWorld;},viewLWorld);for(var i=loI;i<objectSnapshots.length;++i){var snapshot=objectSnapshots[i];var x=snapshot.ts;if(x-snapshotRadiusWorld>viewRWorld)
+break;var xView=dt.xWorldToView(x);ctx.fillStyle=EventPresenter.getObjectSnapshotColor(snapshot);ctx.beginPath();ctx.arc(xView,halfHeight,snapshotRadiusView,0,twoPi);ctx.fill();if(snapshot.selected){ctx.lineWidth=5;ctx.strokeStyle='rgb(100,100,0)';ctx.stroke();ctx.beginPath();ctx.arc(xView,halfHeight,snapshotRadiusView-1,0,twoPi);ctx.lineWidth=2;ctx.strokeStyle='rgb(255,255,0)';ctx.stroke();}else{ctx.lineWidth=1;ctx.strokeStyle='rgb(0,0,0)';ctx.stroke();}}
+ctx.lineWidth=1;var selectionState=SelectionState.NONE;if(objectInstances.length&&objectInstances[0].selectionState===SelectionState.DIMMED){selectionState=SelectionState.DIMMED;}
+if(selectionState===SelectionState.DIMMED){var width=bounds.width*pixelRatio;ctx.fillStyle='rgba(255,255,255,0.5)';ctx.fillRect(0,0,width,height);ctx.restore();}},addEventsToTrackMap:function(eventToTrackMap){if(this.objectInstance_!==undefined){this.objectInstance_.forEach(function(obj){eventToTrackMap.addEvent(obj,this);},this);}
+if(this.objectSnapshots_!==undefined){this.objectSnapshots_.forEach(function(obj){eventToTrackMap.addEvent(obj,this);},this);}},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){var foundSnapshot=false;function onSnapshot(snapshot){selection.push(snapshot);foundSnapshot=true;}
+var snapshotRadiusView=this.snapshotRadiusView;var snapshotRadiusWorld=viewPixWidthWorld*snapshotRadiusView;tr.b.iterateOverIntersectingIntervals(this.objectSnapshots_,function(x){return x.ts-snapshotRadiusWorld;},function(x){return 2*snapshotRadiusWorld;},loWX,hiWX,onSnapshot);if(foundSnapshot)
+return;tr.b.iterateOverIntersectingIntervals(this.objectInstances_,function(x){return x.creationTs;},function(x){return x.deletionTs-x.creationTs;},loWX,hiWX,selection.push.bind(selection));},addEventNearToProvidedEventToSelection:function(event,offset,selection){var events;if(event instanceof tr.model.ObjectSnapshot)
+events=this.objectSnapshots_;else if(event instanceof tr.model.ObjectInstance)
+events=this.objectInstances_;else
+throw new Error('Unrecognized event');var index=events.indexOf(event);var newIndex=index+offset;if(newIndex>=0&&newIndex<events.length){selection.push(events[newIndex]);return true;}
+return false;},addAllEventsMatchingFilterToSelection:function(filter,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){var snapshot=tr.b.findClosestElementInSortedArray(this.objectSnapshots_,function(x){return x.ts;},worldX,worldMaxDist);if(!snapshot)
+return;selection.push(snapshot);}};var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);tr.b.decorateExtensionRegistry(ObjectInstanceTrack,options);return{ObjectInstanceTrack:ObjectInstanceTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ObjectInstanceGroupTrack=tr.ui.b.define('object-instance-group-track',tr.ui.tracks.MultiRowTrack);ObjectInstanceGroupTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate:function(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);this.classList.add('object-instance-group-track');this.objectInstances_=undefined;},get objectInstances(){return this.itemsToGroup;},set objectInstances(objectInstances){this.setItemsToGroup(objectInstances);},addSubTrack_:function(objectInstances){var hasMultipleRows=this.subRows.length>1;var track=new tr.ui.tracks.ObjectInstanceTrack(this.viewport);track.objectInstances=objectInstances;this.appendChild(track);return track;},buildSubRows_:function(objectInstances){objectInstances.sort(function(x,y){return x.creationTs-y.creationTs;});var subRows=[];for(var i=0;i<objectInstances.length;i++){var objectInstance=objectInstances[i];var found=false;for(var j=0;j<subRows.length;j++){var subRow=subRows[j];var lastItemInSubRow=subRow[subRow.length-1];if(objectInstance.creationTs>=lastItemInSubRow.deletionTs){found=true;subRow.push(objectInstance);break;}}
+if(!found){var subRow=[objectInstance];subRows.push(subRow);}}
+return subRows;},updateHeadingAndTooltip_:function(){}};return{ObjectInstanceGroupTrack:ObjectInstanceGroupTrack};});'use strict';tr.exportTo('tr.ui.b',function(){function FastRectRenderer(ctx,minRectSize,maxMergeDist,pallette){this.ctx_=ctx;this.minRectSize_=minRectSize;this.maxMergeDist_=maxMergeDist;this.pallette_=pallette;}
+FastRectRenderer.prototype={y_:0,h_:0,merging_:false,mergeStartX_:0,mergeCurRight_:0,mergedColorId_:0,mergedAlpha_:0,setYandH:function(y,h){if(this.y_===y&&this.h_===h)
+return;this.flush();this.y_=y;this.h_=h;},fillRect:function(x,w,colorId,alpha){var r=x+w;if(w<this.minRectSize_){if(r-this.mergeStartX_>this.maxMergeDist_)
+this.flush();if(!this.merging_){this.merging_=true;this.mergeStartX_=x;this.mergeCurRight_=r;this.mergedColorId_=colorId;this.mergedAlpha_=alpha;}else{this.mergeCurRight_=r;if(this.mergedAlpha_<alpha||(this.mergedAlpha_===alpha&&this.mergedColorId_<colorId)){this.mergedAlpha_=alpha;this.mergedColorId_=colorId;}}}else{if(this.merging_)
+this.flush();this.ctx_.fillStyle=this.pallette_[colorId];this.ctx_.globalAlpha=alpha;this.ctx_.fillRect(x,this.y_,w,this.h_);}},flush:function(){if(this.merging_){this.ctx_.fillStyle=this.pallette_[this.mergedColorId_];this.ctx_.globalAlpha=this.mergedAlpha_;this.ctx_.fillRect(this.mergeStartX_,this.y_,this.mergeCurRight_-this.mergeStartX_,this.h_);this.merging_=false;}}};return{FastRectRenderer:FastRectRenderer};});'use strict';tr.exportTo('tr.ui.tracks',function(){var RectTrack=tr.ui.b.define('rect-track',tr.ui.tracks.Track);RectTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('rect-track');this.asyncStyle_=false;this.rects_=null;this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},set selectionGenerator(generator){this.heading_.selectionGenerator=generator;},set expanded(expanded){this.heading_.expanded=!!expanded;},set arrowVisible(arrowVisible){this.heading_.arrowVisible=!!arrowVisible;},get expanded(){return this.heading_.expanded;},get asyncStyle(){return this.asyncStyle_;},set asyncStyle(v){this.asyncStyle_=!!v;},get rects(){return this.rects_;},set rects(rects){this.rects_=rects||[];this.invalidateDrawingContainer();},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;this.invalidateDrawingContainer();},get hasVisibleContent(){return this.rects_.length>0;},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawRects_(viewLWorld,viewRWorld);break;}},drawRects_:function(viewLWorld,viewRWorld){var ctx=this.context();ctx.save();var bounds=this.getBoundingClientRect();tr.ui.b.drawSlices(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,bounds.height,this.rects_,this.asyncStyle_);ctx.restore();if(bounds.height<=6)
+return;var fontSize,yOffset;if(bounds.height<15){fontSize=6;yOffset=1.0;}else{fontSize=10;yOffset=2.5;}
+tr.ui.b.drawLabels(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,this.rects_,this.asyncStyle_,fontSize,yOffset);},addEventsToTrackMap:function(eventToTrackMap){if(this.rects_===undefined||this.rects_===null)
+return;this.rects_.forEach(function(rect){rect.addToTrackMap(eventToTrackMap,this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){function onRect(rect){rect.addToSelection(selection);}
+onRect=onRect.bind(this);var instantEventWidth=2*viewPixWidthWorld;tr.b.iterateOverIntersectingIntervals(this.rects_,function(x){return x.start;},function(x){return x.duration==0?x.duration+instantEventWidth:x.duration;},loWX,hiWX,onRect);},addEventNearToProvidedEventToSelection:function(event,offset,selection){var index=tr.b.findFirstIndexInArray(this.rects_,function(rect){return rect.modelItem===event;});if(index===-1)
+return false;var newIndex=index+offset;if(newIndex<0||newIndex>=this.rects_.length)
+return false;this.rects_[newIndex].addToSelection(selection);return true;},addAllEventsMatchingFilterToSelection:function(filter,selection){for(var i=0;i<this.rects_.length;++i){var modelItem=this.rects_[i].modelItem;if(!modelItem)
+continue;if(filter.matchSlice(modelItem))
+selection.push(modelItem);}},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){var rect=tr.b.findClosestIntervalInSortedIntervals(this.rects_,function(x){return x.start;},function(x){return x.end;},worldX,worldMaxDist);if(!rect)
+return;rect.addToSelection(selection);}};function Rect(modelItem,title,colorId,start,duration){tr.model.ProxySelectableItem.call(this,modelItem);this.title=title;this.colorId=colorId;this.start=start;this.duration=duration;this.end=start+duration;};Rect.prototype={__proto__:tr.model.ProxySelectableItem.prototype};return{RectTrack:RectTrack,Rect:Rect};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ColorScheme=tr.b.ColorScheme;var ProcessSummaryTrack=tr.ui.b.define('process-summary-track',tr.ui.tracks.RectTrack);ProcessSummaryTrack.buildRectsFromProcess=function(process){if(!process)
+return[];var ops=[];var pushOp=function(isStart,time,slice){ops.push({isStart:isStart,time:time,slice:slice});};for(var tid in process.threads){var sliceGroup=process.threads[tid].sliceGroup;sliceGroup.topLevelSlices.forEach(function(slice){pushOp(true,slice.start,undefined);pushOp(false,slice.end,undefined);});sliceGroup.slices.forEach(function(slice){if(slice.important){pushOp(true,slice.start,slice);pushOp(false,slice.end,slice);}});}
+ops.sort(function(a,b){return a.time-b.time;});var rects=[];var genericColorId=ColorScheme.getColorIdForReservedName('generic_work');var pushRect=function(start,end,slice){rects.push(new tr.ui.tracks.Rect(slice,slice?slice.title:'',slice?slice.colorId:genericColorId,start,end-start));}
+var depth=0;var currentSlice=undefined;var lastStart=undefined;ops.forEach(function(op){depth+=op.isStart?1:-1;if(currentSlice){if(!op.isStart&&op.slice==currentSlice){pushRect(lastStart,op.time,currentSlice);lastStart=depth>=1?op.time:undefined;currentSlice=undefined;}}else{if(op.isStart){if(depth==1){lastStart=op.time;currentSlice=op.slice;}else if(op.slice){if(op.time!=lastStart){pushRect(lastStart,op.time,undefined);lastStart=op.time;}
+currentSlice=op.slice;}}else{if(depth==0){pushRect(lastStart,op.time,undefined);lastStart=undefined;}}}});return rects;};ProcessSummaryTrack.prototype={__proto__:tr.ui.tracks.RectTrack.prototype,decorate:function(viewport){tr.ui.tracks.RectTrack.prototype.decorate.call(this,viewport);},get process(){return this.process_;},set process(process){this.process_=process;this.rects=ProcessSummaryTrack.buildRectsFromProcess(process);}};return{ProcessSummaryTrack:ProcessSummaryTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SliceTrack=tr.ui.b.define('slice-track',tr.ui.tracks.RectTrack);SliceTrack.prototype={__proto__:tr.ui.tracks.RectTrack.prototype,decorate:function(viewport){tr.ui.tracks.RectTrack.prototype.decorate.call(this,viewport);},get slices(){return this.rects;},set slices(slices){this.rects=slices;}};return{SliceTrack:SliceTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var AsyncSliceGroupTrack=tr.ui.b.define('async-slice-group-track',tr.ui.tracks.MultiRowTrack);AsyncSliceGroupTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate:function(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);this.classList.add('async-slice-group-track');this.group_=undefined;},addSubTrack_:function(slices){var track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;this.appendChild(track);track.asyncStyle=true;return track;},get group(){return this.group_;},set group(group){this.group_=group;this.setItemsToGroup(this.group_.slices,this.group_);},get eventContainer(){return this.group;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.MultiRowTrack.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.group,this);},buildSubRows_:function(slices,opt_skipSort){if(!opt_skipSort){slices.sort(function(x,y){return x.start-y.start;});}
+var findLevel=function(sliceToPut,rows,n){if(n>=rows.length)
+return true;var subRow=rows[n];var lastSliceInSubRow=subRow[subRow.length-1];if(sliceToPut.start>=lastSliceInSubRow.end){if(sliceToPut.subSlices===undefined||sliceToPut.subSlices.length===0){return true;}
+for(var i=0;i<sliceToPut.subSlices.length;i++){if(!findLevel(sliceToPut.subSlices[i],rows,n+1))
+return false;}
+return true;}
+return false;}
+var subRows=[];for(var i=0;i<slices.length;i++){var slice=slices[i];var found=false;var index=subRows.length;for(var j=0;j<subRows.length;j++){if(findLevel(slice,subRows,j)){found=true;index=j;break;}}
+if(!found)
+subRows.push([]);subRows[index].push(slice);var fitSubSlicesRecursively=function(subSlices,level,rows){if(subSlices===undefined||subSlices.length===0)
+return;if(level===rows.length)
+rows.push([]);for(var h=0;h<subSlices.length;h++){rows[level].push(subSlices[h]);fitSubSlicesRecursively(subSlices[h].subSlices,level+1,rows);}}
+fitSubSlicesRecursively(slice.subSlices,index+1,subRows);}
+return subRows;}};return{AsyncSliceGroupTrack:AsyncSliceGroupTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SampleTrack=tr.ui.b.define('sample-track',tr.ui.tracks.RectTrack);SampleTrack.prototype={__proto__:tr.ui.tracks.RectTrack.prototype,decorate:function(viewport){tr.ui.tracks.RectTrack.prototype.decorate.call(this,viewport);},get samples(){return this.rects;},set samples(samples){this.rects=samples;}};return{SampleTrack:SampleTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SliceGroupTrack=tr.ui.b.define('slice-group-track',tr.ui.tracks.MultiRowTrack);SliceGroupTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate:function(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);this.classList.add('slice-group-track');this.group_=undefined;this.defaultToCollapsedWhenSubRowCountMoreThan=100;},addSubTrack_:function(slices){var track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;this.appendChild(track);return track;},get group(){return this.group_;},set group(group){this.group_=group;this.setItemsToGroup(this.group_.slices,this.group_);},get eventContainer(){return this.group;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.MultiRowTrack.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.group,this);},buildSubRows_:function(slices){var precisionUnit=this.group.model.intrinsicTimeUnit;if(!slices.length)
+return[];var ops=[];for(var i=0;i<slices.length;i++){if(slices[i].subSlices)
+slices[i].subSlices.splice(0,slices[i].subSlices.length);ops.push(i);}
+ops.sort(function(ix,iy){var x=slices[ix];var y=slices[iy];if(x.start!=y.start)
+return x.start-y.start;return ix-iy;});var subRows=[[]];this.badSlices_=[];for(var i=0;i<ops.length;i++){var op=ops[i];var slice=slices[op];var inserted=false;for(var j=subRows.length-1;j>=0;j--){if(subRows[j].length==0)
+continue;var insertedSlice=subRows[j][subRows[j].length-1];if(slice.start<insertedSlice.start){this.badSlices_.push(slice);inserted=true;}
+if(insertedSlice.bounds(slice,precisionUnit)){while(subRows.length<=j+1)
+subRows.push([]);subRows[j+1].push(slice);if(insertedSlice.subSlices)
+insertedSlice.subSlices.push(slice);inserted=true;break;}}
+if(inserted)
+continue;subRows[0].push(slice);}
+return subRows;}};return{SliceGroupTrack:SliceGroupTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ThreadTrack=tr.ui.b.define('thread-track',tr.ui.tracks.ContainerTrack);ThreadTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.classList.add('thread-track');},get thread(){return this.thread_;},set thread(thread){this.thread_=thread;this.updateContents_();},get hasVisibleContent(){return this.tracks_.length>0;},get eventContainer(){return this.thread;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.ContainerTrack.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.thread,this);},updateContents_:function(){this.detach();if(!this.thread_)
+return;this.heading=this.thread_.userFriendlyName+': ';this.tooltip=this.thread_.userFriendlyDetails;if(this.thread_.asyncSliceGroup.length)
+this.appendAsyncSliceTracks_();this.appendThreadSamplesTracks_();if(this.thread_.timeSlices){var timeSlicesTrack=new tr.ui.tracks.SliceTrack(this.viewport);timeSlicesTrack.heading='';timeSlicesTrack.height=tr.ui.b.THIN_SLICE_HEIGHT+'px';timeSlicesTrack.slices=this.thread_.timeSlices;if(timeSlicesTrack.hasVisibleContent)
+this.appendChild(timeSlicesTrack);}
+if(this.thread_.sliceGroup.length){var track=new tr.ui.tracks.SliceGroupTrack(this.viewport);track.heading=this.thread_.userFriendlyName;track.tooltip=this.thread_.userFriendlyDetails;track.group=this.thread_.sliceGroup;if(track.hasVisibleContent)
+this.appendChild(track);}},appendAsyncSliceTracks_:function(){var subGroups=this.thread_.asyncSliceGroup.viewSubGroups;subGroups.forEach(function(subGroup){var asyncTrack=new tr.ui.tracks.AsyncSliceGroupTrack(this.viewport);var title=subGroup.slices[0].viewSubGroupTitle;asyncTrack.group=subGroup;asyncTrack.heading=title;if(asyncTrack.hasVisibleContent)
+this.appendChild(asyncTrack);},this);},appendThreadSamplesTracks_:function(){var threadSamples=this.thread_.samples;if(threadSamples===undefined||threadSamples.length===0)
+return;var samplesByTitle={};threadSamples.forEach(function(sample){if(samplesByTitle[sample.title]===undefined)
+samplesByTitle[sample.title]=[];samplesByTitle[sample.title].push(sample);});var sampleTitles=tr.b.dictionaryKeys(samplesByTitle);sampleTitles.sort();sampleTitles.forEach(function(sampleTitle){var samples=samplesByTitle[sampleTitle];var samplesTrack=new tr.ui.tracks.SampleTrack(this.viewport);samplesTrack.group=this.thread_;samplesTrack.samples=samples;samplesTrack.heading=this.thread_.userFriendlyName+': '+
+sampleTitle;samplesTrack.tooltip=this.thread_.userFriendlyDetails;samplesTrack.selectionGenerator=function(){var selection=new tr.model.EventSet();for(var i=0;i<samplesTrack.samples.length;i++){selection.push(samplesTrack.samples[i]);}
+return selection;};this.appendChild(samplesTrack);},this);},collapsedDidChange:function(collapsed){if(collapsed){var h=parseInt(this.tracks[0].height);for(var i=0;i<this.tracks.length;++i){if(h>2){this.tracks[i].height=Math.floor(h)+'px';}else{this.tracks[i].style.display='none';}
+h=h*0.5;}}else{for(var i=0;i<this.tracks.length;++i){this.tracks[i].height=this.tracks[0].height;this.tracks[i].style.display='';}}}};return{ThreadTrack:ThreadTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ObjectSnapshotView=tr.ui.analysis.ObjectSnapshotView;var ObjectInstanceView=tr.ui.analysis.ObjectInstanceView;var SpacingTrack=tr.ui.tracks.SpacingTrack;var ProcessTrackBase=tr.ui.b.define('process-track-base',tr.ui.tracks.ContainerTrack);ProcessTrackBase.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.processBase_=undefined;this.classList.add('process-track-base');this.classList.add('expanded');this.processNameEl_=tr.ui.b.createSpan();this.processNameEl_.classList.add('process-track-name');this.headerEl_=tr.ui.b.createDiv({className:'process-track-header'});this.headerEl_.appendChild(this.processNameEl_);this.headerEl_.addEventListener('click',this.onHeaderClick_.bind(this));this.appendChild(this.headerEl_);},get processBase(){return this.processBase_;},set processBase(processBase){this.processBase_=processBase;if(this.processBase_){var modelSettings=new tr.model.ModelSettings(this.processBase_.model);var defaultValue=this.processBase_.important;this.expanded=modelSettings.getSettingFor(this.processBase_,'expanded',defaultValue);}
+this.updateContents_();},get expanded(){return this.classList.contains('expanded');},set expanded(expanded){expanded=!!expanded;if(this.expanded===expanded)
+return;this.classList.toggle('expanded');this.viewport_.dispatchChangeEvent();if(!this.processBase_)
+return;var modelSettings=new tr.model.ModelSettings(this.processBase_.model);modelSettings.setSettingFor(this.processBase_,'expanded',expanded);this.updateContents_();this.viewport.rebuildEventToTrackMap();this.viewport.rebuildContainerToTrackMap();},get hasVisibleContent(){if(this.expanded)
+return this.children.length>1;return true;},onHeaderClick_:function(e){e.stopPropagation();e.preventDefault();this.expanded=!this.expanded;},updateContents_:function(){this.clearTracks_();if(!this.processBase_)
+return;this.processNameEl_.textContent=this.processBase_.userFriendlyName;this.headerEl_.title=this.processBase_.userFriendlyDetails;this.willAppendTracks_();if(this.expanded){this.appendMemoryDumpTrack_();this.appendObjectInstanceTracks_();this.appendCounterTracks_();this.appendFrameTrack_();this.appendThreadTracks_();}else{this.appendSummaryTrack_();}
+this.didAppendTracks_();},addEventsToTrackMap:function(eventToTrackMap){this.tracks_.forEach(function(track){track.addEventsToTrackMap(eventToTrackMap);});},willAppendTracks_:function(){},didAppendTracks_:function(){},appendMemoryDumpTrack_:function(){},appendSummaryTrack_:function(){var track=new tr.ui.tracks.ProcessSummaryTrack(this.viewport);track.process=this.process;if(!track.hasVisibleContent)
+return;this.appendChild(track);},appendFrameTrack_:function(){var frames=this.process?this.process.frames:undefined;if(!frames||!frames.length)
+return;var track=new tr.ui.tracks.FrameTrack(this.viewport);track.frames=frames;this.appendChild(track);this.backgroundProvider=track;},appendObjectInstanceTracks_:function(){var instancesByTypeName=this.processBase_.objects.getAllInstancesByTypeName();var instanceTypeNames=tr.b.dictionaryKeys(instancesByTypeName);instanceTypeNames.sort();var didAppendAtLeastOneTrack=false;instanceTypeNames.forEach(function(typeName){var allInstances=instancesByTypeName[typeName];var instanceViewInfo=ObjectInstanceView.getTypeInfo(undefined,typeName);var snapshotViewInfo=ObjectSnapshotView.getTypeInfo(undefined,typeName);if(instanceViewInfo&&!instanceViewInfo.metadata.showInTrackView)
+instanceViewInfo=undefined;if(snapshotViewInfo&&!snapshotViewInfo.metadata.showInTrackView)
+snapshotViewInfo=undefined;var hasViewInfo=instanceViewInfo||snapshotViewInfo;var visibleInstances=[];for(var i=0;i<allInstances.length;i++){var instance=allInstances[i];if(instance.snapshots.length===0)
+continue;if(instance.hasImplicitSnapshots&&!hasViewInfo)
+continue;visibleInstances.push(instance);}
+if(visibleInstances.length===0)
+return;var trackConstructor=tr.ui.tracks.ObjectInstanceTrack.getConstructor(undefined,typeName);if(!trackConstructor){var snapshotViewInfo=ObjectSnapshotView.getTypeInfo(undefined,typeName);if(snapshotViewInfo&&snapshotViewInfo.metadata.showInstances){trackConstructor=tr.ui.tracks.ObjectInstanceGroupTrack;}else{trackConstructor=tr.ui.tracks.ObjectInstanceTrack;}}
+var track=new trackConstructor(this.viewport);track.objectInstances=visibleInstances;this.appendChild(track);didAppendAtLeastOneTrack=true;},this);if(didAppendAtLeastOneTrack)
+this.appendChild(new SpacingTrack(this.viewport));},appendCounterTracks_:function(){var counters=tr.b.dictionaryValues(this.processBase.counters);counters.sort(tr.model.Counter.compare);counters.forEach(function(counter){var track=new tr.ui.tracks.CounterTrack(this.viewport);track.counter=counter;this.appendChild(track);this.appendChild(new SpacingTrack(this.viewport));}.bind(this));},appendThreadTracks_:function(){var threads=tr.b.dictionaryValues(this.processBase.threads);threads.sort(tr.model.Thread.compare);threads.forEach(function(thread){var track=new tr.ui.tracks.ThreadTrack(this.viewport);track.thread=thread;if(!track.hasVisibleContent)
+return;this.appendChild(track);this.appendChild(new SpacingTrack(this.viewport));}.bind(this));}};return{ProcessTrackBase:ProcessTrackBase};});'use strict';tr.exportTo('tr.ui.tracks',function(){var CpuTrack=tr.ui.b.define('cpu-track',tr.ui.tracks.ContainerTrack);CpuTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.classList.add('cpu-track');this.detailedMode_=true;},get cpu(){return this.cpu_;},set cpu(cpu){this.cpu_=cpu;this.updateContents_();},get detailedMode(){return this.detailedMode_;},set detailedMode(detailedMode){this.detailedMode_=detailedMode;this.updateContents_();},get tooltip(){return this.tooltip_;},set tooltip(value){this.tooltip_=value;this.updateContents_();},get hasVisibleContent(){if(this.cpu_===undefined)
+return false;var cpu=this.cpu_;if(cpu.slices.length)
+return true;if(cpu.samples&&cpu.samples.length)
+return true;if(tr.b.dictionaryLength(cpu.counters)>0)
+return true;return false;},updateContents_:function(){this.detach();if(!this.cpu_)
+return;var slices=this.cpu_.slices;if(slices.length){var track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;track.heading=this.cpu_.userFriendlyName+':';this.appendChild(track);}
+if(this.detailedMode_){this.appendSamplesTracks_();for(var counterName in this.cpu_.counters){var counter=this.cpu_.counters[counterName];track=new tr.ui.tracks.CounterTrack(this.viewport);track.heading=this.cpu_.userFriendlyName+' '+
+counter.name+':';track.counter=counter;this.appendChild(track);}}},appendSamplesTracks_:function(){var samples=this.cpu_.samples;if(samples===undefined||samples.length===0)
+return;var samplesByTitle={};samples.forEach(function(sample){if(samplesByTitle[sample.title]===undefined)
+samplesByTitle[sample.title]=[];samplesByTitle[sample.title].push(sample);});var sampleTitles=tr.b.dictionaryKeys(samplesByTitle);sampleTitles.sort();sampleTitles.forEach(function(sampleTitle){var samples=samplesByTitle[sampleTitle];var samplesTrack=new tr.ui.tracks.SliceTrack(this.viewport);samplesTrack.group=this.cpu_;samplesTrack.slices=samples;samplesTrack.heading=this.cpu_.userFriendlyName+': '+
+sampleTitle;samplesTrack.tooltip=this.cpu_.userFriendlyDetails;samplesTrack.selectionGenerator=function(){var selection=new tr.model.EventSet();for(var i=0;i<samplesTrack.slices.length;i++){selection.push(samplesTrack.slices[i]);}
+return selection;};this.appendChild(samplesTrack);},this);}};return{CpuTrack:CpuTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var Cpu=tr.model.Cpu;var CpuTrack=tr.ui.tracks.cpu_track;var ProcessTrackBase=tr.ui.tracks.ProcessTrackBase;var SpacingTrack=tr.ui.tracks.SpacingTrack;var KernelTrack=tr.ui.b.define('kernel-track',ProcessTrackBase);KernelTrack.prototype={__proto__:ProcessTrackBase.prototype,decorate:function(viewport){ProcessTrackBase.prototype.decorate.call(this,viewport);},set kernel(kernel){this.processBase=kernel;},get kernel(){return this.processBase;},get eventContainer(){return this.kernel;},get hasVisibleContent(){return this.children.length>1;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.ProcessTrackBase.prototype.addContainersToTrackMap.call(this,containerToTrackMap);containerToTrackMap.addContainer(this.kernel,this);},willAppendTracks_:function(){var cpus=tr.b.dictionaryValues(this.kernel.cpus);cpus.sort(tr.model.Cpu.compare);var didAppendAtLeastOneTrack=false;for(var i=0;i<cpus.length;++i){var cpu=cpus[i];var track=new tr.ui.tracks.CpuTrack(this.viewport);track.detailedMode=this.expanded;track.cpu=cpu;if(!track.hasVisibleContent)
+continue;this.appendChild(track);didAppendAtLeastOneTrack=true;}
+if(didAppendAtLeastOneTrack)
+this.appendChild(new SpacingTrack(this.viewport));}};return{KernelTrack:KernelTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var InteractionTrack=tr.ui.b.define('interaction-track',tr.ui.tracks.MultiRowTrack);InteractionTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate:function(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);this.heading='Interactions';this.subRows_=[];},set model(model){this.setItemsToGroup(model.interactionRecords,{guid:tr.b.GUID.allocate(),model:model,getSettingsKey:function(){return undefined;}});},buildSubRows_:function(slices){if(this.subRows_.length)
+return this.subRows_;this.subRows_.push.apply(this.subRows_,tr.ui.tracks.AsyncSliceGroupTrack.prototype.buildSubRows_.call({},slices,true));return this.subRows_;},addSubTrack_:function(slices){var track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;this.appendChild(track);return track;}};return{InteractionTrack:InteractionTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ALLOCATED_MEMORY_TRACK_HEIGHT=50;var ProcessMemoryDumpTrack=tr.ui.b.define('process-memory-dump-track',tr.ui.tracks.ContainerTrack);ProcessMemoryDumpTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.memoryDumps_=undefined;},get memoryDumps(){return this.memoryDumps_;},set memoryDumps(memoryDumps){this.memoryDumps_=memoryDumps;this.updateContents_();},updateContents_:function(){this.clearTracks_();if(!this.memoryDumps_||!this.memoryDumps_.length)
+return;this.appendAllocatedMemoryTrack_();},appendAllocatedMemoryTrack_:function(){var series=tr.ui.tracks.buildProcessAllocatedMemoryChartSeries(this.memoryDumps_);if(!series)
+return;var track=new tr.ui.tracks.ChartTrack(this.viewport);track.heading='Memory per component';track.height=ALLOCATED_MEMORY_TRACK_HEIGHT+'px';track.series=series;track.autoSetAllAxes({expandMax:true});this.appendChild(track);}};return{ProcessMemoryDumpTrack:ProcessMemoryDumpTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ProcessTrackBase=tr.ui.tracks.ProcessTrackBase;var ProcessTrack=tr.ui.b.define('process-track',ProcessTrackBase);ProcessTrack.prototype={__proto__:ProcessTrackBase.prototype,decorate:function(viewport){tr.ui.tracks.ProcessTrackBase.prototype.decorate.call(this,viewport);},drawTrack:function(type){switch(type){case tr.ui.tracks.DrawType.INSTANT_EVENT:if(!this.processBase.instantEvents||this.processBase.instantEvents.length===0)
+break;var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var canvasBounds=ctx.canvas.getBoundingClientRect();ctx.save();ctx.translate(0,pixelRatio*(bounds.top-canvasBounds.top));var dt=this.viewport.currentDisplayTransform;var viewLWorld=dt.xViewToWorld(0);var viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);tr.ui.b.drawInstantSlicesAsLines(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,bounds.height,this.processBase.instantEvents,2);ctx.restore();break;case tr.ui.tracks.DrawType.BACKGROUND:this.drawBackground_();return;}
+tr.ui.tracks.ContainerTrack.prototype.drawTrack.call(this,type);},drawBackground_:function(){var ctx=this.context();var canvasBounds=ctx.canvas.getBoundingClientRect();var pixelRatio=window.devicePixelRatio||1;var draw=false;ctx.fillStyle='#eee';for(var i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track)||(this.children[i]instanceof tr.ui.tracks.SpacingTrack))
+continue;draw=!draw;if(!draw)
+continue;var bounds=this.children[i].getBoundingClientRect();ctx.fillRect(0,pixelRatio*(bounds.top-canvasBounds.top),ctx.canvas.width,pixelRatio*bounds.height);}},set process(process){this.processBase=process;},get process(){return this.processBase;},get eventContainer(){return this.process;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.ProcessTrackBase.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.process,this);},appendMemoryDumpTrack_:function(){var processMemoryDumps=this.process.memoryDumps;if(processMemoryDumps.length){var pmdt=new tr.ui.tracks.ProcessMemoryDumpTrack(this.viewport_);pmdt.memoryDumps=processMemoryDumps;this.appendChild(pmdt);}},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){function onPickHit(instantEvent){selection.push(instantEvent);}
+var instantEventWidth=2*viewPixWidthWorld;tr.b.iterateOverIntersectingIntervals(this.processBase.instantEvents,function(x){return x.start;},function(x){return x.duration+instantEventWidth;},loWX,hiWX,onPickHit.bind(this));tr.ui.tracks.ContainerTrack.prototype.addIntersectingEventsInRangeToSelectionInWorldSpace.apply(this,arguments);},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){this.addClosestInstantEventToSelection(this.processBase.instantEvents,worldX,worldMaxDist,selection);tr.ui.tracks.ContainerTrack.prototype.addClosestEventToSelection.apply(this,arguments);}};return{ProcessTrack:ProcessTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SelectionState=tr.model.SelectionState;var EventPresenter=tr.ui.b.EventPresenter;var ModelTrack=tr.ui.b.define('model-track',tr.ui.tracks.ContainerTrack);ModelTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.classList.add('model-track');var typeInfos=tr.ui.tracks.Highlighter.getAllRegisteredTypeInfos();this.highlighters_=typeInfos.map(function(typeInfo){return new typeInfo.constructor(viewport);});this.upperMode_=false;this.annotationViews_=[];},get upperMode(){return this.upperMode_;},set upperMode(upperMode){this.upperMode_=upperMode;this.updateContents_();},detach:function(){tr.ui.tracks.ContainerTrack.prototype.detach.call(this);},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();this.model_.addEventListener('annotationChange',this.updateAnnotations_.bind(this));},get hasVisibleContent(){return this.children.length>0;},updateContents_:function(){this.textContent='';if(!this.model_)
+return;if(this.upperMode_)
+this.updateContentsForUpperMode_();else
+this.updateContentsForLowerMode_();},updateContentsForUpperMode_:function(){},updateContentsForLowerMode_:function(){if(this.model_.interactionRecords.length){var mrt=new tr.ui.tracks.InteractionTrack(this.viewport_);mrt.model=this.model_;this.appendChild(mrt);}
+if(this.model_.alerts.length){var at=new tr.ui.tracks.AlertTrack(this.viewport_);at.alerts=this.model_.alerts;this.appendChild(at);}
+if(this.model_.globalMemoryDumps.length){var gmdt=new tr.ui.tracks.GlobalMemoryDumpTrack(this.viewport_);gmdt.memoryDumps=this.model_.globalMemoryDumps;this.appendChild(gmdt);}
+this.appendDeviceTrack_();this.appendKernelTrack_();var processes=this.model_.getAllProcesses();processes.sort(tr.model.Process.compare);for(var i=0;i<processes.length;++i){var process=processes[i];var track=new tr.ui.tracks.ProcessTrack(this.viewport);track.process=process;if(!track.hasVisibleContent)
+continue;this.appendChild(track);}
+this.viewport_.rebuildEventToTrackMap();this.viewport_.rebuildContainerToTrackMap();for(var i=0;i<this.highlighters_.length;i++){this.highlighters_[i].processModel(this.model_);}
+this.updateAnnotations_();},updateAnnotations_:function(){this.annotationViews_=[];var annotations=this.model_.getAllAnnotations();for(var i=0;i<annotations.length;i++){this.annotationViews_.push(annotations[i].getOrCreateView(this.viewport_));}
+this.invalidateDrawingContainer();},addEventsToTrackMap:function(eventToTrackMap){if(!this.model_)
+return;var tracks=this.children;for(var i=0;i<tracks.length;++i)
+tracks[i].addEventsToTrackMap(eventToTrackMap);if(this.instantEvents===undefined)
+return;var vp=this.viewport_;this.instantEvents.forEach(function(ev){eventToTrackMap.addEvent(ev,this);}.bind(this));},appendDeviceTrack_:function(){var device=this.model.device;var track=new tr.ui.tracks.DeviceTrack(this.viewport);track.device=this.model.device;if(!track.hasVisibleContent)
+return;this.appendChild(track);},appendKernelTrack_:function(){var kernel=this.model.kernel;var track=new tr.ui.tracks.KernelTrack(this.viewport);track.kernel=this.model.kernel;if(!track.hasVisibleContent)
+return;this.appendChild(track);},drawTrack:function(type){var ctx=this.context();if(!this.model_)
+return;var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var canvasBounds=ctx.canvas.getBoundingClientRect();ctx.save();ctx.translate(0,pixelRatio*(bounds.top-canvasBounds.top));var dt=this.viewport.currentDisplayTransform;var viewLWorld=dt.xViewToWorld(0);var viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);switch(type){case tr.ui.tracks.DrawType.GRID:this.viewport.drawMajorMarkLines(ctx);ctx.restore();return;case tr.ui.tracks.DrawType.FLOW_ARROWS:if(this.model_.flowIntervalTree.size===0){ctx.restore();return;}
+this.drawFlowArrows_(viewLWorld,viewRWorld);ctx.restore();return;case tr.ui.tracks.DrawType.INSTANT_EVENT:if(!this.model_.instantEvents||this.model_.instantEvents.length===0)
+break;tr.ui.b.drawInstantSlicesAsLines(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,bounds.height,this.model_.instantEvents,4);break;case tr.ui.tracks.DrawType.MARKERS:if(!this.viewport.interestRange.isEmpty){this.viewport.interestRange.draw(ctx,viewLWorld,viewRWorld);this.viewport.interestRange.drawIndicators(ctx,viewLWorld,viewRWorld);}
+ctx.restore();return;case tr.ui.tracks.DrawType.HIGHLIGHTS:for(var i=0;i<this.highlighters_.length;i++){this.highlighters_[i].drawHighlight(ctx,dt,viewLWorld,viewRWorld,bounds.height);}
+ctx.restore();return;case tr.ui.tracks.DrawType.ANNOTATIONS:for(var i=0;i<this.annotationViews_.length;i++){this.annotationViews_[i].draw(ctx);}
+ctx.restore();return;}
+ctx.restore();tr.ui.tracks.ContainerTrack.prototype.drawTrack.call(this,type);},drawFlowArrows_:function(viewLWorld,viewRWorld){var ctx=this.context();var dt=this.viewport.currentDisplayTransform;dt.applyTransformToCanvas(ctx);var pixWidth=dt.xViewVectorToWorld(1);ctx.strokeStyle='rgba(0, 0, 0, 0.4)';ctx.fillStyle='rgba(0, 0, 0, 0.4)';ctx.lineWidth=pixWidth>1.0?1:pixWidth;var events=this.model_.flowIntervalTree.findIntersection(viewLWorld,viewRWorld);var onlyHighlighted=!this.viewport.showFlowEvents;var canvasBounds=ctx.canvas.getBoundingClientRect();for(var i=0;i<events.length;++i){if(onlyHighlighted&&events[i].selectionState!==SelectionState.SELECTED&&events[i].selectionState!==SelectionState.HIGHLIGHTED)
+continue;this.drawFlowArrow_(ctx,events[i],canvasBounds,pixWidth);}},drawFlowArrow_:function(ctx,flowEvent,canvasBounds,pixWidth){var pixelRatio=window.devicePixelRatio||1;var startTrack=this.viewport.trackForEvent(flowEvent.startSlice);var endTrack=this.viewport.trackForEvent(flowEvent.endSlice);if(startTrack===undefined||endTrack===undefined)
+return;var startBounds=startTrack.getBoundingClientRect();var endBounds=endTrack.getBoundingClientRect();if(flowEvent.selectionState==SelectionState.SELECTED){ctx.shadowBlur=1;ctx.shadowColor='red';ctx.shadowOffsety=2;ctx.strokeStyle='red';}else if(flowEvent.selectionState==SelectionState.HIGHLIGHTED){ctx.shadowBlur=1;ctx.shadowColor='red';ctx.shadowOffsety=2;ctx.strokeStyle='red';}else if(flowEvent.selectionState==SelectionState.DIMMED){ctx.shadowBlur=0;ctx.shadowOffsetX=0;ctx.strokeStyle='rgba(0, 0, 0, 0.2)';}else{var hasBoost=false;var startSlice=flowEvent.startSlice;hasBoost|=startSlice.selectionState===SelectionState.SELECTED;hasBoost|=startSlice.selectionState===SelectionState.HIGHLIGHTED;var endSlice=flowEvent.endSlice;hasBoost|=endSlice.selectionState===SelectionState.SELECTED;hasBoost|=endSlice.selectionState===SelectionState.HIGHLIGHTED;if(hasBoost){ctx.shadowBlur=1;ctx.shadowColor='rgba(255, 0, 0, 0.4)';ctx.shadowOffsety=2;ctx.strokeStyle='rgba(255, 0, 0, 0.4)';}else{ctx.shadowBlur=0;ctx.shadowOffsetX=0;ctx.strokeStyle='rgba(0, 0, 0, 0.4)';}}
+var startSize=startBounds.left+startBounds.top+
+startBounds.bottom+startBounds.right;var endSize=endBounds.left+endBounds.top+
+endBounds.bottom+endBounds.right;if(startSize===0&&endSize===0)
+return;var startY=this.calculateTrackY_(startTrack,canvasBounds);var endY=this.calculateTrackY_(endTrack,canvasBounds);var pixelStartY=pixelRatio*startY;var pixelEndY=pixelRatio*endY;var half=(flowEvent.end-flowEvent.start)/2;ctx.beginPath();ctx.moveTo(flowEvent.start,pixelStartY);ctx.bezierCurveTo(flowEvent.start+half,pixelStartY,flowEvent.start+half,pixelEndY,flowEvent.end,pixelEndY);ctx.stroke();var arrowWidth=5*pixWidth*pixelRatio;var distance=flowEvent.end-flowEvent.start;if(distance<=(2*arrowWidth))
+return;var tipX=flowEvent.end;var tipY=pixelEndY;var arrowHeight=(endBounds.height/4)*pixelRatio;tr.ui.b.drawTriangle(ctx,tipX,tipY,tipX-arrowWidth,tipY-arrowHeight,tipX-arrowWidth,tipY+arrowHeight);ctx.fill();},calculateTrackY_:function(track,canvasBounds){var bounds=track.getBoundingClientRect();var size=bounds.left+bounds.top+bounds.bottom+bounds.right;if(size===0)
+return this.calculateTrackY_(track.parentNode,canvasBounds);return bounds.top-canvasBounds.top+(bounds.height/2);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){function onPickHit(instantEvent){selection.push(instantEvent);}
+var instantEventWidth=3*viewPixWidthWorld;tr.b.iterateOverIntersectingIntervals(this.model_.instantEvents,function(x){return x.start;},function(x){return x.duration+instantEventWidth;},loWX,hiWX,onPickHit.bind(this));tr.ui.tracks.ContainerTrack.prototype.addIntersectingEventsInRangeToSelectionInWorldSpace.apply(this,arguments);},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){this.addClosestInstantEventToSelection(this.model_.instantEvents,worldX,worldMaxDist,selection);tr.ui.tracks.ContainerTrack.prototype.addClosestEventToSelection.apply(this,arguments);}};return{ModelTrack:ModelTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var RulerTrack=tr.ui.b.define('ruler-track',tr.ui.tracks.Track);var logOf10=Math.log(10);function log10(x){return Math.log(x)/logOf10;}
+RulerTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('ruler-track');this.strings_secs_=[];this.strings_msecs_=[];this.strings_usecs_=[];this.strings_nsecs_=[];this.viewportChange_=this.viewportChange_.bind(this);viewport.addEventListener('change',this.viewportChange_);var heading=document.createElement('tr-ui-heading');heading.arrowVisible=false;this.appendChild(heading);},detach:function(){tr.ui.tracks.Track.prototype.detach.call(this);this.viewport.removeEventListener('change',this.viewportChange_);},viewportChange_:function(){if(this.viewport.interestRange.isEmpty)
+this.classList.remove('tall-mode');else
+this.classList.add('tall-mode');},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GRID:this.drawGrid_(viewLWorld,viewRWorld);break;case tr.ui.tracks.DrawType.MARKERS:if(!this.viewport.interestRange.isEmpty)
+this.viewport.interestRange.draw(this.context(),viewLWorld,viewRWorld);break;}},drawGrid_:function(viewLWorld,viewRWorld){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var canvasBounds=ctx.canvas.getBoundingClientRect();var trackBounds=this.getBoundingClientRect();var width=canvasBounds.width*pixelRatio;var height=trackBounds.height*pixelRatio;var hasInterestRange=!this.viewport.interestRange.isEmpty;var rulerHeight=hasInterestRange?(height*2)/5:height;var vp=this.viewport;var dt=vp.currentDisplayTransform;var idealMajorMarkDistancePix=150*pixelRatio;var idealMajorMarkDistanceWorld=dt.xViewVectorToWorld(idealMajorMarkDistancePix);var majorMarkDistanceWorld;var conservativeGuess=Math.pow(10,Math.ceil(log10(idealMajorMarkDistanceWorld)));var divisors=[10,5,2,1];for(var i=0;i<divisors.length;++i){var tightenedGuess=conservativeGuess/divisors[i];if(dt.xWorldVectorToView(tightenedGuess)<idealMajorMarkDistancePix)
+continue;majorMarkDistanceWorld=conservativeGuess/divisors[i-1];break;}
+var unit;var unitDivisor;var tickLabels=undefined;if(majorMarkDistanceWorld<0.0001){unit='ns';unitDivisor=0.000001;tickLabels=this.strings_nsecs_;}else if(majorMarkDistanceWorld<0.1){unit='us';unitDivisor=0.001;tickLabels=this.strings_usecs_;}else if(majorMarkDistanceWorld<100){unit='ms';unitDivisor=1;tickLabels=this.strings_msecs_;}else{unit='s';unitDivisor=1000;tickLabels=this.strings_secs_;}
+var numTicksPerMajor=5;var minorMarkDistanceWorld=majorMarkDistanceWorld/numTicksPerMajor;var minorMarkDistancePx=dt.xWorldVectorToView(minorMarkDistanceWorld);var firstMajorMark=Math.floor(viewLWorld/majorMarkDistanceWorld)*majorMarkDistanceWorld;var minorTickH=Math.floor(rulerHeight*0.25);ctx.save();var pixelRatio=window.devicePixelRatio||1;ctx.lineWidth=Math.round(pixelRatio);var crispLineCorrection=(ctx.lineWidth%2)/2;ctx.translate(crispLineCorrection,-crispLineCorrection);ctx.fillStyle='rgb(0, 0, 0)';ctx.strokeStyle='rgb(0, 0, 0)';ctx.textAlign='left';ctx.textBaseline='top';ctx.font=(9*pixelRatio)+'px sans-serif';vp.majorMarkPositions=[];ctx.beginPath();for(var curX=firstMajorMark;curX<viewRWorld;curX+=majorMarkDistanceWorld){var curXView=Math.floor(dt.xWorldToView(curX));var unitValue=curX/unitDivisor;var roundedUnitValue=Math.round(unitValue*100000)/100000;if(!tickLabels[roundedUnitValue])
+tickLabels[roundedUnitValue]=roundedUnitValue+' '+unit;ctx.fillText(tickLabels[roundedUnitValue],curXView+(2*pixelRatio),0);vp.majorMarkPositions.push(curXView);tr.ui.b.drawLine(ctx,curXView,0,curXView,rulerHeight);for(var i=1;i<numTicksPerMajor;++i){var xView=Math.floor(curXView+minorMarkDistancePx*i);tr.ui.b.drawLine(ctx,xView,rulerHeight-minorTickH,xView,rulerHeight);}}
+ctx.strokeStyle='rgb(0, 0, 0)';tr.ui.b.drawLine(ctx,0,height,width,height);ctx.stroke();if(!hasInterestRange)
+return;tr.ui.b.drawLine(ctx,0,rulerHeight,width,rulerHeight);ctx.stroke();var displayDistance;var displayTextColor='rgb(0,0,0)';var arrowSpacing=10*pixelRatio;var arrowColor='rgb(128,121,121)';var arrowPosY=rulerHeight*1.75;var arrowWidthView=3*pixelRatio;var arrowLengthView=10*pixelRatio;var spaceForArrowsView=2*(arrowWidthView+arrowSpacing);ctx.textBaseline='middle';ctx.font=(14*pixelRatio)+'px sans-serif';var textPosY=arrowPosY;var interestRange=vp.interestRange;if(interestRange.range===0){var markerWorld=interestRange.min;var markerView=dt.xWorldToView(markerWorld);var displayValue=markerWorld/unitDivisor;displayValue=Math.abs((Math.round(displayValue*1000)/1000));var textToDraw=displayValue+' '+unit;var textLeftView=markerView+4*pixelRatio;var textWidthView=ctx.measureText(textToDraw).width;if(textLeftView+textWidthView>width)
+textLeftView=markerView-4*pixelRatio-textWidthView;ctx.fillStyle=displayTextColor;ctx.fillText(textToDraw,textLeftView,textPosY);return;}
+var leftMarker=interestRange.min;var rightMarker=interestRange.max;var leftMarkerView=dt.xWorldToView(leftMarker);var rightMarkerView=dt.xWorldToView(rightMarker);var distanceBetweenMarkers=interestRange.range;var distanceBetweenMarkersView=dt.xWorldVectorToView(distanceBetweenMarkers);var positionInMiddleOfMarkersView=leftMarkerView+(distanceBetweenMarkersView/2);if(distanceBetweenMarkers<0.0001){unit='ns';unitDivisor=0.000001;}else if(distanceBetweenMarkers<0.1){unit='us';unitDivisor=0.001;}else if(distanceBetweenMarkers<100){unit='ms';unitDivisor=1;}else{unit='s';unitDivisor=1000;}
+displayDistance=distanceBetweenMarkers/unitDivisor;var roundedDisplayDistance=Math.abs((Math.round(displayDistance*1000)/1000));var textToDraw=roundedDisplayDistance+' '+unit;var textWidthView=ctx.measureText(textToDraw).width;var spaceForArrowsAndTextView=textWidthView+spaceForArrowsView+arrowSpacing;var textLeftView=positionInMiddleOfMarkersView-textWidthView/2;var textRightView=textLeftView+textWidthView;if(spaceForArrowsAndTextView>distanceBetweenMarkersView){textLeftView=rightMarkerView+2*arrowSpacing;if(textLeftView+textWidthView>width)
+textLeftView=leftMarkerView-2*arrowSpacing-textWidthView;ctx.fillStyle=displayTextColor;ctx.fillText(textToDraw,textLeftView,textPosY);ctx.strokeStyle=arrowColor;ctx.beginPath();tr.ui.b.drawLine(ctx,leftMarkerView,arrowPosY,rightMarkerView,arrowPosY);ctx.stroke();ctx.fillStyle=arrowColor;tr.ui.b.drawArrow(ctx,leftMarkerView-1.5*arrowSpacing,arrowPosY,leftMarkerView,arrowPosY,arrowLengthView,arrowWidthView);tr.ui.b.drawArrow(ctx,rightMarkerView+1.5*arrowSpacing,arrowPosY,rightMarkerView,arrowPosY,arrowLengthView,arrowWidthView);}else if(spaceForArrowsView<=distanceBetweenMarkersView){var leftArrowStart;var rightArrowStart;if(spaceForArrowsAndTextView<=distanceBetweenMarkersView){ctx.fillStyle=displayTextColor;ctx.fillText(textToDraw,textLeftView,textPosY);leftArrowStart=textLeftView-arrowSpacing;rightArrowStart=textRightView+arrowSpacing;}else{leftArrowStart=positionInMiddleOfMarkersView;rightArrowStart=positionInMiddleOfMarkersView;}
+ctx.strokeStyle=arrowColor;ctx.fillStyle=arrowColor;tr.ui.b.drawArrow(ctx,leftArrowStart,arrowPosY,leftMarkerView,arrowPosY,arrowLengthView,arrowWidthView);tr.ui.b.drawArrow(ctx,rightArrowStart,arrowPosY,rightMarkerView,arrowPosY,arrowLengthView,arrowWidthView);}
+ctx.restore();},addIntersectingEventsInRangeToSelection:function(loVX,hiVX,loY,hiY,selection){},addAllEventsMatchingFilterToSelection:function(filter,selection){}};return{RulerTrack:RulerTrack};});'use strict';Polymer('tr-ui-timeline-track-view',{ready:function(){this.displayTransform_=new tr.ui.TimelineDisplayTransform();this.model_=undefined;this.timelineView_=undefined;this.viewport_=new tr.ui.TimelineViewport(this);this.viewportDisplayTransformAtMouseDown_=undefined;this.brushingStateController_=undefined;this.rulerTrackContainer_=new tr.ui.tracks.DrawingContainer(this.viewport_);this.appendChild(this.rulerTrackContainer_);this.rulerTrackContainer_.invalidate();this.rulerTrack_=new tr.ui.tracks.RulerTrack(this.viewport_);this.rulerTrackContainer_.appendChild(this.rulerTrack_);this.upperModelTrack_=new tr.ui.tracks.ModelTrack(this.viewport_);this.upperModelTrack_.upperMode=true;this.rulerTrackContainer_.appendChild(this.upperModelTrack_);this.modelTrackContainer_=new tr.ui.tracks.DrawingContainer(this.viewport_);this.appendChild(this.modelTrackContainer_);this.modelTrackContainer_.style.display='block';this.modelTrackContainer_.invalidate();this.viewport_.modelTrackContainer=this.modelTrackContainer_;this.modelTrack_=new tr.ui.tracks.ModelTrack(this.viewport_);this.modelTrackContainer_.appendChild(this.modelTrack_);this.timingTool_=new tr.ui.b.TimingTool(this.viewport_,this);this.initMouseModeSelector();this.hideDragBox_();this.initHintText_();this.onSelectionChanged_=this.onSelectionChanged_.bind(this);this.onDblClick_=this.onDblClick_.bind(this);this.addEventListener('dblclick',this.onDblClick_);this.onMouseWheel_=this.onMouseWheel_.bind(this);this.addEventListener('mousewheel',this.onMouseWheel_);this.onMouseDown_=this.onMouseDown_.bind(this);this.addEventListener('mousedown',this.onMouseDown_);this.onMouseMove_=this.onMouseMove_.bind(this);this.addEventListener('mousemove',this.onMouseMove_);this.onTouchStart_=this.onTouchStart_.bind(this);this.addEventListener('touchstart',this.onTouchStart_);this.onTouchMove_=this.onTouchMove_.bind(this);this.addEventListener('touchmove',this.onTouchMove_);this.onTouchEnd_=this.onTouchEnd_.bind(this);this.addEventListener('touchend',this.onTouchEnd_);this.addHotKeys_();this.mouseViewPosAtMouseDown_={x:0,y:0};this.lastMouseViewPos_={x:0,y:0};this.lastTouchViewPositions_=[];this.alert_=undefined;this.isPanningAndScanning_=false;this.isZooming_=false;},initMouseModeSelector:function(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this;this.appendChild(this.mouseModeSelector_);this.mouseModeSelector_.addEventListener('beginpan',this.onBeginPanScan_.bind(this));this.mouseModeSelector_.addEventListener('updatepan',this.onUpdatePanScan_.bind(this));this.mouseModeSelector_.addEventListener('endpan',this.onEndPanScan_.bind(this));this.mouseModeSelector_.addEventListener('beginselection',this.onBeginSelection_.bind(this));this.mouseModeSelector_.addEventListener('updateselection',this.onUpdateSelection_.bind(this));this.mouseModeSelector_.addEventListener('endselection',this.onEndSelection_.bind(this));this.mouseModeSelector_.addEventListener('beginzoom',this.onBeginZoom_.bind(this));this.mouseModeSelector_.addEventListener('updatezoom',this.onUpdateZoom_.bind(this));this.mouseModeSelector_.addEventListener('endzoom',this.onEndZoom_.bind(this));this.mouseModeSelector_.addEventListener('entertiming',this.timingTool_.onEnterTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('begintiming',this.timingTool_.onBeginTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('updatetiming',this.timingTool_.onUpdateTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('endtiming',this.timingTool_.onEndTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('exittiming',this.timingTool_.onExitTiming.bind(this.timingTool_));var m=tr.ui.b.MOUSE_SELECTOR_MODE;this.mouseModeSelector_.supportedModeMask=m.SELECTION|m.PANSCAN|m.ZOOM|m.TIMING;this.mouseModeSelector_.settingsKey='timelineTrackView.mouseModeSelector';this.mouseModeSelector_.setKeyCodeForMode(m.PANSCAN,'2'.charCodeAt(0));this.mouseModeSelector_.setKeyCodeForMode(m.SELECTION,'1'.charCodeAt(0));this.mouseModeSelector_.setKeyCodeForMode(m.ZOOM,'3'.charCodeAt(0));this.mouseModeSelector_.setKeyCodeForMode(m.TIMING,'4'.charCodeAt(0));this.mouseModeSelector_.setModifierForAlternateMode(m.SELECTION,tr.ui.b.MODIFIER.SHIFT);this.mouseModeSelector_.setModifierForAlternateMode(m.PANSCAN,tr.ui.b.MODIFIER.SPACE);},get brushingStateController(){return this.brushingStateController_;},set brushingStateController(brushingStateController){if(this.brushingStateController_){this.brushingStateController_.removeEventListener('change',this.onSelectionChanged_);}
+this.brushingStateController_=brushingStateController;if(this.brushingStateController_){this.brushingStateController_.addEventListener('change',this.onSelectionChanged_);}},set timelineView(view){this.timelineView_=view;},onSelectionChanged_:function(){this.showHintText_('Press \'m\' to mark current selection');this.viewport_.dispatchChangeEvent();},set selection(selection){throw new Error('DO NOT CALL THIS');},set highlight(highlight){throw new Error('DO NOT CALL THIS');},detach:function(){this.modelTrack_.detach();this.upperModelTrack_.detach();this.viewport_.detach();},get viewport(){return this.viewport_;},get model(){return this.model_;},set model(model){if(!model)
+throw new Error('Model cannot be undefined');var modelInstanceChanged=this.model_!==model;this.model_=model;this.modelTrack_.model=model;this.upperModelTrack_.model=model;if(modelInstanceChanged)
+this.viewport_.setWhenPossible(this.setInitialViewport_.bind(this));},get hasVisibleContent(){return this.modelTrack_.hasVisibleContent||this.upperModelTrack_.hasVisibleContent;},setInitialViewport_:function(){this.modelTrackContainer_.updateCanvasSizeIfNeeded_();var w=this.modelTrackContainer_.canvas.width;var min;var range;if(this.model_.bounds.isEmpty){min=0;range=1000;}else if(this.model_.bounds.range===0){min=this.model_.bounds.min;range=1000;}else{min=this.model_.bounds.min;range=this.model_.bounds.range;}
+var boost=range*0.15;this.displayTransform_.set(this.viewport_.currentDisplayTransform);this.displayTransform_.xSetWorldBounds(min-boost,min+range+boost,w);this.viewport_.setDisplayTransformImmediately(this.displayTransform_);},addAllEventsMatchingFilterToSelectionAsTask:function(filter,selection){var modelTrack=this.modelTrack_;var firstT=modelTrack.addAllEventsMatchingFilterToSelectionAsTask(filter,selection);var lastT=firstT.after(function(){this.upperModelTrack_.addAllEventsMatchingFilterToSelection(filter,selection);},this);return firstT;},onMouseMove_:function(e){if(this.isZooming_)
+return;this.storeLastMousePos_(e);},onTouchStart_:function(e){this.storeLastTouchPositions_(e);this.focusElements_();},onTouchMove_:function(e){e.preventDefault();this.onUpdateTransformForTouch_(e);},onTouchEnd_:function(e){this.storeLastTouchPositions_(e);this.focusElements_();},addHotKeys_:function(){this.addKeyDownHotKeys_();this.addKeyPressHotKeys_();},addKeyPressHotKeys_:function(){var addBinding=function(dict){dict.eventType='keypress';dict.useCapture=false;dict.thisArg=this;var binding=new tr.ui.b.HotKey(dict);this.$.hotkey_controller.addHotKey(binding);}.bind(this);addBinding({keyCodes:['w'.charCodeAt(0),','.charCodeAt(0)],callback:function(e){this.zoomBy_(1.5,true);e.stopPropagation();}});addBinding({keyCodes:['s'.charCodeAt(0),'o'.charCodeAt(0)],callback:function(e){this.zoomBy_(1/1.5,true);e.stopPropagation();}});addBinding({keyCode:'g'.charCodeAt(0),callback:function(e){this.onGridToggle_(true);e.stopPropagation();}});addBinding({keyCode:'G'.charCodeAt(0),callback:function(e){this.onGridToggle_(false);e.stopPropagation();}});addBinding({keyCodes:['W'.charCodeAt(0),'<'.charCodeAt(0)],callback:function(e){this.zoomBy_(10,true);e.stopPropagation();}});addBinding({keyCodes:['S'.charCodeAt(0),'O'.charCodeAt(0)],callback:function(e){this.zoomBy_(1/10,true);e.stopPropagation();}});addBinding({keyCode:'a'.charCodeAt(0),callback:function(e){this.queueSmoothPan_(this.viewWidth_*0.3,0);e.stopPropagation();}});addBinding({keyCodes:['d'.charCodeAt(0),'e'.charCodeAt(0)],callback:function(e){this.queueSmoothPan_(this.viewWidth_*-0.3,0);e.stopPropagation();}});addBinding({keyCode:'A'.charCodeAt(0),callback:function(e){this.queueSmoothPan_(viewWidth*0.5,0);e.stopPropagation();}});addBinding({keyCode:'D'.charCodeAt(0),callback:function(e){this.queueSmoothPan_(viewWidth*-0.5,0);e.stopPropagation();}});addBinding({keyCode:'0'.charCodeAt(0),callback:function(e){this.setInitialViewport_();e.stopPropagation();}});addBinding({keyCode:'f'.charCodeAt(0),callback:function(e){this.zoomToSelection();e.stopPropagation();}});addBinding({keyCode:'m'.charCodeAt(0),callback:function(e){this.setCurrentSelectionAsInterestRange_();e.stopPropagation();}});addBinding({keyCode:'h'.charCodeAt(0),callback:function(e){this.toggleHighDetails_();e.stopPropagation();}});},get viewWidth_(){return this.modelTrackContainer_.canvas.clientWidth;},addKeyDownHotKeys_:function(){var addBinding=function(dict){dict.eventType='keydown';dict.useCapture=false;dict.thisArg=this;var binding=new tr.ui.b.HotKey(dict);this.$.hotkey_controller.addHotKey(binding);}.bind(this);addBinding({keyCode:37,callback:function(e){var curSel=this.brushingStateController_.selection;var sel=this.viewport.getShiftedSelection(curSel,-1);if(sel){this.brushingStateController.changeSelectionFromTimeline(sel);this.panToSelection();}else{this.queueSmoothPan_(this.viewWidth_*0.3,0);}
+e.preventDefault();e.stopPropagation();}});addBinding({keyCode:39,callback:function(e){var curSel=this.brushingStateController_.selection;var sel=this.viewport.getShiftedSelection(curSel,1);if(sel){this.brushingStateController.changeSelectionFromTimeline(sel);this.panToSelection();}else{this.queueSmoothPan_(-this.viewWidth_*0.3,0);}
+e.preventDefault();e.stopPropagation();}});},onDblClick_:function(e){if(this.mouseModeSelector_.mode!==tr.ui.b.MOUSE_SELECTOR_MODE.SELECTION)
+return;var curSelection=this.brushingStateController_.selection;if(!curSelection.length||!curSelection[0].title)
+return;var selection=new tr.model.EventSet();var filter=new tr.c.ExactTitleFilter(curSelection[0].title);this.modelTrack_.addAllEventsMatchingFilterToSelection(filter,selection);this.brushingStateController.changeSelectionFromTimeline(selection);},onMouseWheel_:function(e){if(!e.altKey)
+return;var delta=e.wheelDelta/120;var zoomScale=Math.pow(1.5,delta);this.zoomBy_(zoomScale);e.preventDefault();},onMouseDown_:function(e){if(this.mouseModeSelector_.mode!==tr.ui.b.MOUSE_SELECTOR_MODE.SELECTION)
+return;if(e.target!==this.rulerTrack_)
+return;this.dragBeginEvent_=undefined;if(this.xNavStringMarker_){this.model.removeAnnotation(this.xNavStringMarker_);this.xNavStringMarker_=undefined;}
+var dt=this.viewport_.currentDisplayTransform;tr.ui.b.trackMouseMovesUntilMouseUp(function(e){if(e.target===this.rulerTrack_)
+return;var relativePosition=this.extractRelativeMousePosition_(e);var loc=tr.model.Location.fromViewCoordinates(this.viewport_,relativePosition.x,relativePosition.y);if(!loc)
+return;if(this.guideLineAnnotation_===undefined){this.guideLineAnnotation_=new tr.model.XMarkerAnnotation(loc.xWorld);this.model.addAnnotation(this.guideLineAnnotation_);}else{this.guideLineAnnotation_.timestamp=loc.xWorld;this.modelTrackContainer_.invalidate();}
+var state=new tr.ui.b.UIState(loc,this.viewport_.currentDisplayTransform.scaleX);this.timelineView_.setFindCtlText(state.toUserFriendlyString(this.viewport_));}.bind(this),undefined,function onKeyUpDuringDrag(){if(this.dragBeginEvent_){this.setDragBoxPosition_(this.dragBoxXStart_,this.dragBoxYStart_,this.dragBoxXEnd_,this.dragBoxYEnd_);}}.bind(this));},queueSmoothPan_:function(viewDeltaX,deltaY){var deltaX=this.viewport_.currentDisplayTransform.xViewVectorToWorld(viewDeltaX);var animation=new tr.ui.TimelineDisplayTransformPanAnimation(deltaX,deltaY);this.viewport_.queueDisplayTransformAnimation(animation);},zoomBy_:function(scale,smooth){if(scale<=0){return;}
+smooth=!!smooth;var vp=this.viewport_;var pixelRatio=window.devicePixelRatio||1;var goalFocalPointXView=this.lastMouseViewPos_.x*pixelRatio;var goalFocalPointXWorld=vp.currentDisplayTransform.xViewToWorld(goalFocalPointXView);if(smooth){var animation=new tr.ui.TimelineDisplayTransformZoomToAnimation(goalFocalPointXWorld,goalFocalPointXView,vp.currentDisplayTransform.panY,scale);vp.queueDisplayTransformAnimation(animation);}else{this.displayTransform_.set(vp.currentDisplayTransform);this.displayTransform_.scaleX*=scale;this.displayTransform_.xPanWorldPosToViewPos(goalFocalPointXWorld,goalFocalPointXView,this.viewWidth_);vp.setDisplayTransformImmediately(this.displayTransform_);}},zoomToSelection:function(){if(!this.brushingStateController.selectionOfInterest.length)
+return;var bounds=this.brushingStateController.selectionOfInterest.bounds;if(!bounds.range)
+return;var worldCenter=bounds.center;var viewCenter=this.modelTrackContainer_.canvas.width/2;var adjustedWorldRange=bounds.range*1.25;var newScale=this.modelTrackContainer_.canvas.width/adjustedWorldRange;var zoomInRatio=newScale/this.viewport_.currentDisplayTransform.scaleX;var animation=new tr.ui.TimelineDisplayTransformZoomToAnimation(worldCenter,viewCenter,this.viewport_.currentDisplayTransform.panY,zoomInRatio);this.viewport_.queueDisplayTransformAnimation(animation);},panToSelection:function(){if(!this.brushingStateController.selectionOfInterest.length)
+return;var bounds=this.brushingStateController.selectionOfInterest.bounds;var worldCenter=bounds.center;var viewWidth=this.viewWidth_;var dt=this.viewport_.currentDisplayTransform;if(false&&!bounds.range){if(dt.xWorldToView(bounds.center)<0||dt.xWorldToView(bounds.center)>viewWidth){this.displayTransform_.set(dt);this.displayTransform_.xPanWorldPosToViewPos(worldCenter,'center',viewWidth);var deltaX=this.displayTransform_.panX-dt.panX;var animation=new tr.ui.TimelineDisplayTransformPanAnimation(deltaX,0);this.viewport_.queueDisplayTransformAnimation(animation);}
+return;}
+this.displayTransform_.set(dt);this.displayTransform_.xPanWorldBoundsIntoView(bounds.min,bounds.max,viewWidth);var deltaX=this.displayTransform_.panX-dt.panX;var animation=new tr.ui.TimelineDisplayTransformPanAnimation(deltaX,0);this.viewport_.queueDisplayTransformAnimation(animation);},navToPosition:function(uiState,showNavLine){var location=uiState.location;var scaleX=uiState.scaleX;var track=location.getContainingTrack(this.viewport_);var worldCenter=location.xWorld;var viewCenter=this.modelTrackContainer_.canvas.width/5;var zoomInRatio=scaleX/this.viewport_.currentDisplayTransform.scaleX;track.scrollIntoViewIfNeeded();var animation=new tr.ui.TimelineDisplayTransformZoomToAnimation(worldCenter,viewCenter,this.viewport_.currentDisplayTransform.panY,zoomInRatio);this.viewport_.queueDisplayTransformAnimation(animation);if(!showNavLine)
+return;if(this.xNavStringMarker_)
+this.model.removeAnnotation(this.xNavStringMarker_);this.xNavStringMarker_=new tr.model.XMarkerAnnotation(worldCenter);this.model.addAnnotation(this.xNavStringMarker_);},setCurrentSelectionAsInterestRange_:function(){var selectionBounds=this.brushingStateController_.selection.bounds;if(selectionBounds.empty){this.viewport_.interestRange.reset();return;}
+if(this.viewport_.interestRange.min==selectionBounds.min&&this.viewport_.interestRange.max==selectionBounds.max)
+this.viewport_.interestRange.reset();else
+this.viewport_.interestRange.set(selectionBounds);},toggleHighDetails_:function(){this.viewport_.highDetails=!this.viewport_.highDetails;},hideDragBox_:function(){this.$.drag_box.style.left='-1000px';this.$.drag_box.style.top='-1000px';this.$.drag_box.style.width=0;this.$.drag_box.style.height=0;},setDragBoxPosition_:function(xStart,yStart,xEnd,yEnd){var loY=Math.min(yStart,yEnd);var hiY=Math.max(yStart,yEnd);var loX=Math.min(xStart,xEnd);var hiX=Math.max(xStart,xEnd);var modelTrackRect=this.modelTrack_.getBoundingClientRect();var dragRect={left:loX,top:loY,width:hiX-loX,height:hiY-loY};dragRect.right=dragRect.left+dragRect.width;dragRect.bottom=dragRect.top+dragRect.height;var modelTrackContainerRect=this.modelTrackContainer_.getBoundingClientRect();var clipRect={left:modelTrackContainerRect.left,top:modelTrackContainerRect.top,right:modelTrackContainerRect.right,bottom:modelTrackContainerRect.bottom};var headingWidth=window.getComputedStyle(this.querySelector('tr-ui-heading')).width;var trackTitleWidth=parseInt(headingWidth);clipRect.left=clipRect.left+trackTitleWidth;var intersectRect_=function(r1,r2){if(r2.left>r1.right||r2.right<r1.left||r2.top>r1.bottom||r2.bottom<r1.top)
+return false;var results={};results.left=Math.max(r1.left,r2.left);results.top=Math.max(r1.top,r2.top);results.right=Math.min(r1.right,r2.right);results.bottom=Math.min(r1.bottom,r2.bottom);results.width=results.right-results.left;results.height=results.bottom-results.top;return results;}
+var finalDragBox=intersectRect_(clipRect,dragRect);this.$.drag_box.style.left=finalDragBox.left+'px';this.$.drag_box.style.width=finalDragBox.width+'px';this.$.drag_box.style.top=finalDragBox.top+'px';this.$.drag_box.style.height=finalDragBox.height+'px';this.$.drag_box.style.whiteSpace='nowrap';var pixelRatio=window.devicePixelRatio||1;var canv=this.modelTrackContainer_.canvas;var dt=this.viewport_.currentDisplayTransform;var loWX=dt.xViewToWorld((loX-canv.offsetLeft)*pixelRatio);var hiWX=dt.xViewToWorld((hiX-canv.offsetLeft)*pixelRatio);this.$.drag_box.textContent=tr.b.u.TimeDuration.format(hiWX-loWX);var e=new tr.b.Event('selectionChanging');e.loWX=loWX;e.hiWX=hiWX;this.dispatchEvent(e);},onGridToggle_:function(left){var selection=this.brushingStateController_.selection;var tb=left?selection.bounds.min:selection.bounds.max;if(this.viewport_.gridEnabled&&this.viewport_.gridSide===left&&this.viewport_.gridInitialTimebase===tb){this.viewport_.gridside=undefined;this.viewport_.gridEnabled=false;this.viewport_.gridInitialTimebase=undefined;return;}
+var numIntervalsSinceStart=Math.ceil((tb-this.model_.bounds.min)/this.viewport_.gridStep_);this.viewport_.gridEnabled=true;this.viewport_.gridSide=left;this.viewport_.gridInitialTimebase=tb;this.viewport_.gridTimebase=tb-
+(numIntervalsSinceStart+1)*this.viewport_.gridStep_;},storeLastMousePos_:function(e){this.lastMouseViewPos_=this.extractRelativeMousePosition_(e);},storeLastTouchPositions_:function(e){this.lastTouchViewPositions_=this.extractRelativeTouchPositions_(e);},extractRelativeMousePosition_:function(e){var canv=this.modelTrackContainer_.canvas;return{x:e.clientX-canv.offsetLeft,y:e.clientY-canv.offsetTop};},extractRelativeTouchPositions_:function(e){var canv=this.modelTrackContainer_.canvas;var touches=[];for(var i=0;i<e.touches.length;++i){touches.push({x:e.touches[i].clientX-canv.offsetLeft,y:e.touches[i].clientY-canv.offsetTop});}
+return touches;},storeInitialMouseDownPos_:function(e){var position=this.extractRelativeMousePosition_(e);this.mouseViewPosAtMouseDown_.x=position.x;this.mouseViewPosAtMouseDown_.y=position.y;},focusElements_:function(){this.$.hotkey_controller.childRequestsGeneralFocus(this);},storeInitialInteractionPositionsAndFocus_:function(e){this.storeInitialMouseDownPos_(e);this.storeLastMousePos_(e);this.focusElements_();},onBeginPanScan_:function(e){var vp=this.viewport_;this.viewportDisplayTransformAtMouseDown_=vp.currentDisplayTransform.clone();this.isPanningAndScanning_=true;this.storeInitialInteractionPositionsAndFocus_(e);e.preventDefault();},onUpdatePanScan_:function(e){if(!this.isPanningAndScanning_)
+return;var viewWidth=this.viewWidth_;var pixelRatio=window.devicePixelRatio||1;var xDeltaView=pixelRatio*(this.lastMouseViewPos_.x-
+this.mouseViewPosAtMouseDown_.x);var yDelta=this.lastMouseViewPos_.y-
+this.mouseViewPosAtMouseDown_.y;this.displayTransform_.set(this.viewportDisplayTransformAtMouseDown_);this.displayTransform_.incrementPanXInViewUnits(xDeltaView);this.displayTransform_.panY-=yDelta;this.viewport_.setDisplayTransformImmediately(this.displayTransform_);e.preventDefault();e.stopPropagation();this.storeLastMousePos_(e);},onEndPanScan_:function(e){this.isPanningAndScanning_=false;this.storeLastMousePos_(e);if(!e.isClick)
+e.preventDefault();},onBeginSelection_:function(e){var canv=this.modelTrackContainer_.canvas;var rect=this.modelTrack_.getBoundingClientRect();var canvRect=canv.getBoundingClientRect();var inside=rect&&e.clientX>=rect.left&&e.clientX<rect.right&&e.clientY>=rect.top&&e.clientY<rect.bottom&&e.clientX>=canvRect.left&&e.clientX<canvRect.right;if(!inside)
+return;this.dragBeginEvent_=e;this.storeInitialInteractionPositionsAndFocus_(e);e.preventDefault();},onUpdateSelection_:function(e){if(!this.dragBeginEvent_)
+return;this.dragBoxXStart_=this.dragBeginEvent_.clientX;this.dragBoxXEnd_=e.clientX;this.dragBoxYStart_=this.dragBeginEvent_.clientY;this.dragBoxYEnd_=e.clientY;this.setDragBoxPosition_(this.dragBoxXStart_,this.dragBoxYStart_,this.dragBoxXEnd_,this.dragBoxYEnd_);},onEndSelection_:function(e){e.preventDefault();if(!this.dragBeginEvent_)
+return;this.hideDragBox_();var eDown=this.dragBeginEvent_;this.dragBeginEvent_=undefined;var loY=Math.min(eDown.clientY,e.clientY);var hiY=Math.max(eDown.clientY,e.clientY);var loX=Math.min(eDown.clientX,e.clientX);var hiX=Math.max(eDown.clientX,e.clientX);var canv=this.modelTrackContainer_.canvas;var worldOffset=canv.getBoundingClientRect().left;var loVX=loX-worldOffset;var hiVX=hiX-worldOffset;var selection=new tr.model.EventSet();if(eDown.appendSelection){var previousSelection=this.brushingStateController_.selection;if(previousSelection!==undefined)
+selection.addEventSet(previousSelection);}
+this.modelTrack_.addIntersectingEventsInRangeToSelection(loVX,hiVX,loY,hiY,selection);this.brushingStateController_.changeSelectionFromTimeline(selection);},onBeginZoom_:function(e){this.isZooming_=true;this.storeInitialInteractionPositionsAndFocus_(e);e.preventDefault();},onUpdateZoom_:function(e){if(!this.isZooming_)
+return;var newPosition=this.extractRelativeMousePosition_(e);var zoomScaleValue=1+(this.lastMouseViewPos_.y-
+newPosition.y)*0.01;this.zoomBy_(zoomScaleValue,false);this.storeLastMousePos_(e);},onEndZoom_:function(e){this.isZooming_=false;if(!e.isClick)
+e.preventDefault();},computeTouchCenter_:function(positions){var xSum=0;var ySum=0;for(var i=0;i<positions.length;++i){xSum+=positions[i].x;ySum+=positions[i].y;}
+return{x:xSum/positions.length,y:ySum/positions.length};},computeTouchSpan_:function(positions){var xMin=Number.MAX_VALUE;var yMin=Number.MAX_VALUE;var xMax=Number.MIN_VALUE;var yMax=Number.MIN_VALUE;for(var i=0;i<positions.length;++i){xMin=Math.min(xMin,positions[i].x);yMin=Math.min(yMin,positions[i].y);xMax=Math.max(xMax,positions[i].x);yMax=Math.max(yMax,positions[i].y);}
+return Math.sqrt((xMin-xMax)*(xMin-xMax)+
+(yMin-yMax)*(yMin-yMax));},onUpdateTransformForTouch_:function(e){var newPositions=this.extractRelativeTouchPositions_(e);var currentPositions=this.lastTouchViewPositions_;var newCenter=this.computeTouchCenter_(newPositions);var currentCenter=this.computeTouchCenter_(currentPositions);var newSpan=this.computeTouchSpan_(newPositions);var currentSpan=this.computeTouchSpan_(currentPositions);var vp=this.viewport_;var viewWidth=this.viewWidth_;var pixelRatio=window.devicePixelRatio||1;var xDelta=pixelRatio*(newCenter.x-currentCenter.x);var yDelta=newCenter.y-currentCenter.y;var zoomScaleValue=currentSpan>10?newSpan/currentSpan:1;var viewFocus=pixelRatio*newCenter.x;var worldFocus=vp.currentDisplayTransform.xViewToWorld(viewFocus);this.displayTransform_.set(vp.currentDisplayTransform);this.displayTransform_.scaleX*=zoomScaleValue;this.displayTransform_.xPanWorldPosToViewPos(worldFocus,viewFocus,viewWidth);this.displayTransform_.incrementPanXInViewUnits(xDelta);this.displayTransform_.panY-=yDelta;vp.setDisplayTransformImmediately(this.displayTransform_);this.storeLastTouchPositions_(e);},initHintText_:function(){this.$.hint_text.style.display='none';this.pendingHintTextClearTimeout_=undefined;},showHintText_:function(text){if(this.pendingHintTextClearTimeout_){window.clearTimeout(this.pendingHintTextClearTimeout_);this.pendingHintTextClearTimeout_=undefined;}
+this.pendingHintTextClearTimeout_=setTimeout(this.hideHintText_.bind(this),1000);this.$.hint_text.textContent=text;this.$.hint_text.style.display='';},hideHintText_:function(){this.pendingHintTextClearTimeout_=undefined;this.$.hint_text.style.display='none';}});'use strict';Polymer('tr-ui-find-control',{filterKeyDown:function(e){if(e.keyCode===27){var hkc=tr.b.getHotkeyControllerForElement(this);if(hkc){hkc.childRequestsBlur(this);}else{this.blur();}
+e.preventDefault();e.stopPropagation();return;}else if(e.keyCode===13){if(e.shiftKey)
+this.findPrevious();else
+this.findNext();}},filterBlur:function(e){this.updateHitCountEl();},filterFocus:function(e){this.$.filter.select();},filterMouseUp:function(e){e.preventDefault();},get controller(){return this.controller_;},set controller(c){this.controller_=c;this.updateHitCountEl();},focus:function(){this.$.filter.focus();},get hasFocus(){return this===document.activeElement;},filterTextChanged:function(){this.$.hitCount.textContent='';this.$.spinner.style.visibility='visible';this.controller.startFiltering(this.$.filter.value).then(function(){this.$.spinner.style.visibility='hidden';this.updateHitCountEl();}.bind(this));},findNext:function(){if(this.controller)
+this.controller.findNext();this.updateHitCountEl();},findPrevious:function(){if(this.controller)
+this.controller.findPrevious();this.updateHitCountEl();},updateHitCountEl:function(){if(!this.controller||!this.hasFocus){this.$.hitCount.textContent='';return;}
+var n=this.controller.filterHits.length;var i=n===0?-1:this.controller.currentHitIndex;this.$.hitCount.textContent=(i+1)+' of '+n;},setText:function(string){this.$.filter.value=string;}});'use strict';tr.exportTo('tr.e.tquery',function(){function Context(){this.event=undefined;this.ancestors=[];}
+Context.prototype={push:function(event){var ctx=new Context();ctx.ancestors=this.ancestors.slice();ctx.ancestors.push(event);return ctx;},pop:function(event){var ctx=new Context();ctx.event=this.ancestors[this.ancestors.length-1];ctx.ancestors=this.ancestors.slice(0,this.ancestors.length-1);return ctx;}};return{Context:Context};});'use strict';tr.exportTo('tr.e.tquery',function(){function Filter(){tr.c.ScriptingObject.call(this);}
+Filter.normalizeFilterExpression=function(filterExpression){if(filterExpression instanceof String||typeof(filterExpression)=='string'||filterExpression instanceof RegExp){var filter=new tr.e.tquery.FilterHasTitle(filterExpression);return filter;}
+return filterExpression;};Filter.prototype={__proto__:tr.c.ScriptingObject.prototype,evaluate:function(context){throw new Error('Not implemented');},matchValue_:function(value,expected){if(expected instanceof RegExp)
+return expected.test(value);else if(expected instanceof Function)
+return expected(value);return value===expected;}};return{Filter:Filter};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterAllOf(opt_subExpressions){tr.e.tquery.Filter.call(this);this.subExpressions=opt_subExpressions||[];}
+FilterAllOf.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpressions(exprs){this.subExpressions_=[];for(var i=0;i<exprs.length;i++){this.subExpressions_.push(tr.e.tquery.Filter.normalizeFilterExpression(exprs[i]));}},get subExpressions(){return this.subExpressions_;},evaluate:function(context){if(!this.subExpressions.length)
+return true;for(var i=0;i<this.subExpressions.length;i++){if(!this.subExpressions[i].evaluate(context))
+return false;}
+return true;}};tr.c.ScriptingObjectRegistry.register(function(){var exprs=[];for(var i=0;i<arguments.length;i++){exprs.push(arguments[i]);}
+return new FilterAllOf(exprs);},{name:'allOf'});return{FilterAllOf:FilterAllOf};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterAnyOf(opt_subExpressions){tr.e.tquery.Filter.call(this);this.subExpressions=opt_subExpressions||[];};FilterAnyOf.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpressions(exprs){this.subExpressions_=[];for(var i=0;i<exprs.length;i++){this.subExpressions_.push(tr.e.tquery.Filter.normalizeFilterExpression(exprs[i]));}},get subExpressions(){return this.subExpressions_;},evaluate:function(context){if(!this.subExpressions.length)
+return true;for(var i=0;i<this.subExpressions.length;i++){if(this.subExpressions[i].evaluate(context))
+return true;}
+return false;}};tr.c.ScriptingObjectRegistry.register(function(){var exprs=[];for(var i=0;i<arguments.length;i++){exprs.push(arguments[i]);}
+return new FilterAnyOf(exprs);},{name:'anyOf'});return{FilterAnyOf:FilterAnyOf};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterHasAncestor(opt_subExpression){this.subExpression=opt_subExpression;};FilterHasAncestor.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpression(expr){this.subExpression_=tr.e.tquery.Filter.normalizeFilterExpression(expr);},get subExpression(){return this.subExpression_;},evaluate:function(context){if(!this.subExpression)
+return context.ancestors.length>0;while(context.ancestors.length){context=context.pop();if(this.subExpression.evaluate(context))
+return true;}
+return false;}};tr.c.ScriptingObjectRegistry.register(function(subExpression){return new FilterHasAncestor(subExpression);},{name:'hasAncestor'});return{FilterHasAncestor:FilterHasAncestor};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterHasDuration(minValueOrExpected,opt_maxValue){if(minValueOrExpected!==undefined&&opt_maxValue!==undefined){this.minValue=minValueOrExpected;this.maxValue=opt_maxValue;}else{this.expected=minValueOrExpected;}};FilterHasDuration.prototype={__proto__:tr.e.tquery.Filter.prototype,evaluate:function(context){if(context.event.duration===undefined)
+return false;if(this.minValue!==undefined&&this.maxValue!==undefined){return context.event.duration>=this.minValue&&context.event.duration<=this.maxValue;}
+return this.matchValue_(context.event.duration,this.expected);}};tr.c.ScriptingObjectRegistry.register(function(minValueOrExpected,opt_maxValue){return new FilterHasDuration(minValueOrExpected,opt_maxValue);},{name:'hasDuration'});return{FilterHasDuration:FilterHasDuration};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterHasTitle(expected){tr.e.tquery.Filter.call(this);this.expected=expected;}
+FilterHasTitle.prototype={__proto__:tr.e.tquery.Filter.prototype,evaluate:function(context){return this.matchValue_(context.event.title,this.expected);}};tr.c.ScriptingObjectRegistry.register(function(expected){var filter=new tr.e.tquery.FilterHasTitle(expected);return filter;},{name:'hasTitle'});return{FilterHasTitle:FilterHasTitle};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterIsTopLevel(opt_subExpression){this.subExpression=opt_subExpression;}
+FilterIsTopLevel.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpression(expr){this.subExpression_=tr.e.tquery.Filter.normalizeFilterExpression(expr);},get subExpression(){return this.subExpression_;},evaluate:function(context){if(context.ancestors.length>0)
+return false;if(!this.subExpression)
+return true;return this.subExpression.evaluate(context);}};tr.c.ScriptingObjectRegistry.register(function(subExpression){return new FilterIsTopLevel(subExpression);},{name:'isTopLevel'});return{FilterIsTopLevel:FilterIsTopLevel};});'use strict';tr.exportTo('tr.e.tquery',function(){function addEventTreeToSelection(selection,event){selection.push(event);if(!event.subSlices)
+return;event.subSlices.forEach(addEventTreeToSelection.bind(undefined,selection));}
+function TQuery(model){tr.c.ScriptingObject.call(this);this.model_=model;this.parent_=undefined;this.filterExpression_=undefined;this.selection_=undefined;};TQuery.prototype={__proto__:tr.c.ScriptingObject.prototype,onModelChanged:function(model){this.model_=model;this.selection_=undefined;},get brushingStateController(){return this.brushingStateController_;},filter:function(filterExpression){var result=new TQuery(this.model_);result.parent_=this;result.filterExpression_=tr.e.tquery.Filter.normalizeFilterExpression(filterExpression);return result;},createFilterTaskGraph_:function(){var nodes=[];var node=this;while(node!==undefined){nodes.push(node);node=node.parent_;}
+var rootTask=new tr.b.Task();var lastTask=rootTask;for(var i=nodes.length-1;i>=0;i--){var node=nodes[i];if(node.selection_!==undefined)
+continue;node.selection_=new tr.model.EventSet();if(node.parent_===undefined){lastTask=lastTask.after(this.selectEverythingAsTask_(node.selection_));}else{var prevNode=nodes[i+1];lastTask=this.createFilterTaskForNode_(lastTask,node,prevNode);}}
+return{rootTask:rootTask,lastTask:lastTask,lastNode:node};},createFilterTaskForNode_:function(lastTask,node,prevNode){return lastTask.after(function(){node.evaluateFilterExpression_(prevNode.selection_,node.selection_);},this);},evaluateFilterExpression_:function(inputSelection,outputSelection){var seenEvents={};inputSelection.forEach(function(event){var context=new tr.e.tquery.Context();context.event=event;this.evaluateFilterExpressionForEvent_(context,inputSelection,outputSelection,seenEvents);}.bind(this));},evaluateFilterExpressionForEvent_:function(context,inputSelection,outputSelection,seenEvents){var event=context.event;if(inputSelection.contains(event)&&!seenEvents[event.guid]){seenEvents[event.guid]=true;if(!this.filterExpression_||this.filterExpression_.evaluate(context))
+outputSelection.push(event);}
+if(!event.subSlices)
+return;context=context.push(event);for(var i=0;i<event.subSlices.length;i++){context.event=event.subSlices[i];this.evaluateFilterExpressionForEvent_(context,inputSelection,outputSelection,seenEvents);}},selectEverythingAsTask_:function(selection){var filterTask=new tr.b.Task();this.model_.iterateAllEventContainers(function(container){filterTask.subTask(function(){container.iterateAllEventsInThisContainer(function(){return true;},addEventTreeToSelection.bind(undefined,selection));},this);},this);return filterTask;},ready:function(){return new Promise(function(resolve,reject){var graph=this.createFilterTaskGraph_();graph.lastTask=graph.lastTask.after(function(){resolve(this.selection_);},this);tr.b.Task.RunWhenIdle(graph.rootTask);}.bind(this));},get selection(){if(this.selection_===undefined){var graph=this.createFilterTaskGraph_();tr.b.Task.RunSynchronously(graph.rootTask);}
+return this.selection_;}};tr.c.ScriptingObjectRegistry.register(new TQuery(),{name:'$t'});return{TQuery:TQuery};});'use strict';Polymer('tr-ui-scripting-control',{_isEnterKey:function(event){return event.keyCode!==229&&event.keyIdentifier==='Enter';},_setFocused:function(focused){var promptEl=this.$.prompt;if(focused){promptEl.focus();this.$.root.classList.add('focused');if(promptEl.innerText.length>0){var sel=window.getSelection();sel.collapse(promptEl.firstChild,promptEl.innerText.length);}}else{promptEl.blur();this.$.root.classList.remove('focused');var parent=promptEl.parentElement;var nextEl=promptEl.nextSibling;promptEl.remove();parent.insertBefore(promptEl,nextEl);}},onConsoleFocus:function(e){e.stopPropagation();this._setFocused(true);},onConsoleBlur:function(e){e.stopPropagation();this._setFocused(false);},promptKeyDown:function(e){e.stopPropagation();if(!this._isEnterKey(e))
+return;var promptEl=this.$.prompt;var command=promptEl.innerText;if(command.length===0)
+return;promptEl.innerText='';this.addLine_(String.fromCharCode(187)+' '+command);try{var result=this.controller_.executeCommand(command);}catch(e){result=e.stack||e.stackTrace;}
+if(result instanceof tr.e.tquery.TQuery){result.ready().then(function(selection){this.addLine_(selection.length+' matches');this.controller_.brushingStateController.showScriptControlSelection(selection);}.bind(this));}else{this.addLine_(result);}},addLine_:function(line){var historyEl=this.$.history;if(historyEl.innerText.length!==0)
+historyEl.innerText+='\n';historyEl.innerText+=line;},promptKeyPress:function(e){e.stopPropagation();},toggleVisibility:function(){var root=this.$.root;if(!this.visible){root.classList.remove('hidden');this._setFocused(true);}else{root.classList.add('hidden');this._setFocused(false);}},get hasFocus(){return this===document.activeElement;},get visible(){var root=this.$.root;return!root.classList.contains('hidden');},get controller(){return this.controller_;},set controller(c){this.controller_=c;}});'use strict';Polymer('tr-ui-side-panel',{ready:function(){},get rangeOfInterest(){throw new Error('Not implemented');},set rangeOfInterest(rangeOfInterest){throw new Error('Not implemented');},get selection(){throw new Error('Not implemented');},set selection(selection){throw new Error('Not implemented');},get model(){throw new Error('Not implemented');},set model(model){throw new Error('Not implemented');},get listeningToKeys(){throw new Error('Not implemented');},supportsModel:function(m){throw new Error('Not implemented');}});'use strict';Polymer('tr-ui-side-panel-container',{ready:function(){this.activePanelContainer_=this.$.active_panel_container;this.tabStrip_=this.$.tab_strip;this.rangeOfInterest_=new tr.b.Range();this.brushingStateController_=undefined;this.onSelectionChanged_=this.onSelectionChanged_.bind(this);this.onModelChanged_=this.onModelChanged_.bind(this);},get brushingStateController(){return this.brushingStateController_;},set brushingStateController(brushingStateController){if(this.brushingStateController){this.brushingStateController_.removeEventListener('change',this.onSelectionChanged_);this.brushingStateController_.removeEventListener('model-changed',this.onModelChanged_);}
+this.brushingStateController_=brushingStateController;if(this.brushingStateController){this.brushingStateController_.addEventListener('change',this.onSelectionChanged_);this.brushingStateController_.addEventListener('model-changed',this.onModelChanged_);}},get selection(){return this.brushingStateController_.selection;},onSelectionChanged_:function(){if(this.activePanel)
+this.activePanel.selection=this.selection;},get model(){return this.brushingStateController_.model;},onModelChanged_:function(){this.activePanelType_=undefined;this.updateContents_();},get expanded(){this.hasAttribute('expanded');},get activePanel(){if(this.activePanelContainer_.children.length===0)
+return undefined;return this.activePanelContainer_.children[0];},get activePanelType(){return this.activePanelType_;},set activePanelType(panelType){if(this.model===undefined)
+throw new Error('Cannot activate panel without a model');var panel=undefined;if(panelType)
+panel=document.createElement(panelType);if(panel!==undefined&&!panel.supportsModel(this.model))
+throw new Error('Cannot activate panel: does not support this model');if(this.activePanelType){this.getLabelElementForPanelType_(this.activePanelType).removeAttribute('selected');}
+this.activePanelContainer_.textContent='';if(panelType===undefined){this.removeAttribute('expanded');this.activePanelType_=undefined;return;}
+this.getLabelElementForPanelType_(panelType).setAttribute('selected',true);this.setAttribute('expanded',true);this.activePanelContainer_.appendChild(panel);panel.rangeOfInterest=this.rangeOfInterest_;panel.selection=this.selection_;panel.model=this.model;this.activePanelType_=panelType;},getPanelTypeForConstructor_:function(constructor){for(var i=0;i<this.tabStrip_.children.length;i++){if(this.tabStrip_.children[i].panelType.constructor==constructor)
+return this.tabStrip_.children[i].panelType;}},getLabelElementForPanelType_:function(panelType){for(var i=0;i<this.tabStrip_.children.length;i++){if(this.tabStrip_.children[i].panelType==panelType)
+return this.tabStrip_.children[i];}
+return undefined;},updateContents_:function(){var previouslyActivePanelType=this.activePanelType;this.tabStrip_.textContent='';var supportedPanelTypes=[];var panelTypes=tr.ui.b.getPolymerElementsThatSubclass('tr-ui-side-panel');panelTypes.forEach(function(panelType){var labelEl=document.createElement('tab-strip-label');var panel=document.createElement(panelType);labelEl.textContent=panel.textLabel;labelEl.panelType=panelType;var supported=panel.supportsModel(this.model);if(this.model&&supported.supported){supportedPanelTypes.push(panelType);labelEl.setAttribute('enabled',true);labelEl.addEventListener('click',function(){this.activePanelType=this.activePanelType===panelType?undefined:panelType;}.bind(this));}else{labelEl.title='Not supported for the current trace: '+
+supported.reason;labelEl.style.display='none';}
+this.tabStrip_.appendChild(labelEl);},this);if(previouslyActivePanelType&&supportedPanelTypes.indexOf(previouslyActivePanelType)!=-1){this.activePanelType=previouslyActivePanelType;this.setAttribute('expanded',true);}else{this.activePanelContainer_.textContent='';this.removeAttribute('expanded');}},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(range){if(range==undefined)
+throw new Error('Must not be undefined');this.rangeOfInterest_=range;if(this.activePanel)
+this.activePanel.rangeOfInterest=range;}});'use strict';Polymer('tr-ui-timeline-view-help-overlay',{ready:function(){var mod=tr.isMac?'cmd ':'ctrl';var spans=this.shadowRoot.querySelectorAll('span.mod');for(var i=0;i<spans.length;i++){spans[i].textContent=mod;}}});'use strict';tr.exportTo('tr.b.u',function(){function GenericTable(items){if(items!==undefined)
+this.items=items;else
+this.items=[];};GenericTable.prototype={};return{GenericTable:GenericTable};});'use strict';tr.exportTo('tr.ui.units',function(){var ArrayOfNumbersSummaryModes={AVERAGE_MODE:'average-mode',TOTAL_MODE:'total-mode'};return{ArrayOfNumbersSummaryModes:ArrayOfNumbersSummaryModes};});'use strict';Polymer('tr-ui-u-array-of-numbers-span',{created:function(){this.numbers_=undefined;this.summaryMode_=tr.ui.units.ArrayOfNumbersSummaryModes.AVERAGE_MODE;},get summaryMode(){return this.summaryMode_;},set summaryMode(summaryMode){this.summaryMode_=summaryMode;this.updateContents_();},get numbers(){return this.numbers_;},set numbers(numbers){if(numbers===undefined){this.numbers_=undefined;this.updateContents_();return;}
+if(!(numbers instanceof Array))
+throw new Error('Must provide an array');this.numbers_=numbers;this.updateContents_();},updateContents_:function(){if(this.numbers_===undefined){this.shadowRoot.textContent='-';return;}
+var ArrayOfNumbersSummaryModes=tr.ui.units.ArrayOfNumbersSummaryModes;var value;if(this.summaryMode_===ArrayOfNumbersSummaryModes.AVERAGE_MODE)
+value=tr.b.Statistics.mean(this.numbers_);else
+value=tr.b.Statistics.sum(this.numbers_);var valueRounded=Math.round(value*1000.0)/1000.0;this.shadowRoot.textContent=valueRounded;}});'use strict';tr.exportTo('tr.ui.units',function(){var TEXT_COLUMN_MODE=1;var NUMERIC_COLUMN_MODE=2;var ELEMENT_COLUMN_MODE=3;function isNumeric(value){if((typeof value)==='number')
+return true;else if(value instanceof Number)
+return true;return false;}
+function GenericTableViewTotalsItem(opt_values){if(opt_values!==undefined)
+this.values=opt_values;else
+this.values=[];}
+function GenericTableViewColumnDescriptor(fieldName,firstFieldValue){this.title=fieldName;this.fieldName=fieldName;this.updateModeGivenValue(firstFieldValue);}
+GenericTableViewColumnDescriptor.prototype={get columnMode(){return this.columnMode_;},get isInNumericMode(){return this.columnMode_===NUMERIC_COLUMN_MODE;},cmp:function(a,b){if(this.columnMode_===ELEMENT_COLUMN_MODE)
+return 0;return tr.b.comparePossiblyUndefinedValues(a,b,function(a,b){var vA=a[this.fieldName];var vB=b[this.fieldName];return tr.b.comparePossiblyUndefinedValues(vA,vB,function(vA,vB){if(vA.localeCompare)
+return vA.localeCompare(vB);return vA-vB;},this);},this);},updateModeGivenValue:function(fieldValue){if(this.columnMode_===undefined){if(fieldValue===undefined||fieldValue===null)
+return;if(isNumeric(fieldValue)){this.columnMode_=NUMERIC_COLUMN_MODE;return;}
+if(fieldValue instanceof HTMLElement){this.columnMode_=ELEMENT_COLUMN_MODE;return;}
+this.columnMode_=TEXT_COLUMN_MODE;return;}
+if(fieldValue===undefined||fieldValue===null)
+return;if(isNumeric(fieldValue))
+return;if(fieldValue instanceof HTMLElement){this.columnMode_=ELEMENT_COLUMN_MODE;return;}
+if(this.columnMode_===NUMERIC_COLUMN_MODE)
+this.columnMode_=TEXT_COLUMN_MODE;},value:function(item){var fieldValue=item[this.fieldName];if(fieldValue instanceof GenericTableViewTotalsItem){var span=document.createElement('tr-ui-u-array-of-numbers-span');span.summaryMode=tr.ui.units.ArrayOfNumbersSummaryModes.TOTAL_MODE;span.numbers=fieldValue.values;return span;}
+if(fieldValue===undefined)
+return'-';if(fieldValue instanceof HTMLElement)
+return fieldValue;if(fieldValue instanceof Object){var gov=document.createElement('tr-ui-a-generic-object-view');gov.object=fieldValue;return gov;}
+return fieldValue;}};Polymer('tr-ui-u-generic-table-view',{created:function(){this.items_=undefined;this.importantColumNames_=[];},get items(){return this.items_;},set items(itemsOrGenericTable){if(itemsOrGenericTable===undefined){this.items_=undefined;}else if(itemsOrGenericTable instanceof Array){this.items_=itemsOrGenericTable;}else if(itemsOrGenericTable instanceof tr.b.u.GenericTable){this.items_=itemsOrGenericTable.items;}
+this.updateContents_();},get importantColumNames(){return this.importantColumNames_;},set importantColumNames(importantColumNames){this.importantColumNames_=importantColumNames;this.updateContents_();},createColumns_:function(){var columnsByName={};this.items_.forEach(function(item){tr.b.iterItems(item,function(itemFieldName,itemFieldValue){var colDesc=columnsByName[itemFieldName];if(colDesc!==undefined){colDesc.updateModeGivenValue(itemFieldValue);return;}
+colDesc=new GenericTableViewColumnDescriptor(itemFieldName,itemFieldValue);columnsByName[itemFieldName]=colDesc;},this);},this);var columns=tr.b.dictionaryValues(columnsByName);if(columns.length===0)
+return undefined;var isColumnNameImportant={};var importantColumNames=this.importantColumNames||[];importantColumNames.forEach(function(icn){isColumnNameImportant[icn]=true;});columns.sort(function(a,b){var iA=isColumnNameImportant[a.title]?1:0;var iB=isColumnNameImportant[b.title]?1:0;if((iB-iA)!==0)
+return iB-iA;return a.title.localeCompare(b.title);});var colWidthPercentage;if(columns.length==1)
+colWidthPercentage='100%';else
+colWidthPercentage=(100/(columns.length-1)).toFixed(3)+'%';columns[0].width='250px';for(var i=1;i<columns.length;i++)
+columns[i].width=colWidthPercentage;return columns;},createFooterRowsIfNeeded_:function(columns){var hasColumnThatIsNumeric=columns.some(function(column){return column.isInNumericMode;});if(!hasColumnThatIsNumeric)
+return[];var totalsItems={};columns.forEach(function(column){if(!column.isInNumericMode)
+return;var totalsItem=new GenericTableViewTotalsItem();this.items_.forEach(function(item){var fieldValue=item[column.fieldName];if(fieldValue===undefined||fieldValue===null)
+return;totalsItem.values.push(fieldValue);});totalsItems[column.fieldName]=totalsItem;},this);return[totalsItems];},updateContents_:function(){var columns;if(this.items_!==undefined)
+columns=this.createColumns_();if(!columns){this.$.table.tableColumns=[];this.$.table.tableRows=[];this.$.table.footerRows=[];return;}
+this.$.table.tableColumns=columns;this.$.table.tableRows=this.items_;this.$.table.footerRows=this.createFooterRowsIfNeeded_(columns);this.$.table.rebuild();},get selectionMode(){return this.$.table.selectionMode;},set selectionMode(selectionMode){this.$.table.selectionMode=selectionMode;},get rowHighlightStyle(){return this.$.table.rowHighlightStyle;},set rowHighlightStyle(rowHighlightStyle){this.$.table.rowHighlightStyle=rowHighlightStyle;},get cellHighlightStyle(){return this.$.table.cellHighlightStyle;},set cellHighlightStyle(cellHighlightStyle){this.$.table.cellHighlightStyle=cellHighlightStyle;}});return{GenericTableViewTotalsItem:GenericTableViewTotalsItem,GenericTableViewColumnDescriptor:GenericTableViewColumnDescriptor};});'use strict';Polymer('tr-ui-timeline-view-metadata-overlay',{created:function(){this.metadata_=undefined;},get metadata(){return this.metadata_;},set metadata(metadata){this.metadata_=metadata;this.$.gtv.items=this.metadata_;}});'use strict';Polymer('tr-ui-u-preferred-display-unit',{ready:function(){this.preferredTimeDisplayMode_=undefined;},attached:function(){tr.b.u.Units.didPreferredTimeDisplayUnitChange();},detached:function(){tr.b.u.Units.didPreferredTimeDisplayUnitChange();},get preferredTimeDisplayMode(){return this.preferredTimeDisplayMode_;},set preferredTimeDisplayMode(v){if(this.preferredTimeDisplayMode_===v)
+return;this.preferredTimeDisplayMode_=v;tr.b.u.Units.didPreferredTimeDisplayUnitChange();}});'use strict';Polymer('tr-ui-timeline-view',{ready:function(){this.tabIndex=0;this.titleEl_=this.$.title;this.leftControlsEl_=this.$.left_controls;this.rightControlsEl_=this.$.right_controls;this.collapsingControlsEl_=this.$.collapsing_controls;this.sidePanelContainer_=this.$.side_panel_container;this.brushingStateController_=new tr.c.BrushingStateController(this);this.findCtl_=this.$.view_find_control;this.findCtl_.controller=new tr.ui.FindController(this.brushingStateController_);this.scriptingCtl_=document.createElement('tr-ui-scripting-control');this.scriptingCtl_.controller=new tr.c.ScriptingController(this.brushingStateController_);this.sidePanelContainer_.brushingStateController=this.brushingStateController_;if(window.tr.e&&window.tr.e.rail&&window.tr.e.rail.RAILScore){this.railScoreSpan_=document.createElement('tr-ui-e-rail-rail-score-span');this.rightControls.appendChild(this.railScoreSpan_);}else{this.railScoreSpan_=undefined;}
+this.optionsDropdown_=this.$.view_options_dropdown;this.optionsDropdown_.iconElement.textContent='View Options';this.showFlowEvents_=false;this.optionsDropdown_.appendChild(tr.ui.b.createCheckBox(this,'showFlowEvents','tr.ui.TimelineView.showFlowEvents',false,'Flow events'));this.highlightVSync_=false;this.highlightVSyncCheckbox_=tr.ui.b.createCheckBox(this,'highlightVSync','tr.ui.TimelineView.highlightVSync',false,'Highlight VSync');this.optionsDropdown_.appendChild(this.highlightVSyncCheckbox_);this.initMetadataButton_();this.initConsoleButton_();this.initHelpButton_();this.collapsingControls.appendChild(this.scriptingCtl_);this.dragEl_=this.$.drag_handle;tr.ui.b.decorate(this.dragEl_,tr.ui.b.DragHandle);this.analysisEl_=this.$.analysis;this.analysisEl_.brushingStateController=this.brushingStateController_;this.addEventListener('requestSelectionChange',function(e){var sc=this.brushingStateController_;sc.changeSelectionFromRequestSelectionChangeEvent(e.selection);}.bind(this));this.onViewportChanged_=this.onViewportChanged_.bind(this);this.bindKeyListeners_();this.dragEl_.target=this.analysisEl_;},domReady:function(){this.trackViewContainer_=this.querySelector('#track_view_container');},get globalMode(){return this.hotkeyController.globalMode;},set globalMode(globalMode){globalMode=!!globalMode;this.brushingStateController_.historyEnabled=globalMode;this.hotkeyController.globalMode=globalMode;},get hotkeyController(){return this.$.hkc;},updateDocumentFavicon:function(){var hue;if(!this.model)
+hue='blue';else
+hue=this.model.faviconHue;var faviconData=tr.ui.b.FaviconsByHue[hue];if(faviconData===undefined)
+faviconData=tr.ui.b.FaviconsByHue['blue'];var link=document.head.querySelector('link[rel="shortcut icon"]');if(!link){link=document.createElement('link');link.rel='shortcut icon';document.head.appendChild(link);}
+link.href=faviconData;},get showFlowEvents(){return this.showFlowEvents_;},set showFlowEvents(showFlowEvents){this.showFlowEvents_=showFlowEvents;if(!this.trackView_)
+return;this.trackView_.viewport.showFlowEvents=showFlowEvents;},get highlightVSync(){return this.highlightVSync_;},set highlightVSync(highlightVSync){this.highlightVSync_=highlightVSync;if(!this.trackView_)
+return;this.trackView_.viewport.highlightVSync=highlightVSync;},initHelpButton_:function(){var helpButtonEl=this.$.view_help_button;function onClick(e){var dlg=new tr.ui.b.Overlay();dlg.title='Chrome Tracing Help';dlg.appendChild(document.createElement('tr-ui-timeline-view-help-overlay'));dlg.visible=true;e.stopPropagation();}
+helpButtonEl.addEventListener('click',onClick.bind(this));},initConsoleButton_:function(){var toggleEl=this.$.view_console_button;function onClick(e){this.scriptingCtl_.toggleVisibility();e.stopPropagation();return false;}
+toggleEl.addEventListener('click',onClick.bind(this));},initMetadataButton_:function(){var showEl=this.$.view_metadata_button;function onClick(e){var dlg=new tr.ui.b.Overlay();dlg.title='Metadata for trace';var metadataOverlay=document.createElement('tr-ui-timeline-view-metadata-overlay');metadataOverlay.metadata=this.model.metadata;dlg.appendChild(metadataOverlay);dlg.visible=true;e.stopPropagation();return false;}
+showEl.addEventListener('click',onClick.bind(this));this.updateMetadataButtonVisibility_();},updateMetadataButtonVisibility_:function(){var showEl=this.$.view_metadata_button;showEl.style.display=(this.model&&this.model.metadata.length)?'':'none';},get leftControls(){return this.leftControlsEl_;},get rightControls(){return this.rightControlsEl_;},get collapsingControls(){return this.collapsingControlsEl_;},get viewTitle(){return this.titleEl_.textContent.substring(this.titleEl_.textContent.length-2);},set viewTitle(text){if(text===undefined){this.titleEl_.textContent='';this.titleEl_.hidden=true;return;}
+this.titleEl_.hidden=false;this.titleEl_.textContent=text;},get model(){if(this.trackView_)
+return this.trackView_.model;return undefined;},set model(model){var modelInstanceChanged=model!=this.model;var modelValid=model&&!model.bounds.isEmpty;var importWarningsEl=this.shadowRoot.querySelector('#import-warnings');importWarningsEl.textContent='';if(modelInstanceChanged){if(this.railScoreSpan_)
+this.railScoreSpan_.railScore=undefined;this.trackViewContainer_.textContent='';if(this.trackView_){this.trackView_.viewport.removeEventListener('change',this.onViewportChanged_);this.trackView_.brushingStateController=undefined;this.trackView_.detach();this.trackView_=undefined;}
+this.brushingStateController_.modelWillChange();}
+if(modelValid&&!this.trackView_){this.trackView_=document.createElement('tr-ui-timeline-track-view');this.trackView_.timelineView=this;this.trackView.brushingStateController=this.brushingStateController_;this.trackViewContainer_.appendChild(this.trackView_);this.trackView_.viewport.addEventListener('change',this.onViewportChanged_);}
+if(modelValid){this.trackView_.model=model;this.trackView_.viewport.showFlowEvents=this.showFlowEvents;this.trackView_.viewport.highlightVSync=this.highlightVSync;if(this.railScoreSpan_){var railScore=tr.e.rail.RAILScore.fromModel(model);this.railScoreSpan_.railScore=railScore;}
+this.$.display_unit.preferredTimeDisplayMode=model.intrinsicTimeUnit;}
+if(model){model.importWarningsThatShouldBeShownToUser.forEach(function(importWarning){importWarningsEl.addMessage('Import Warning: '+importWarning.type+': '+
+importWarning.message);},this);}
+if(modelInstanceChanged){this.updateMetadataButtonVisibility_();this.brushingStateController_.modelDidChange();this.onViewportChanged_();}},get brushingStateController(){return this.brushingStateController_;},get trackView(){return this.trackView_;},get settings(){if(!this.settings_)
+this.settings_=new tr.b.Settings();return this.settings_;},set focusElement(value){throw new Error('This is deprecated. Please set globalMode to true.');},bindKeyListeners_:function(){var hkc=this.hotkeyController;hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'`'.charCodeAt(0),useCapture:true,thisArg:this,callback:function(e){this.scriptingCtl_.toggleVisibility();if(!this.scriptingCtl_.hasFocus)
+this.focus();e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'/'.charCodeAt(0),useCapture:true,thisArg:this,callback:function(e){if(this.scriptingCtl_.hasFocus)
+return;if(this.findCtl_.hasFocus)
+this.focus();else
+this.findCtl_.focus();e.preventDefault();e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'?'.charCodeAt(0),useCapture:false,thisArg:this,callback:function(e){this.$.view_help_button.click();e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'v'.charCodeAt(0),useCapture:false,thisArg:this,callback:function(e){this.toggleHighlightVSync_();e.stopPropagation();}}));},onViewportChanged_:function(e){var spc=this.sidePanelContainer_;if(!this.trackView_){spc.rangeOfInterest.reset();return;}
+var vr=this.trackView_.viewport.interestRange.asRangeObject();if(!spc.rangeOfInterest.equals(vr))
+spc.rangeOfInterest=vr;},toggleHighlightVSync_:function(){this.highlightVSyncCheckbox_.checked=!this.highlightVSyncCheckbox_.checked;},setFindCtlText:function(string){this.findCtl_.setText(string);}});'use strict';tr.exportTo('tr.e.cc',function(){function PictureAsImageData(picture,errorOrImageData){this.picture_=picture;if(errorOrImageData instanceof ImageData){this.error_=undefined;this.imageData_=errorOrImageData;}else{this.error_=errorOrImageData;this.imageData_=undefined;}};PictureAsImageData.Pending=function(picture){return new PictureAsImageData(picture,undefined);};PictureAsImageData.prototype={get picture(){return this.picture_;},get error(){return this.error_;},get imageData(){return this.imageData_;},isPending:function(){return this.error_===undefined&&this.imageData_===undefined;},asCanvas:function(){if(!this.imageData_)
+return;var canvas=document.createElement('canvas');var ctx=canvas.getContext('2d');canvas.width=this.imageData_.width;canvas.height=this.imageData_.height;ctx.putImageData(this.imageData_,0,0);return canvas;}};return{PictureAsImageData:PictureAsImageData};});'use strict';tr.exportTo('tr.e.cc',function(){var convertedNameCache={};function convertNameToJSConvention(name){if(name in convertedNameCache)
+return convertedNameCache[name];if(name[0]=='_'||name[name.length-1]=='_'){convertedNameCache[name]=name;return name;}
+var words=name.split('_');if(words.length==1){convertedNameCache[name]=words[0];return words[0];}
+for(var i=1;i<words.length;i++)
+words[i]=words[i][0].toUpperCase()+words[i].substring(1);convertedNameCache[name]=words.join('');return convertedNameCache[name];}
+function convertObjectFieldNamesToJSConventions(object){tr.b.iterObjectFieldsRecursively(object,function(object,fieldName,fieldValue){delete object[fieldName];object[newFieldName]=fieldValue;return newFieldName;});}
+function convertQuadSuffixedTypesToQuads(object){tr.b.iterObjectFieldsRecursively(object,function(object,fieldName,fieldValue){});}
+function convertObject(object){convertObjectFieldNamesToJSConventions(object);convertQuadSuffixedTypesToQuads(object);}
+function moveRequiredFieldsFromArgsToToplevel(object,fields){for(var i=0;i<fields.length;i++){var key=fields[i];if(object.args[key]===undefined)
+throw Error('Expected field '+key+' not found in args');if(object[key]!==undefined)
+throw Error('Field '+key+' already in object');object[key]=object.args[key];delete object.args[key];}}
+function moveOptionalFieldsFromArgsToToplevel(object,fields){for(var i=0;i<fields.length;i++){var key=fields[i];if(object.args[key]===undefined)
+continue;if(object[key]!==undefined)
+throw Error('Field '+key+' already in object');object[key]=object.args[key];delete object.args[key];}}
+function preInitializeObject(object){preInitializeObjectInner(object.args,false);}
+function preInitializeObjectInner(object,hasRecursed){if(!(object instanceof Object))
+return;if(object instanceof Array){for(var i=0;i<object.length;i++)
+preInitializeObjectInner(object[i],true);return;}
+if(hasRecursed&&(object instanceof tr.model.ObjectSnapshot||object instanceof tr.model.ObjectInstance))
+return;for(var key in object){var newKey=convertNameToJSConvention(key);if(newKey!=key){var value=object[key];delete object[key];object[newKey]=value;key=newKey;}
+if(/Quad$/.test(key)&&!(object[key]instanceof tr.b.Quad)){var q;try{q=tr.b.Quad.from8Array(object[key]);}catch(e){console.log(e);}
+object[key]=q;continue;}
+if(/Rect$/.test(key)&&!(object[key]instanceof tr.b.Rect)){var r;try{r=tr.b.Rect.fromArray(object[key]);}catch(e){console.log(e);}
+object[key]=r;}
+preInitializeObjectInner(object[key],true);}}
+function bytesToRoundedMegabytes(bytes){return Math.round(bytes/100000.0)/10.0;}
+return{preInitializeObject:preInitializeObject,convertNameToJSConvention:convertNameToJSConvention,moveRequiredFieldsFromArgsToToplevel:moveRequiredFieldsFromArgsToToplevel,moveOptionalFieldsFromArgsToToplevel:moveOptionalFieldsFromArgsToToplevel,bytesToRoundedMegabytes:bytesToRoundedMegabytes};});'use strict';tr.exportTo('tr.e.cc',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;var PictureCount=0;var OPS_TIMING_ITERATIONS=3;function Picture(skp64,layerRect){this.skp64_=skp64;this.layerRect_=layerRect;this.guid_=tr.b.GUID.allocate();}
+Picture.prototype={get canSave(){return true;},get layerRect(){return this.layerRect_;},get guid(){return this.guid_;},getBase64SkpData:function(){return this.skp64_;},getOps:function(){if(!PictureSnapshot.CanGetOps()){console.error(PictureSnapshot.HowToEnablePictureDebugging());return undefined;}
+var ops=window.chrome.skiaBenchmarking.getOps({skp64:this.skp64_,params:{layer_rect:this.layerRect_.toArray()}});if(!ops)
+console.error('Failed to get picture ops.');return ops;},getOpTimings:function(){if(!PictureSnapshot.CanGetOpTimings()){console.error(PictureSnapshot.HowToEnablePictureDebugging());return undefined;}
+var opTimings=window.chrome.skiaBenchmarking.getOpTimings({skp64:this.skp64_,params:{layer_rect:this.layerRect_.toArray()}});if(!opTimings)
+console.error('Failed to get picture op timings.');return opTimings;},tagOpsWithTimings:function(ops){var opTimings=new Array();for(var iteration=0;iteration<OPS_TIMING_ITERATIONS;iteration++){opTimings[iteration]=this.getOpTimings();if(!opTimings[iteration]||!opTimings[iteration].cmd_times)
+return ops;if(opTimings[iteration].cmd_times.length!=ops.length)
+return ops;}
+for(var opIndex=0;opIndex<ops.length;opIndex++){var min=Number.MAX_VALUE;for(var i=0;i<OPS_TIMING_ITERATIONS;i++)
+min=Math.min(min,opTimings[i].cmd_times[opIndex]);ops[opIndex].cmd_time=min;}
+return ops;},rasterize:function(params,rasterCompleteCallback){if(!PictureSnapshot.CanRasterize()||!PictureSnapshot.CanGetOps()){rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,tr.e.cc.PictureSnapshot.HowToEnablePictureDebugging()));return;}
+var raster=window.chrome.skiaBenchmarking.rasterize({skp64:this.skp64_,params:{layer_rect:this.layerRect_.toArray()}},{stop:params.stopIndex===undefined?-1:params.stopIndex,overdraw:!!params.showOverdraw,params:{}});if(raster){var canvas=document.createElement('canvas');var ctx=canvas.getContext('2d');canvas.width=raster.width;canvas.height=raster.height;var imageData=ctx.createImageData(raster.width,raster.height);imageData.data.set(new Uint8ClampedArray(raster.data));rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,imageData));}else{var error='Failed to rasterize picture. '+'Your recording may be from an old Chrome version. '+'The SkPicture format is not backward compatible.';rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,error));}}};function LayeredPicture(pictures){this.guid_=tr.b.GUID.allocate();this.pictures_=pictures;this.layerRect_=undefined;}
+LayeredPicture.prototype={__proto__:Picture.prototype,get canSave(){return false;},get typeName(){return'cc::LayeredPicture';},get layerRect(){if(this.layerRect_!==undefined)
+return this.layerRect_;this.layerRect_={x:0,y:0,width:0,height:0};for(var i=0;i<this.pictures_.length;++i){var rect=this.pictures_[i].layerRect;this.layerRect_.x=Math.min(this.layerRect_.x,rect.x);this.layerRect_.y=Math.min(this.layerRect_.y,rect.y);this.layerRect_.width=Math.max(this.layerRect_.width,rect.x+rect.width);this.layerRect_.height=Math.max(this.layerRect_.height,rect.y+rect.height);}
+return this.layerRect_;},get guid(){return this.guid_;},getBase64SkpData:function(){throw new Error('Not available with a LayeredPicture.');},getOps:function(){var ops=[];for(var i=0;i<this.pictures_.length;++i)
+ops=ops.concat(this.pictures_[i].getOps());return ops;},getOpTimings:function(){var opTimings=this.pictures_[0].getOpTimings();for(var i=1;i<this.pictures_.length;++i){var timings=this.pictures_[i].getOpTimings();opTimings.cmd_times=opTimings.cmd_times.concat(timings.cmd_times);opTimings.total_time+=timings.total_time;}
+return opTimings;},tagOpsWithTimings:function(ops){var opTimings=new Array();for(var iteration=0;iteration<OPS_TIMING_ITERATIONS;iteration++){opTimings[iteration]=this.getOpTimings();if(!opTimings[iteration]||!opTimings[iteration].cmd_times)
+return ops;}
+for(var opIndex=0;opIndex<ops.length;opIndex++){var min=Number.MAX_VALUE;for(var i=0;i<OPS_TIMING_ITERATIONS;i++)
+min=Math.min(min,opTimings[i].cmd_times[opIndex]);ops[opIndex].cmd_time=min;}
+return ops;},rasterize:function(params,rasterCompleteCallback){this.picturesAsImageData_=[];var rasterCallback=function(pictureAsImageData){this.picturesAsImageData_.push(pictureAsImageData);if(this.picturesAsImageData_.length!==this.pictures_.length)
+return;var canvas=document.createElement('canvas');var ctx=canvas.getContext('2d');canvas.width=this.layerRect.width;canvas.height=this.layerRect.height;for(var i=0;i<this.picturesAsImageData_.length;++i){ctx.putImageData(this.picturesAsImageData_[i].imageData,this.pictures_[i].layerRect.x,this.pictures_[i].layerRect.y);}
+this.picturesAsImageData_=[];rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,ctx.getImageData(this.layerRect.x,this.layerRect.y,this.layerRect.width,this.layerRect.height)));}.bind(this);for(var i=0;i<this.pictures_.length;++i)
+this.pictures_[i].rasterize(params,rasterCallback);}};function PictureSnapshot(){ObjectSnapshot.apply(this,arguments);}
+PictureSnapshot.HasSkiaBenchmarking=function(){return tr.isExported('chrome.skiaBenchmarking');}
+PictureSnapshot.CanRasterize=function(){if(!PictureSnapshot.HasSkiaBenchmarking())
+return false;if(!window.chrome.skiaBenchmarking.rasterize)
+return false;return true;}
+PictureSnapshot.CanGetOps=function(){if(!PictureSnapshot.HasSkiaBenchmarking())
+return false;if(!window.chrome.skiaBenchmarking.getOps)
+return false;return true;}
+PictureSnapshot.CanGetOpTimings=function(){if(!PictureSnapshot.HasSkiaBenchmarking())
+return false;if(!window.chrome.skiaBenchmarking.getOpTimings)
+return false;return true;}
+PictureSnapshot.CanGetInfo=function(){if(!PictureSnapshot.HasSkiaBenchmarking())
+return false;if(!window.chrome.skiaBenchmarking.getInfo)
+return false;return true;}
+PictureSnapshot.HowToEnablePictureDebugging=function(){if(tr.isHeadless)
+return'Pictures only work in chrome';var usualReason=['For pictures to show up, you need to have Chrome running with ','--enable-skia-benchmarking. Please restart chrome with this flag ','and try again.'].join('');if(!tr.isExported('global.chrome.skiaBenchmarking'))
+return usualReason;if(!global.chrome.skiaBenchmarking.rasterize)
+return'Your chrome is old';if(!global.chrome.skiaBenchmarking.getOps)
+return'Your chrome is old: skiaBenchmarking.getOps not found';if(!global.chrome.skiaBenchmarking.getOpTimings)
+return'Your chrome is old: skiaBenchmarking.getOpTimings not found';if(!global.chrome.skiaBenchmarking.getInfo)
+return'Your chrome is old: skiaBenchmarking.getInfo not found';return'Rasterizing is on';}
+PictureSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);this.rasterResult_=undefined;},initialize:function(){if(this.args.alias)
+this.args=this.args.alias.args;if(!this.args.params.layerRect)
+throw new Error('Missing layer rect');this.layerRect_=this.args.params.layerRect;this.picture_=new Picture(this.args.skp64,this.args.params.layerRect);},set picture(picture){this.picture_=picture;},get canSave(){return this.picture_.canSave;},get layerRect(){return this.layerRect_?this.layerRect_:this.picture_.layerRect;},get guid(){return this.picture_.guid;},getBase64SkpData:function(){return this.picture_.getBase64SkpData();},getOps:function(){return this.picture_.getOps();},getOpTimings:function(){return this.picture_.getOpTimings();},tagOpsWithTimings:function(ops){return this.picture_.tagOpsWithTimings(ops);},rasterize:function(params,rasterCompleteCallback){this.picture_.rasterize(params,rasterCompleteCallback);}};ObjectSnapshot.register(PictureSnapshot,{typeNames:['cc::Picture']});return{PictureSnapshot:PictureSnapshot,Picture:Picture,LayeredPicture:LayeredPicture};});'use strict';tr.exportTo('tr.e.cc',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function DisplayItemList(skp64,layerRect){tr.e.cc.Picture.apply(this,arguments);}
+DisplayItemList.prototype={__proto__:tr.e.cc.Picture.prototype};function DisplayItemListSnapshot(){tr.e.cc.PictureSnapshot.apply(this,arguments);}
+DisplayItemListSnapshot.prototype={__proto__:tr.e.cc.PictureSnapshot.prototype,initialize:function(){tr.e.cc.PictureSnapshot.prototype.initialize.call(this);this.displayItems_=this.args.params.items;},get items(){return this.displayItems_;}};ObjectSnapshot.register(DisplayItemListSnapshot,{typeNames:['cc::DisplayItemList']});return{DisplayItemListSnapshot:DisplayItemListSnapshot,DisplayItemList:DisplayItemList};});'use strict';tr.exportTo('tr.e.cc',function(){var constants={};constants.ACTIVE_TREE=0;constants.PENDING_TREE=1;constants.HIGH_PRIORITY_BIN=0;constants.LOW_PRIORITY_BIN=1;constants.SEND_BEGIN_FRAME_EVENT='ThreadProxy::ScheduledActionSendBeginMainFrame';constants.BEGIN_MAIN_FRAME_EVENT='ThreadProxy::BeginMainFrame';return{constants:constants};});'use strict';tr.exportTo('tr.e.cc',function(){function Region(){this.rects=[];}
+Region.fromArray=function(array){if(array.length%4!=0)
+throw new Error('Array must consist be a multiple of 4 in length');var r=new Region();for(var i=0;i<array.length;i+=4){r.rects.push(tr.b.Rect.fromXYWH(array[i],array[i+1],array[i+2],array[i+3]));}
+return r;}
+Region.fromArrayOrUndefined=function(array){if(array===undefined)
+return new Region();return Region.fromArray(array);};Region.prototype={__proto__:Region.prototype,rectIntersects:function(r){for(var i=0;i<this.rects.length;i++){if(this.rects[i].intersects(r))
+return true;}
+return false;},addRect:function(r){this.rects.push(r);}};return{Region:Region};});'use strict';tr.exportTo('tr.e.cc',function(){function TileCoverageRect(rect,tile){this.geometryRect=rect;this.tile=tile;}
+return{TileCoverageRect:TileCoverageRect};});'use strict';tr.exportTo('tr.e.cc',function(){var constants=tr.e.cc.constants;var ObjectSnapshot=tr.model.ObjectSnapshot;function LayerImplSnapshot(){ObjectSnapshot.apply(this,arguments);}
+LayerImplSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);this.layerTreeImpl_=undefined;this.parentLayer=undefined;},initialize:function(){this.invalidation=new tr.e.cc.Region();this.annotatedInvalidation=new tr.e.cc.Region();this.unrecordedRegion=new tr.e.cc.Region();this.pictures=[];tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['layerId','children','layerQuad']);tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['maskLayer','replicaLayer','idealContentsScale','geometryContentsScale','layoutRects','usingGpuRasterization']);this.gpuMemoryUsageInBytes=this.args.gpuMemoryUsage;this.bounds=tr.b.Rect.fromXYWH(0,0,this.args.bounds.width,this.args.bounds.height);if(this.args.animationBounds){this.animationBoundsRect=tr.b.Rect.fromXYWH(this.args.animationBounds[0],this.args.animationBounds[1],this.args.animationBounds[3],this.args.animationBounds[4]);}
+for(var i=0;i<this.children.length;i++)
+this.children[i].parentLayer=this;if(this.maskLayer)
+this.maskLayer.parentLayer=this;if(this.replicaLayer)
+this.replicaLayer.parentLayer=this;if(!this.geometryContentsScale)
+this.geometryContentsScale=1.0;if(!this.idealContentsScale)
+this.idealContentsScale=1.0;this.touchEventHandlerRegion=tr.e.cc.Region.fromArrayOrUndefined(this.args.touchEventHandlerRegion);this.wheelEventHandlerRegion=tr.e.cc.Region.fromArrayOrUndefined(this.args.wheelEventHandlerRegion);this.nonFastScrollableRegion=tr.e.cc.Region.fromArrayOrUndefined(this.args.nonFastScrollableRegion);},get layerTreeImpl(){if(this.layerTreeImpl_)
+return this.layerTreeImpl_;if(this.parentLayer)
+return this.parentLayer.layerTreeImpl;return undefined;},set layerTreeImpl(layerTreeImpl){this.layerTreeImpl_=layerTreeImpl;},get activeLayer(){if(this.layerTreeImpl.whichTree==constants.ACTIVE_TREE)
+return this;var activeTree=this.layerTreeImpl.layerTreeHostImpl.activeTree;return activeTree.findLayerWithId(this.layerId);},get pendingLayer(){if(this.layerTreeImpl.whichTree==constants.PENDING_TREE)
+return this;var pendingTree=this.layerTreeImpl.layerTreeHostImpl.pendingTree;return pendingTree.findLayerWithId(this.layerId);}};function PictureLayerImplSnapshot(){LayerImplSnapshot.apply(this,arguments);}
+PictureLayerImplSnapshot.prototype={__proto__:LayerImplSnapshot.prototype,initialize:function(){LayerImplSnapshot.prototype.initialize.call(this);if(this.args.invalidation){this.invalidation=tr.e.cc.Region.fromArray(this.args.invalidation);delete this.args.invalidation;}
+if(this.args.annotatedInvalidationRects){this.annotatedInvalidation=new tr.e.cc.Region();for(var i=0;i<this.args.annotatedInvalidationRects.length;++i){var annotatedRect=this.args.annotatedInvalidationRects[i];var rect=annotatedRect.geometryRect;rect.reason=annotatedRect.reason;this.annotatedInvalidation.addRect(rect);}
+delete this.args.annotatedInvalidationRects;}
+if(this.args.unrecordedRegion){this.unrecordedRegion=tr.e.cc.Region.fromArray(this.args.unrecordedRegion);delete this.args.unrecordedRegion;}
+if(this.args.pictures){this.pictures=this.args.pictures;this.pictures.sort(function(a,b){return a.ts-b.ts;});}
+this.tileCoverageRects=[];if(this.args.coverageTiles){for(var i=0;i<this.args.coverageTiles.length;++i){var rect=this.args.coverageTiles[i].geometryRect.scale(this.idealContentsScale);var tile=this.args.coverageTiles[i].tile;this.tileCoverageRects.push(new tr.e.cc.TileCoverageRect(rect,tile));}
+delete this.args.coverageTiles;}}};ObjectSnapshot.register(PictureLayerImplSnapshot,{typeName:'cc::PictureLayerImpl'});ObjectSnapshot.register(LayerImplSnapshot,{typeNames:['cc::LayerImpl','cc::DelegatedRendererLayerImpl','cc::HeadsUpDisplayLayerImpl','cc::IOSurfaceLayerImpl','cc::NinePatchLayerImpl','cc::PictureImageLayerImpl','cc::ScrollbarLayerImpl','cc::SolidColorLayerImpl','cc::SurfaceLayerImpl','cc::TextureLayerImpl','cc::TiledLayerImpl','cc::VideoLayerImpl','cc::PaintedScrollbarLayerImpl','ClankPatchLayer','TabBorderLayer','CounterLayer']});return{LayerImplSnapshot:LayerImplSnapshot,PictureLayerImplSnapshot:PictureLayerImplSnapshot};});'use strict';tr.exportTo('tr.e.cc',function(){var constants=tr.e.cc.constants;var ObjectSnapshot=tr.model.ObjectSnapshot;function LayerTreeImplSnapshot(){ObjectSnapshot.apply(this,arguments);}
+LayerTreeImplSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);this.layerTreeHostImpl=undefined;this.whichTree=undefined;this.sourceFrameNumber=undefined;},initialize:function(){tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['rootLayer','renderSurfaceLayerList']);if(this.args.sourceFrameNumber)
+this.sourceFrameNumber=this.args.sourceFrameNumber;this.rootLayer.layerTreeImpl=this;if(this.args.swapPromiseTraceIds&&this.args.swapPromiseTraceIds.length){this.tracedInputLatencies=[];var ownProcess=this.objectInstance.parent;var model=ownProcess.model;if(tr.e.audits.ChromeModelHelper.supportsModel(model))
+this._initializeTracedInputLatencies(model);}},_initializeTracedInputLatencies:function(model){var modelHelper=new tr.e.audits.ChromeModelHelper(model);if(!modelHelper.browserHelper)
+return;var latencyEvents=modelHelper.browserHelper.getLatencyEventsInRange(model.bounds);latencyEvents.forEach(function(event){for(var i=0;i<this.args.swapPromiseTraceIds.length;i++){if(!event.args.data||!event.args.data.trace_id)
+continue;if(parseInt(event.args.data.trace_id)===this.args.swapPromiseTraceIds[i])
+this.tracedInputLatencies.push(event);}},this);},get hasSourceFrameBeenDrawnBefore(){if(this.whichTree==tr.e.cc.constants.PENDING_TREE)
+return false;if(this.sourceFrameNumber===undefined)
+return;var thisLTHI=this.layerTreeHostImpl;var thisLTHIIndex=thisLTHI.objectInstance.snapshots.indexOf(thisLTHI);var prevLTHIIndex=thisLTHIIndex-1;if(prevLTHIIndex<0||prevLTHIIndex>=thisLTHI.objectInstance.snapshots.length)
+return false;var prevLTHI=thisLTHI.objectInstance.snapshots[prevLTHIIndex];if(!prevLTHI.activeTree)
+return false;if(prevLTHI.activeTree.sourceFrameNumber===undefined)
+return;return prevLTHI.activeTree.sourceFrameNumber==this.sourceFrameNumber;},get otherTree(){var other=this.whichTree==constants.ACTIVE_TREE?constants.PENDING_TREE:constants.ACTIVE_TREE;return this.layerTreeHostImpl.getTree(other);},get gpuMemoryUsageInBytes(){var totalBytes=0;this.iterLayers(function(layer){if(layer.gpuMemoryUsageInBytes!==undefined)
+totalBytes+=layer.gpuMemoryUsageInBytes;});return totalBytes;},iterLayers:function(func,thisArg){var visitedLayers={};function visitLayer(layer,depth,isMask,isReplica){if(visitedLayers[layer.layerId])
+return;visitedLayers[layer.layerId]=true;func.call(thisArg,layer,depth,isMask,isReplica);if(layer.children){for(var i=0;i<layer.children.length;i++)
+visitLayer(layer.children[i],depth+1);}
+if(layer.maskLayer)
+visitLayer(layer.maskLayer,depth+1,true,false);if(layer.replicaLayer)
+visitLayer(layer.replicaLayer,depth+1,false,true);}
+visitLayer(this.rootLayer,0,false,false);},findLayerWithId:function(id){var foundLayer=undefined;function visitLayer(layer){if(layer.layerId==id)
+foundLayer=layer;}
+this.iterLayers(visitLayer);return foundLayer;}};ObjectSnapshot.register(LayerTreeImplSnapshot,{typeName:'cc::LayerTreeImpl'});return{LayerTreeImplSnapshot:LayerTreeImplSnapshot};});'use strict';tr.exportTo('tr.b',function(){function BBox2(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;};BBox2.prototype={__proto__:Object.prototype,reset:function(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;},get isEmpty(){return this.isEmpty_;},addBBox2:function(bbox2){if(bbox2.isEmpty)
+return;this.addVec2(bbox2.min_);this.addVec2(bbox2.max_);},clone:function(){var bbox=new BBox2();bbox.addBBox2(this);return bbox;},addXY:function(x,y){if(this.isEmpty_){this.max_=vec2.create();this.min_=vec2.create();vec2.set(this.max_,x,y);vec2.set(this.min_,x,y);this.isEmpty_=false;return;}
+this.max_[0]=Math.max(this.max_[0],x);this.max_[1]=Math.max(this.max_[1],y);this.min_[0]=Math.min(this.min_[0],x);this.min_[1]=Math.min(this.min_[1],y);},addVec2:function(value){if(this.isEmpty_){this.max_=vec2.create();this.min_=vec2.create();vec2.set(this.max_,value[0],value[1]);vec2.set(this.min_,value[0],value[1]);this.isEmpty_=false;return;}
+this.max_[0]=Math.max(this.max_[0],value[0]);this.max_[1]=Math.max(this.max_[1],value[1]);this.min_[0]=Math.min(this.min_[0],value[0]);this.min_[1]=Math.min(this.min_[1],value[1]);},addQuad:function(quad){this.addVec2(quad.p1);this.addVec2(quad.p2);this.addVec2(quad.p3);this.addVec2(quad.p4);},get minVec2(){if(this.isEmpty_)
+return undefined;return this.min_;},get maxVec2(){if(this.isEmpty_)
+return undefined;return this.max_;},get sizeAsVec2(){if(this.isEmpty_)
+throw new Error('Empty BBox2 has no size');var size=vec2.create();vec2.subtract(size,this.max_,this.min_);return size;},get size(){if(this.isEmpty_)
+throw new Error('Empty BBox2 has no size');return{width:this.max_[0]-this.min_[0],height:this.max_[1]-this.min_[1]};},get width(){if(this.isEmpty_)
+throw new Error('Empty BBox2 has no width');return this.max_[0]-this.min_[0];},get height(){if(this.isEmpty_)
+throw new Error('Empty BBox2 has no width');return this.max_[1]-this.min_[1];},toString:function(){if(this.isEmpty_)
+return'empty';return'min=('+this.min_[0]+','+this.min_[1]+') '+'max=('+this.max_[0]+','+this.max_[1]+')';},asRect:function(){return tr.b.Rect.fromXYWH(this.min_[0],this.min_[1],this.max_[0]-this.min_[0],this.max_[1]-this.min_[1]);}};return{BBox2:BBox2};});'use strict';tr.exportTo('tr.e.cc',function(){var constants=tr.e.cc.constants;var ObjectSnapshot=tr.model.ObjectSnapshot;var ObjectInstance=tr.model.ObjectInstance;function LayerTreeHostImplSnapshot(){ObjectSnapshot.apply(this,arguments);}
+LayerTreeHostImplSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);},initialize:function(){tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['deviceViewportSize','activeTree']);tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['pendingTree']);if(this.args.activeTiles!==undefined){this.activeTiles=this.args.activeTiles;delete this.args.activeTiles;}else if(this.args.tiles!==undefined){this.activeTiles=this.args.tiles;delete this.args.tiles;}
+if(!this.activeTiles)
+this.activeTiles=[];this.activeTree.layerTreeHostImpl=this;this.activeTree.whichTree=constants.ACTIVE_TREE;if(this.pendingTree){this.pendingTree.layerTreeHostImpl=this;this.pendingTree.whichTree=constants.PENDING_TREE;}},getContentsScaleNames:function(){var scales={};for(var i=0;i<this.activeTiles.length;++i){var tile=this.activeTiles[i];scales[tile.contentsScale]=tile.resolution;}
+return scales;},getTree:function(whichTree){if(whichTree==constants.ACTIVE_TREE)
+return this.activeTree;if(whichTree==constants.PENDING_TREE)
+return this.pendingTree;throw new Exception('Unknown tree type + '+whichTree);},get tilesHaveGpuMemoryUsageInfo(){if(this.tilesHaveGpuMemoryUsageInfo_!==undefined)
+return this.tilesHaveGpuMemoryUsageInfo_;for(var i=0;i<this.activeTiles.length;i++){if(this.activeTiles[i].gpuMemoryUsageInBytes===undefined)
+continue;this.tilesHaveGpuMemoryUsageInfo_=true;return true;}
+this.tilesHaveGpuMemoryUsageInfo_=false;return false;},get gpuMemoryUsageInBytes(){if(!this.tilesHaveGpuMemoryUsageInfo)
+return;var usage=0;for(var i=0;i<this.activeTiles.length;i++){var u=this.activeTiles[i].gpuMemoryUsageInBytes;if(u!==undefined)
+usage+=u;}
+return usage;},get userFriendlyName(){var frameNumber;if(!this.activeTree){frameNumber=this.objectInstance.snapshots.indexOf(this);}else{if(this.activeTree.sourceFrameNumber===undefined)
+frameNumber=this.objectInstance.snapshots.indexOf(this);else
+frameNumber=this.activeTree.sourceFrameNumber;}
+return'cc::LayerTreeHostImpl frame '+frameNumber;}};ObjectSnapshot.register(LayerTreeHostImplSnapshot,{typeName:'cc::LayerTreeHostImpl'});function LayerTreeHostImplInstance(){ObjectInstance.apply(this,arguments);this.allLayersBBox_=undefined;}
+LayerTreeHostImplInstance.prototype={__proto__:ObjectInstance.prototype,get allContentsScales(){if(this.allContentsScales_)
+return this.allContentsScales_;var scales={};for(var tileID in this.allTileHistories_){var tileHistory=this.allTileHistories_[tileID];scales[tileHistory.contentsScale]=true;}
+this.allContentsScales_=tr.b.dictionaryKeys(scales);return this.allContentsScales_;},get allLayersBBox(){if(this.allLayersBBox_)
+return this.allLayersBBox_;var bbox=new tr.b.BBox2();function handleTree(tree){tree.renderSurfaceLayerList.forEach(function(layer){bbox.addQuad(layer.layerQuad);});}
+this.snapshots.forEach(function(lthi){handleTree(lthi.activeTree);if(lthi.pendingTree)
+handleTree(lthi.pendingTree);});this.allLayersBBox_=bbox;return this.allLayersBBox_;}};ObjectInstance.register(LayerTreeHostImplInstance,{typeName:'cc::LayerTreeHostImpl'});return{LayerTreeHostImplSnapshot:LayerTreeHostImplSnapshot,LayerTreeHostImplInstance:LayerTreeHostImplInstance};});'use strict';tr.exportTo('tr.e.cc',function(){var tileTypes={highRes:'highRes',lowRes:'lowRes',extraHighRes:'extraHighRes',extraLowRes:'extraLowRes',missing:'missing',culled:'culled',solidColor:'solidColor',picture:'picture',directPicture:'directPicture',unknown:'unknown'};var tileBorder={highRes:{color:'rgba(80, 200, 200, 0.7)',width:1},lowRes:{color:'rgba(212, 83, 192, 0.7)',width:2},extraHighRes:{color:'rgba(239, 231, 20, 0.7)',width:2},extraLowRes:{color:'rgba(93, 186, 18, 0.7)',width:2},missing:{color:'rgba(255, 0, 0, 0.7)',width:1},culled:{color:'rgba(160, 100, 0, 0.8)',width:1},solidColor:{color:'rgba(128, 128, 128, 0.7)',width:1},picture:{color:'rgba(64, 64, 64, 0.7)',width:1},directPicture:{color:'rgba(127, 255, 0, 1.0)',width:1},unknown:{color:'rgba(0, 0, 0, 1.0)',width:2}};return{tileTypes:tileTypes,tileBorder:tileBorder};});'use strict';tr.exportTo('tr.e.cc',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function TileSnapshot(){ObjectSnapshot.apply(this,arguments);}
+TileSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);},initialize:function(){tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['layerId','contentsScale','contentRect']);if(this.args.managedState){this.resolution=this.args.managedState.resolution;this.isSolidColor=this.args.managedState.isSolidColor;this.isUsingGpuMemory=this.args.managedState.isUsingGpuMemory;this.hasResource=this.args.managedState.hasResource;this.scheduledPriority=this.args.scheduledPriority;this.gpuMemoryUsageInBytes=this.args.gpuMemoryUsage;}else{this.resolution=this.args.resolution;this.isSolidColor=this.args.drawInfo.isSolidColor;this.isUsingGpuMemory=this.args.isUsingGpuMemory;this.hasResource=this.args.hasResource;this.scheduledPriority=this.args.scheduledPriority;this.gpuMemoryUsageInBytes=this.args.gpuMemoryUsage;}
+if(this.contentRect)
+this.layerRect=this.contentRect.scale(1.0/this.contentsScale);if(this.isSolidColor)
+this.type_=tr.e.cc.tileTypes.solidColor;else if(!this.hasResource)
+this.type_=tr.e.cc.tileTypes.missing;else if(this.resolution==='HIGH_RESOLUTION')
+this.type_=tr.e.cc.tileTypes.highRes;else if(this.resolution==='LOW_RESOLUTION')
+this.type_=tr.e.cc.tileTypes.lowRes;else
+this.type_=tr.e.cc.tileTypes.unknown;},getTypeForLayer:function(layer){var type=this.type_;if(type==tr.e.cc.tileTypes.unknown){if(this.contentsScale<layer.idealContentsScale)
+type=tr.e.cc.tileTypes.extraLowRes;else if(this.contentsScale>layer.idealContentsScale)
+type=tr.e.cc.tileTypes.extraHighRes;}
+return type;}};ObjectSnapshot.register(TileSnapshot,{typeName:'cc::Tile'});return{TileSnapshot:TileSnapshot};});'use strict';tr.exportTo('tr.ui.b',function(){var ListView=tr.ui.b.define('x-list-view',tr.ui.b.ContainerThatDecoratesItsChildren);ListView.prototype={__proto__:tr.ui.b.ContainerThatDecoratesItsChildren.prototype,decorate:function(){tr.ui.b.ContainerThatDecoratesItsChildren.prototype.decorate.call(this);this.classList.add('x-list-view');this.onItemClicked_=this.onItemClicked_.bind(this);this.onKeyDown_=this.onKeyDown_.bind(this);this.tabIndex=0;this.addEventListener('keydown',this.onKeyDown_);this.selectionChanged_=false;},decorateChild_:function(item){item.classList.add('list-item');item.addEventListener('click',this.onItemClicked_,true);var listView=this;Object.defineProperty(item,'selected',{configurable:true,set:function(value){var oldSelection=listView.selectedElement;if(oldSelection&&oldSelection!=this&&value)
+listView.selectedElement.removeAttribute('selected');if(value)
+this.setAttribute('selected','selected');else
+this.removeAttribute('selected');var newSelection=listView.selectedElement;if(newSelection!=oldSelection)
+tr.b.dispatchSimpleEvent(listView,'selection-changed',false);},get:function(){return this.hasAttribute('selected');}});},undecorateChild_:function(item){this.selectionChanged_|=item.selected;item.classList.remove('list-item');item.removeEventListener('click',this.onItemClicked_);delete item.selected;},beginDecorating_:function(){this.selectionChanged_=false;},doneDecoratingForNow_:function(){if(this.selectionChanged_)
+tr.b.dispatchSimpleEvent(this,'selection-changed',false);},get selectedElement(){var el=this.querySelector('.list-item[selected]');if(!el)
+return undefined;return el;},set selectedElement(el){if(!el){if(this.selectedElement)
+this.selectedElement.selected=false;return;}
+if(el.parentElement!=this)
+throw new Error('Can only select elements that are children of this list view');el.selected=true;},getElementByIndex:function(index){return this.querySelector('.list-item:nth-child('+index+')');},clear:function(){var changed=this.selectedElement!==undefined;tr.ui.b.ContainerThatDecoratesItsChildren.prototype.clear.call(this);if(changed)
+tr.b.dispatchSimpleEvent(this,'selection-changed',false);},onItemClicked_:function(e){var currentSelectedElement=this.selectedElement;if(currentSelectedElement)
+currentSelectedElement.removeAttribute('selected');var element=e.target;while(element.parentElement!=this)
+element=element.parentElement;if(element!==currentSelectedElement)
+element.setAttribute('selected','selected');tr.b.dispatchSimpleEvent(this,'selection-changed',false);},onKeyDown_:function(e){if(this.selectedElement===undefined)
+return;if(e.keyCode==38){var prev=this.selectedElement.previousSibling;if(prev){prev.selected=true;tr.ui.b.scrollIntoViewIfNeeded(prev);e.preventDefault();return true;}}else if(e.keyCode==40){var next=this.selectedElement.nextSibling;if(next){next.selected=true;tr.ui.b.scrollIntoViewIfNeeded(next);e.preventDefault();return true;}}},addItem:function(textContent){var item=document.createElement('div');item.textContent=textContent;this.appendChild(item);return item;}};return{ListView:ListView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){function Selection(){this.selectionToSetIfClicked=undefined;};Selection.prototype={get specicifity(){throw new Error('Not implemented');},get associatedLayerId(){throw new Error('Not implemented');},get associatedRenderPassId(){throw new Error('Not implemented');},get highlightsByLayerId(){return{};},createAnalysis:function(){throw new Error('Not implemented');},findEquivalent:function(lthi){throw new Error('Not implemented');}};function RenderPassSelection(renderPass,renderPassId){if(!renderPass||(renderPassId===undefined))
+throw new Error('Render pass (with id) is required');this.renderPass_=renderPass;this.renderPassId_=renderPassId;}
+RenderPassSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 1;},get associatedLayerId(){return undefined;},get associatedRenderPassId(){return this.renderPassId_;},get renderPass(){return this.renderPass_;},createAnalysis:function(){var dataView=document.createElement('tr-ui-a-generic-object-view-with-label');dataView.label='RenderPass '+this.renderPassId_;dataView.object=this.renderPass_.args;return dataView;},get title(){return this.renderPass_.objectInstance.typeName;}};function LayerSelection(layer){if(!layer)
+throw new Error('Layer is required');this.layer_=layer;}
+LayerSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 1;},get associatedLayerId(){return this.layer_.layerId;},get associatedRenderPassId(){return undefined;},get layer(){return this.layer_;},createAnalysis:function(){var dataView=document.createElement('tr-ui-a-generic-object-view-with-label');dataView.label='Layer '+this.layer_.layerId;if(this.layer_.usingGpuRasterization)
+dataView.label+=' (GPU-rasterized)';dataView.object=this.layer_.args;return dataView;},get title(){return this.layer_.objectInstance.typeName;},findEquivalent:function(lthi){var layer=lthi.activeTree.findLayerWithId(this.layer_.layerId)||lthi.pendingTree.findLayerWithId(this.layer_.layerId);if(!layer)
+return undefined;return new LayerSelection(layer);}};function TileSelection(tile,opt_data){this.tile_=tile;this.data_=opt_data||{};}
+TileSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 2;},get associatedLayerId(){return this.tile_.layerId;},get highlightsByLayerId(){var highlights={};highlights[this.tile_.layerId]=[{colorKey:this.tile_.objectInstance.typeName,rect:this.tile_.layerRect}];return highlights;},createAnalysis:function(){var analysis=document.createElement('tr-ui-a-generic-object-view-with-label');analysis.label='Tile '+this.tile_.objectInstance.id+' on layer '+
+this.tile_.layerId;if(this.data_){analysis.object={moreInfo:this.data_,tileArgs:this.tile_.args};}else{analysis.object=this.tile_.args;}
+return analysis;},findEquivalent:function(lthi){var tileInstance=this.tile_.tileInstance;if(lthi.ts<tileInstance.creationTs||lthi.ts>=tileInstance.deletionTs)
+return undefined;var tileSnapshot=tileInstance.getSnapshotAt(lthi.ts);if(!tileSnapshot)
+return undefined;return new TileSelection(tileSnapshot);}};function LayerRectSelection(layer,rectType,rect,opt_data){this.layer_=layer;this.rectType_=rectType;this.rect_=rect;this.data_=opt_data!==undefined?opt_data:rect;}
+LayerRectSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 2;},get associatedLayerId(){return this.layer_.layerId;},get highlightsByLayerId(){var highlights={};highlights[this.layer_.layerId]=[{colorKey:this.rectType_,rect:this.rect_}];return highlights;},createAnalysis:function(){var analysis=document.createElement('tr-ui-a-generic-object-view-with-label');analysis.label=this.rectType_+' on layer '+this.layer_.layerId;analysis.object=this.data_;return analysis;},findEquivalent:function(lthi){return undefined;}};function AnimationRectSelection(layer,rect){this.layer_=layer;this.rect_=rect;}
+AnimationRectSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 0;},get associatedLayerId(){return this.layer_.layerId;},createAnalysis:function(){var analysis=document.createElement('tr-ui-a-generic-object-view-with-label');analysis.label='Animation Bounds of layer '+this.layer_.layerId;analysis.object=this.rect_;return analysis;}};return{Selection:Selection,RenderPassSelection:RenderPassSelection,LayerSelection:LayerSelection,TileSelection:TileSelection,LayerRectSelection:LayerRectSelection,AnimationRectSelection:AnimationRectSelection};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var OPS_TIMING_ITERATIONS=3;var ANNOTATION='Comment';var BEGIN_ANNOTATION='BeginCommentGroup';var END_ANNOTATION='EndCommentGroup';var ANNOTATION_ID='ID: ';var ANNOTATION_CLASS='CLASS: ';var ANNOTATION_TAG='TAG: ';var constants=tr.e.cc.constants;var PictureOpsListView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-ops-list-view');PictureOpsListView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.opsList_=new tr.ui.b.ListView();this.appendChild(this.opsList_);this.selectedOp_=undefined;this.selectedOpIndex_=undefined;this.opsList_.addEventListener('selection-changed',this.onSelectionChanged_.bind(this));this.picture_=undefined;},get picture(){return this.picture_;},set picture(picture){this.picture_=picture;this.updateContents_();},updateContents_:function(){this.opsList_.clear();if(!this.picture_)
+return;var ops=this.picture_.getOps();if(!ops)
+return;ops=this.picture_.tagOpsWithTimings(ops);ops=this.opsTaggedWithAnnotations_(ops);for(var i=0;i<ops.length;i++){var op=ops[i];var item=document.createElement('div');item.opIndex=op.opIndex;item.textContent=i+') '+op.cmd_string;if(op.elementInfo.tag||op.elementInfo.id||op.elementInfo.class){var elementInfo=document.createElement('span');elementInfo.classList.add('elementInfo');var tag=op.elementInfo.tag?op.elementInfo.tag:'unknown';var id=op.elementInfo.id?'id='+op.elementInfo.id:undefined;var className=op.elementInfo.class?'class='+
+op.elementInfo.class:undefined;elementInfo.textContent='<'+tag+(id?' ':'')+
+(id?id:'')+(className?' ':'')+
+(className?className:'')+'>';item.appendChild(elementInfo);}
+if(op.info.length>0){var infoItem=document.createElement('div');infoItem.textContent=JSON.stringify(op.info);item.appendChild(infoItem);}
+if(op.cmd_time&&op.cmd_time>=0.0001){var time=document.createElement('span');time.classList.add('time');var rounded=op.cmd_time.toFixed(4);time.textContent='('+rounded+'ms)';item.appendChild(time);}
+this.opsList_.appendChild(item);}},onSelectionChanged_:function(e){var beforeSelectedOp=true;if(this.opsList_.selectedElement===this.selectedOp_){this.opsList_.selectedElement=undefined;beforeSelectedOp=false;this.selectedOpIndex_=undefined;}
+this.selectedOp_=this.opsList_.selectedElement;var ops=this.opsList_.children;for(var i=0;i<ops.length;i++){var op=ops[i];if(op===this.selectedOp_){beforeSelectedOp=false;this.selectedOpIndex_=op.opIndex;}else if(beforeSelectedOp){op.setAttribute('beforeSelection','beforeSelection');}else{op.removeAttribute('beforeSelection');}}
+tr.b.dispatchSimpleEvent(this,'selection-changed',false);},get numOps(){return this.opsList_.children.length;},get selectedOpIndex(){return this.selectedOpIndex_;},set selectedOpIndex(s){this.selectedOpIndex_=s;if(s===undefined){this.opsList_.selectedElement=this.selectedOp_;this.onSelectionChanged_();}else{if(s<0)throw new Error('Invalid index');if(s>=this.numOps)throw new Error('Invalid index');this.opsList_.selectedElement=this.opsList_.getElementByIndex(s+1);tr.ui.b.scrollIntoViewIfNeeded(this.opsList_.selectedElement);}},opsTaggedWithAnnotations_:function(ops){var annotationGroups=new Array();var opsWithoutAnnotations=new Array();for(var opIndex=0;opIndex<ops.length;opIndex++){var op=ops[opIndex];op.opIndex=opIndex;switch(op.cmd_string){case BEGIN_ANNOTATION:annotationGroups.push(new Array());break;case END_ANNOTATION:annotationGroups.pop();break;case ANNOTATION:annotationGroups[annotationGroups.length-1].push(op);break;default:var annotations=new Array();var elementInfo={};annotationGroups.forEach(function(annotationGroup){elementInfo={};annotationGroup.forEach(function(annotation){annotation.info.forEach(function(info){if(info.indexOf(ANNOTATION_TAG)!=-1)
+elementInfo.tag=info.substring(info.indexOf(ANNOTATION_TAG)+
+ANNOTATION_TAG.length).toLowerCase();else if(info.indexOf(ANNOTATION_ID)!=-1)
+elementInfo.id=info.substring(info.indexOf(ANNOTATION_ID)+
+ANNOTATION_ID.length);else if(info.indexOf(ANNOTATION_CLASS)!=-1)
+elementInfo.class=info.substring(info.indexOf(ANNOTATION_CLASS)+
+ANNOTATION_CLASS.length);annotations.push(info);});});});op.annotations=annotations;op.elementInfo=elementInfo;opsWithoutAnnotations.push(op);}}
+return opsWithoutAnnotations;}};return{PictureOpsListView:PictureOpsListView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var THIS_DOC=document.currentScript.ownerDocument;var DisplayItemDebugger=tr.ui.b.define('tr-ui-e-chrome-cc-display-item-debugger');DisplayItemDebugger.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){var node=tr.ui.b.instantiateTemplate('#tr-ui-e-chrome-cc-display-item-debugger-template',THIS_DOC);this.appendChild(node);this.pictureAsImageData_=undefined;this.zoomScaleValue_=1;this.sizeInfo_=this.querySelector('.size');this.rasterArea_=this.querySelector('raster-area');this.rasterCanvas_=this.rasterArea_.querySelector('canvas');this.rasterCtx_=this.rasterCanvas_.getContext('2d');this.trackMouse_();this.displayItemInfo_=this.querySelector('display-item-info');this.displayItemInfo_.addEventListener('click',this.onDisplayItemInfoClick_.bind(this),false);this.displayItemListView_=new tr.ui.b.ListView();this.displayItemListView_.addEventListener('selection-changed',this.onDisplayItemListSelection_.bind(this));this.displayItemInfo_.appendChild(this.displayItemListView_);this.displayListFilename_=this.querySelector('.dlfilename');this.displayListExportButton_=this.querySelector('.dlexport');this.displayListExportButton_.addEventListener('click',this.onExportDisplayListClicked_.bind(this));this.skpFilename_=this.querySelector('.skpfilename');this.skpExportButton_=this.querySelector('.skpexport');this.skpExportButton_.addEventListener('click',this.onExportSkPictureClicked_.bind(this));var leftPanel=this.querySelector('left-panel');var middleDragHandle=new tr.ui.b.DragHandle();middleDragHandle.horizontal=false;middleDragHandle.target=leftPanel;var rightPanel=this.querySelector('right-panel');this.infoBar_=document.createElement('tr-ui-b-info-bar');this.rasterArea_.insertBefore(this.infoBar_,this.rasterCanvas_);this.insertBefore(middleDragHandle,rightPanel);this.picture_=undefined;this.pictureOpsListView_=new tr.ui.e.chrome.cc.PictureOpsListView();rightPanel.insertBefore(this.pictureOpsListView_,this.rasterArea_);this.pictureOpsListDragHandle_=new tr.ui.b.DragHandle();this.pictureOpsListDragHandle_.horizontal=false;this.pictureOpsListDragHandle_.target=this.pictureOpsListView_;rightPanel.insertBefore(this.pictureOpsListDragHandle_,this.rasterArea_);},get picture(){return this.picture_;},set displayItemList(displayItemList){this.displayItemList_=displayItemList;this.picture=this.displayItemList_;this.displayItemListView_.clear();this.displayItemList_.items.forEach(function(item){var newListItem=document.createElement('div');newListItem.innerText=item;var text=item.skp64?item.name:item;this.displayItemListView_.addItem(text);}.bind(this));},set picture(picture){this.picture_=picture;var showOpsList=picture&&picture!==this.displayItemList_;this.updateDrawOpsList_(showOpsList);if(picture){var size=this.getRasterCanvasSize_();this.rasterCanvas_.width=size.width;this.rasterCanvas_.height=size.height;}
+var bounds=this.rasterArea_.getBoundingClientRect();var selectorBounds=this.mouseModeSelector_.getBoundingClientRect();this.mouseModeSelector_.pos={x:(bounds.right-selectorBounds.width-10),y:bounds.top};this.rasterize_();this.scheduleUpdateContents_();},getRasterCanvasSize_:function(){var style=window.getComputedStyle(this.rasterArea_);var width=parseInt(style.width);var height=parseInt(style.height);if(this.picture_){width=Math.max(width,this.picture_.layerRect.width);height=Math.max(height,this.picture_.layerRect.height);}
+return{width:width,height:height};},scheduleUpdateContents_:function(){if(this.updateContentsPending_)
+return;this.updateContentsPending_=true;tr.b.requestAnimationFrameInThisFrameIfPossible(this.updateContents_.bind(this));},updateContents_:function(){this.updateContentsPending_=false;if(this.picture_){this.sizeInfo_.textContent='('+
+this.picture_.layerRect.width+' x '+
+this.picture_.layerRect.height+')';}
+if(!this.pictureAsImageData_)
+return;this.infoBar_.visible=false;this.infoBar_.removeAllButtons();if(this.pictureAsImageData_.error){this.infoBar_.message='Cannot rasterize...';this.infoBar_.addButton('More info...',function(e){var overlay=new tr.ui.b.Overlay();overlay.textContent=this.pictureAsImageData_.error;overlay.visible=true;e.stopPropagation();return false;}.bind(this));this.infoBar_.visible=true;}
+this.drawPicture_();},drawPicture_:function(){var size=this.getRasterCanvasSize_();if(size.width!==this.rasterCanvas_.width)
+this.rasterCanvas_.width=size.width;if(size.height!==this.rasterCanvas_.height)
+this.rasterCanvas_.height=size.height;this.rasterCtx_.clearRect(0,0,size.width,size.height);if(!this.picture_||!this.pictureAsImageData_.imageData)
+return;var imgCanvas=this.pictureAsImageData_.asCanvas();var w=imgCanvas.width;var h=imgCanvas.height;this.rasterCtx_.drawImage(imgCanvas,0,0,w,h,0,0,w*this.zoomScaleValue_,h*this.zoomScaleValue_);},rasterize_:function(){if(this.picture_){this.picture_.rasterize({showOverdraw:false},this.onRasterComplete_.bind(this));}},onRasterComplete_:function(pictureAsImageData){this.pictureAsImageData_=pictureAsImageData;this.scheduleUpdateContents_();},onDisplayItemListSelection_:function(e){var selected=this.displayItemListView_.selectedElement;if(!selected){this.picture=this.displayItemList_;return;}
+var index=Array.prototype.indexOf.call(this.displayItemListView_.children,selected);var displayItem=this.displayItemList_.items[index];if(displayItem&&displayItem.skp64)
+this.picture=new tr.e.cc.Picture(displayItem.skp64,this.displayItemList_.layerRect);else
+this.picture=undefined;},onDisplayItemInfoClick_:function(e){if(e&&e.target==this.displayItemInfo_){this.displayItemListView_.selectedElement=undefined;}},updateDrawOpsList_:function(showOpsList){if(showOpsList){this.pictureOpsListView_.picture=this.picture_;if(this.pictureOpsListView_.numOps>0){this.pictureOpsListView_.classList.add('hasPictureOps');this.pictureOpsListDragHandle_.classList.add('hasPictureOps');}}else{this.pictureOpsListView_.classList.remove('hasPictureOps');this.pictureOpsListDragHandle_.classList.remove('hasPictureOps');}},trackMouse_:function(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this.rasterArea_;this.rasterArea_.appendChild(this.mouseModeSelector_);this.mouseModeSelector_.supportedModeMask=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.mode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.defaultMode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.settingsKey='pictureDebugger.mouseModeSelector';this.mouseModeSelector_.addEventListener('beginzoom',this.onBeginZoom_.bind(this));this.mouseModeSelector_.addEventListener('updatezoom',this.onUpdateZoom_.bind(this));this.mouseModeSelector_.addEventListener('endzoom',this.onEndZoom_.bind(this));},onBeginZoom_:function(e){this.isZooming_=true;this.lastMouseViewPos_=this.extractRelativeMousePosition_(e);e.preventDefault();},onUpdateZoom_:function(e){if(!this.isZooming_)
+return;var currentMouseViewPos=this.extractRelativeMousePosition_(e);this.zoomScaleValue_+=((this.lastMouseViewPos_.y-currentMouseViewPos.y)*0.001);this.zoomScaleValue_=Math.max(this.zoomScaleValue_,0.1);this.drawPicture_();this.lastMouseViewPos_=currentMouseViewPos;},onEndZoom_:function(e){this.lastMouseViewPos_=undefined;this.isZooming_=false;e.preventDefault();},extractRelativeMousePosition_:function(e){return{x:e.clientX-this.rasterArea_.offsetLeft,y:e.clientY-this.rasterArea_.offsetTop};},saveFile_:function(filename,rawData){if(!rawData)
+return;var length=rawData.length;var arrayBuffer=new ArrayBuffer(length);var uint8Array=new Uint8Array(arrayBuffer);for(var c=0;c<length;c++)
+uint8Array[c]=rawData.charCodeAt(c);var blob=new Blob([uint8Array],{type:'application/octet-binary'});var blobUrl=window.URL.createObjectURL(blob);var link=document.createElementNS('http://www.w3.org/1999/xhtml','a');link.href=blobUrl;link.download=filename;var event=document.createEvent('MouseEvents');event.initMouseEvent('click',true,false,window,0,0,0,0,0,false,false,false,false,0,null);link.dispatchEvent(event);},onExportDisplayListClicked_:function(){var rawData=JSON.stringify(this.displayItemList_.items);this.saveFile_(this.displayListFilename_.value,rawData);},onExportSkPictureClicked_:function(){var rawData=atob(this.picture_.getBase64SkpData());this.saveFile_(this.skpFilename_.value,rawData);}};return{DisplayItemDebugger:DisplayItemDebugger};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var DisplayItemSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-display-item-list-view',tr.ui.analysis.ObjectSnapshotView);DisplayItemSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-chrome-cc-display-item-list-view');this.displayItemDebugger_=new tr.ui.e.chrome.cc.DisplayItemDebugger();this.appendChild(this.displayItemDebugger_);},updateContents:function(){if(this.objectSnapshot_&&this.displayItemDebugger_)
+this.displayItemDebugger_.displayItemList=this.objectSnapshot_;}};tr.ui.analysis.ObjectSnapshotView.register(DisplayItemSnapshotView,{typeNames:['cc::DisplayItemList'],showInstances:false});return{DisplayItemSnapshotView:DisplayItemSnapshotView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var constants=tr.e.cc.constants;var bytesToRoundedMegabytes=tr.e.cc.bytesToRoundedMegabytes;var RENDER_PASS_QUADS=Math.max(constants.ACTIVE_TREE,constants.PENDING_TREE)+1;var LayerPicker=tr.ui.b.define('tr-ui-e-chrome-cc-layer-picker');LayerPicker.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.lthi_=undefined;this.controls_=document.createElement('top-controls');this.renderPassQuads_=false;this.itemList_=new tr.ui.b.ListView();this.appendChild(this.controls_);this.appendChild(this.itemList_);this.itemList_.addEventListener('selection-changed',this.onItemSelectionChanged_.bind(this));this.controls_.appendChild(tr.ui.b.createSelector(this,'whichTree','layerPicker.whichTree',constants.ACTIVE_TREE,[{label:'Active tree',value:constants.ACTIVE_TREE},{label:'Pending tree',value:constants.PENDING_TREE},{label:'Render pass quads',value:RENDER_PASS_QUADS}]));this.showPureTransformLayers_=false;var showPureTransformLayers=tr.ui.b.createCheckBox(this,'showPureTransformLayers','layerPicker.showPureTransformLayers',false,'Transform layers');showPureTransformLayers.classList.add('show-transform-layers');showPureTransformLayers.title='When checked, pure transform layers are shown';this.controls_.appendChild(showPureTransformLayers);},get lthiSnapshot(){return this.lthiSnapshot_;},set lthiSnapshot(lthiSnapshot){this.lthiSnapshot_=lthiSnapshot;this.updateContents_();},get whichTree(){return this.renderPassQuads_?constants.ACTIVE_TREE:this.whichTree_;},set whichTree(whichTree){this.whichTree_=whichTree;this.renderPassQuads_=(whichTree==RENDER_PASS_QUADS);this.updateContents_();tr.b.dispatchSimpleEvent(this,'selection-change',false);},get layerTreeImpl(){if(this.lthiSnapshot===undefined)
+return undefined;return this.lthiSnapshot.getTree(this.whichTree);},get isRenderPassQuads(){return this.renderPassQuads_;},get showPureTransformLayers(){return this.showPureTransformLayers_;},set showPureTransformLayers(show){if(this.showPureTransformLayers_===show)
+return;this.showPureTransformLayers_=show;this.updateContents_();},getRenderPassInfos_:function(){if(!this.lthiSnapshot_)
+return[];var renderPassInfo=[];if(!this.lthiSnapshot_.args.frame||!this.lthiSnapshot_.args.frame.renderPasses)
+return renderPassInfo;var renderPasses=this.lthiSnapshot_.args.frame.renderPasses;for(var i=0;i<renderPasses.length;++i){var info={renderPass:renderPasses[i],depth:0,id:i,name:'cc::RenderPass'};renderPassInfo.push(info);}
+return renderPassInfo;},getLayerInfos_:function(){if(!this.lthiSnapshot_)
+return[];var tree=this.lthiSnapshot_.getTree(this.whichTree_);if(!tree)
+return[];var layerInfos=[];var showPureTransformLayers=this.showPureTransformLayers_;function isPureTransformLayer(layer){if(layer.args.compositingReasons&&layer.args.compositingReasons.length!=1&&layer.args.compositingReasons[0]!='No reasons given')
+return false;if(layer.args.drawsContent)
+return false;return true;}
+var visitedLayers={};function visitLayer(layer,depth,isMask,isReplica){if(visitedLayers[layer.layerId])
+return;visitedLayers[layer.layerId]=true;var info={layer:layer,depth:depth};if(layer.args.drawsContent)
+info.name=layer.objectInstance.name;else
+info.name='cc::LayerImpl';if(layer.usingGpuRasterization)
+info.name+=' (G)';info.isMaskLayer=isMask;info.replicaLayer=isReplica;if(showPureTransformLayers||!isPureTransformLayer(layer))
+layerInfos.push(info);};tree.iterLayers(visitLayer);return layerInfos;},updateContents_:function(){if(this.renderPassQuads_)
+this.updateRenderPassContents_();else
+this.updateLayerContents_();},updateRenderPassContents_:function(){this.itemList_.clear();var selectedRenderPassId;if(this.selection_&&this.selection_.associatedRenderPassId)
+selectedRenderPassId=this.selection_.associatedRenderPassId;var renderPassInfos=this.getRenderPassInfos_();renderPassInfos.forEach(function(renderPassInfo){var renderPass=renderPassInfo.renderPass;var id=renderPassInfo.id;var item=this.createElementWithDepth_(renderPassInfo.depth);var labelEl=item.appendChild(tr.ui.b.createSpan());labelEl.textContent=renderPassInfo.name+' '+id;item.renderPass=renderPass;item.renderPassId=id;this.itemList_.appendChild(item);if(id==selectedRenderPassId){renderPass.selectionState=tr.model.SelectionState.SELECTED;}},this);},updateLayerContents_:function(){this.changingItemSelection_=true;try{this.itemList_.clear();var selectedLayerId;if(this.selection_&&this.selection_.associatedLayerId)
+selectedLayerId=this.selection_.associatedLayerId;var layerInfos=this.getLayerInfos_();layerInfos.forEach(function(layerInfo){var layer=layerInfo.layer;var id=layer.layerId;var item=this.createElementWithDepth_(layerInfo.depth);var labelEl=item.appendChild(tr.ui.b.createSpan());labelEl.textContent=layerInfo.name+' '+id;var notesEl=item.appendChild(tr.ui.b.createSpan());if(layerInfo.isMaskLayer)
+notesEl.textContent+='(mask)';if(layerInfo.isReplicaLayer)
+notesEl.textContent+='(replica)';if(layer.gpuMemoryUsageInBytes!==undefined){var rounded=bytesToRoundedMegabytes(layer.gpuMemoryUsageInBytes);if(rounded!==0)
+notesEl.textContent+=' ('+rounded+' MB)';}
+item.layer=layer;this.itemList_.appendChild(item);if(layer.layerId==selectedLayerId){layer.selectionState=tr.model.SelectionState.SELECTED;item.selected=true;}},this);}finally{this.changingItemSelection_=false;}},createElementWithDepth_:function(depth){var item=document.createElement('div');var indentEl=item.appendChild(tr.ui.b.createSpan());indentEl.style.whiteSpace='pre';for(var i=0;i<depth;i++)
+indentEl.textContent=indentEl.textContent+' ';return item;},onItemSelectionChanged_:function(e){if(this.changingItemSelection_)
+return;if(this.renderPassQuads_)
+this.onRenderPassSelected_(e);else
+this.onLayerSelected_(e);tr.b.dispatchSimpleEvent(this,'selection-change',false);},onRenderPassSelected_:function(e){var selectedRenderPass;var selectedRenderPassId;if(this.itemList_.selectedElement){selectedRenderPass=this.itemList_.selectedElement.renderPass;selectedRenderPassId=this.itemList_.selectedElement.renderPassId;}
+if(selectedRenderPass){this.selection_=new tr.ui.e.chrome.cc.RenderPassSelection(selectedRenderPass,selectedRenderPassId);}else{this.selection_=undefined;}},onLayerSelected_:function(e){var selectedLayer;if(this.itemList_.selectedElement)
+selectedLayer=this.itemList_.selectedElement.layer;if(selectedLayer)
+this.selection_=new tr.ui.e.chrome.cc.LayerSelection(selectedLayer);else
+this.selection_=undefined;},get selection(){return this.selection_;},set selection(selection){if(this.selection_==selection)
+return;this.selection_=selection;this.updateContents_();}};return{LayerPicker:LayerPicker};});'use strict';tr.exportTo('tr.e.cc',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function RenderPassSnapshot(){ObjectSnapshot.apply(this,arguments);}
+RenderPassSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);},initialize:function(){tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['quadList']);}};ObjectSnapshot.register(RenderPassSnapshot,{typeName:'cc::RenderPass'});return{RenderPassSnapshot:RenderPassSnapshot};});'use strict';tr.exportTo('tr.ui.b',function(){var constants={DEFAULT_SCALE:0.5,DEFAULT_EYE_DISTANCE:10000,MINIMUM_DISTANCE:1000,MAXIMUM_DISTANCE:100000,FOV:15,RESCALE_TIMEOUT_MS:200,MAXIMUM_TILT:80,SETTINGS_NAMESPACE:'tr.ui_camera'};var Camera=tr.ui.b.define('camera');Camera.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(eventSource){this.eventSource_=eventSource;this.eventSource_.addEventListener('beginpan',this.onPanBegin_.bind(this));this.eventSource_.addEventListener('updatepan',this.onPanUpdate_.bind(this));this.eventSource_.addEventListener('endpan',this.onPanEnd_.bind(this));this.eventSource_.addEventListener('beginzoom',this.onZoomBegin_.bind(this));this.eventSource_.addEventListener('updatezoom',this.onZoomUpdate_.bind(this));this.eventSource_.addEventListener('endzoom',this.onZoomEnd_.bind(this));this.eventSource_.addEventListener('beginrotate',this.onRotateBegin_.bind(this));this.eventSource_.addEventListener('updaterotate',this.onRotateUpdate_.bind(this));this.eventSource_.addEventListener('endrotate',this.onRotateEnd_.bind(this));this.eye_=[0,0,constants.DEFAULT_EYE_DISTANCE];this.gazeTarget_=[0,0,0];this.rotation_=[0,0];this.pixelRatio_=window.devicePixelRatio||1;},get modelViewMatrix(){var mvMatrix=mat4.create();mat4.lookAt(mvMatrix,this.eye_,this.gazeTarget_,[0,1,0]);return mvMatrix;},get projectionMatrix(){var rect=tr.ui.b.windowRectForElement(this.canvas_).scaleSize(this.pixelRatio_);var aspectRatio=rect.width/rect.height;var matrix=mat4.create();mat4.perspective(matrix,tr.b.deg2rad(constants.FOV),aspectRatio,1,100000);return matrix;},set canvas(c){this.canvas_=c;},set deviceRect(rect){this.deviceRect_=rect;},get stackingDistanceDampening(){var gazeVector=[this.gazeTarget_[0]-this.eye_[0],this.gazeTarget_[1]-this.eye_[1],this.gazeTarget_[2]-this.eye_[2]];vec3.normalize(gazeVector,gazeVector);return 1+gazeVector[2];},loadCameraFromSettings:function(settings){this.eye_=settings.get('eye',this.eye_,constants.SETTINGS_NAMESPACE);this.gazeTarget_=settings.get('gaze_target',this.gazeTarget_,constants.SETTINGS_NAMESPACE);this.rotation_=settings.get('rotation',this.rotation_,constants.SETTINGS_NAMESPACE);this.dispatchRenderEvent_();},saveCameraToSettings:function(settings){settings.set('eye',this.eye_,constants.SETTINGS_NAMESPACE);settings.set('gaze_target',this.gazeTarget_,constants.SETTINGS_NAMESPACE);settings.set('rotation',this.rotation_,constants.SETTINGS_NAMESPACE);},resetCamera:function(){this.eye_=[0,0,constants.DEFAULT_EYE_DISTANCE];this.gazeTarget_=[0,0,0];this.rotation_=[0,0];var settings=tr.b.SessionSettings();var keys=settings.keys(constants.SETTINGS_NAMESPACE);if(keys.length!==0){this.loadCameraFromSettings(settings);return;}
+if(this.deviceRect_){var rect=tr.ui.b.windowRectForElement(this.canvas_).scaleSize(this.pixelRatio_);this.eye_[0]=this.deviceRect_.width/2;this.eye_[1]=this.deviceRect_.height/2;this.gazeTarget_[0]=this.deviceRect_.width/2;this.gazeTarget_[1]=this.deviceRect_.height/2;}
+this.saveCameraToSettings(settings);this.dispatchRenderEvent_();},updatePanByDelta:function(delta){var rect=tr.ui.b.windowRectForElement(this.canvas_).scaleSize(this.pixelRatio_);var eyeVector=[this.eye_[0]-this.gazeTarget_[0],this.eye_[1]-this.gazeTarget_[1],this.eye_[2]-this.gazeTarget_[2]];var length=vec3.length(eyeVector);vec3.normalize(eyeVector,eyeVector);var halfFov=constants.FOV/2;var multiplier=2.0*length*Math.tan(tr.b.deg2rad(halfFov))/rect.height;var up=[0,1,0];var rotMatrix=mat4.create();mat4.rotate(rotMatrix,rotMatrix,tr.b.deg2rad(this.rotation_[1]),[0,1,0]);mat4.rotate(rotMatrix,rotMatrix,tr.b.deg2rad(this.rotation_[0]),[1,0,0]);vec3.transformMat4(up,up,rotMatrix);var right=[0,0,0];vec3.cross(right,eyeVector,up);vec3.normalize(right,right);for(var i=0;i<3;++i){this.gazeTarget_[i]+=delta[0]*multiplier*right[i]-delta[1]*multiplier*up[i];this.eye_[i]=this.gazeTarget_[i]+length*eyeVector[i];}
+if(Math.abs(this.gazeTarget_[2])>1e-6){var gazeVector=[-eyeVector[0],-eyeVector[1],-eyeVector[2]];var newLength=tr.b.clamp(-this.eye_[2]/gazeVector[2],constants.MINIMUM_DISTANCE,constants.MAXIMUM_DISTANCE);for(var i=0;i<3;++i)
+this.gazeTarget_[i]=this.eye_[i]+newLength*gazeVector[i];}
+this.saveCameraToSettings(tr.b.SessionSettings());this.dispatchRenderEvent_();},updateZoomByDelta:function(delta){var deltaY=delta[1];deltaY=tr.b.clamp(deltaY,-50,50);var scale=1.0-deltaY/100.0;var eyeVector=[0,0,0];vec3.subtract(eyeVector,this.eye_,this.gazeTarget_);var length=vec3.length(eyeVector);if(length*scale<constants.MINIMUM_DISTANCE)
+scale=constants.MINIMUM_DISTANCE/length;else if(length*scale>constants.MAXIMUM_DISTANCE)
+scale=constants.MAXIMUM_DISTANCE/length;vec3.scale(eyeVector,eyeVector,scale);vec3.add(this.eye_,this.gazeTarget_,eyeVector);this.saveCameraToSettings(tr.b.SessionSettings());this.dispatchRenderEvent_();},updateRotateByDelta:function(delta){delta[0]*=0.5;delta[1]*=0.5;if(Math.abs(this.rotation_[0]+delta[1])>constants.MAXIMUM_TILT)
+return;if(Math.abs(this.rotation_[1]-delta[0])>constants.MAXIMUM_TILT)
+return;var eyeVector=[0,0,0,0];vec3.subtract(eyeVector,this.eye_,this.gazeTarget_);var rotMatrix=mat4.create();mat4.rotate(rotMatrix,rotMatrix,-tr.b.deg2rad(this.rotation_[0]),[1,0,0]);mat4.rotate(rotMatrix,rotMatrix,-tr.b.deg2rad(this.rotation_[1]),[0,1,0]);vec4.transformMat4(eyeVector,eyeVector,rotMatrix);this.rotation_[0]+=delta[1];this.rotation_[1]-=delta[0];mat4.identity(rotMatrix);mat4.rotate(rotMatrix,rotMatrix,tr.b.deg2rad(this.rotation_[1]),[0,1,0]);mat4.rotate(rotMatrix,rotMatrix,tr.b.deg2rad(this.rotation_[0]),[1,0,0]);vec4.transformMat4(eyeVector,eyeVector,rotMatrix);vec3.add(this.eye_,this.gazeTarget_,eyeVector);this.saveCameraToSettings(tr.b.SessionSettings());this.dispatchRenderEvent_();},onPanBegin_:function(e){this.panning_=true;this.lastMousePosition_=this.getMousePosition_(e);},onPanUpdate_:function(e){if(!this.panning_)
+return;var delta=this.getMouseDelta_(e,this.lastMousePosition_);this.lastMousePosition_=this.getMousePosition_(e);this.updatePanByDelta(delta);},onPanEnd_:function(e){this.panning_=false;},onZoomBegin_:function(e){this.zooming_=true;var p=this.getMousePosition_(e);this.lastMousePosition_=p;this.zoomPoint_=p;},onZoomUpdate_:function(e){if(!this.zooming_)
+return;var delta=this.getMouseDelta_(e,this.lastMousePosition_);this.lastMousePosition_=this.getMousePosition_(e);this.updateZoomByDelta(delta);},onZoomEnd_:function(e){this.zooming_=false;this.zoomPoint_=undefined;},onRotateBegin_:function(e){this.rotating_=true;this.lastMousePosition_=this.getMousePosition_(e);},onRotateUpdate_:function(e){if(!this.rotating_)
+return;var delta=this.getMouseDelta_(e,this.lastMousePosition_);this.lastMousePosition_=this.getMousePosition_(e);this.updateRotateByDelta(delta);},onRotateEnd_:function(e){this.rotating_=false;},getMousePosition_:function(e){var rect=tr.ui.b.windowRectForElement(this.canvas_);return[(e.clientX-rect.x)*this.pixelRatio_,(e.clientY-rect.y)*this.pixelRatio_];},getMouseDelta_:function(e,p){var newP=this.getMousePosition_(e);return[newP[0]-p[0],newP[1]-p[1]];},dispatchRenderEvent_:function(){tr.b.dispatchSimpleEvent(this,'renderrequired',false,false);}};return{Camera:Camera};});'use strict';tr.exportTo('tr.ui.b',function(){var THIS_DOC=document.currentScript.ownerDocument;var constants={};constants.IMAGE_LOAD_RETRY_TIME_MS=500;constants.SUBDIVISION_MINIMUM=1;constants.SUBDIVISION_RECURSION_DEPTH=3;constants.SUBDIVISION_DEPTH_THRESHOLD=100;constants.FAR_PLANE_DISTANCE=10000;function drawTexturedTriangle(ctx,img,p0,p1,p2,t0,t1,t2){var tmp_p0=[p0[0],p0[1]];var tmp_p1=[p1[0],p1[1]];var tmp_p2=[p2[0],p2[1]];var tmp_t0=[t0[0],t0[1]];var tmp_t1=[t1[0],t1[1]];var tmp_t2=[t2[0],t2[1]];ctx.beginPath();ctx.moveTo(tmp_p0[0],tmp_p0[1]);ctx.lineTo(tmp_p1[0],tmp_p1[1]);ctx.lineTo(tmp_p2[0],tmp_p2[1]);ctx.closePath();tmp_p1[0]-=tmp_p0[0];tmp_p1[1]-=tmp_p0[1];tmp_p2[0]-=tmp_p0[0];tmp_p2[1]-=tmp_p0[1];tmp_t1[0]-=tmp_t0[0];tmp_t1[1]-=tmp_t0[1];tmp_t2[0]-=tmp_t0[0];tmp_t2[1]-=tmp_t0[1];var det=1/(tmp_t1[0]*tmp_t2[1]-tmp_t2[0]*tmp_t1[1]),a=(tmp_t2[1]*tmp_p1[0]-tmp_t1[1]*tmp_p2[0])*det,b=(tmp_t2[1]*tmp_p1[1]-tmp_t1[1]*tmp_p2[1])*det,c=(tmp_t1[0]*tmp_p2[0]-tmp_t2[0]*tmp_p1[0])*det,d=(tmp_t1[0]*tmp_p2[1]-tmp_t2[0]*tmp_p1[1])*det,e=tmp_p0[0]-a*tmp_t0[0]-c*tmp_t0[1],f=tmp_p0[1]-b*tmp_t0[0]-d*tmp_t0[1];ctx.save();ctx.transform(a,b,c,d,e,f);ctx.clip();ctx.drawImage(img,0,0);ctx.restore();}
+function drawTriangleSub(ctx,img,p0,p1,p2,t0,t1,t2,opt_recursion_depth){var depth=opt_recursion_depth||0;var subdivisionIndex=0;if(depth<constants.SUBDIVISION_MINIMUM){subdivisionIndex=7;}else if(depth<constants.SUBDIVISION_RECURSION_DEPTH){if(Math.abs(p0[2]-p1[2])>constants.SUBDIVISION_DEPTH_THRESHOLD)
+subdivisionIndex+=1;if(Math.abs(p0[2]-p2[2])>constants.SUBDIVISION_DEPTH_THRESHOLD)
+subdivisionIndex+=2;if(Math.abs(p1[2]-p2[2])>constants.SUBDIVISION_DEPTH_THRESHOLD)
+subdivisionIndex+=4;}
+var p01=vec4.create();var p02=vec4.create();var p12=vec4.create();var t01=vec2.create();var t02=vec2.create();var t12=vec2.create();for(var i=0;i<2;++i){p0[i]*=p0[2];p1[i]*=p1[2];p2[i]*=p2[2];}
+for(var i=0;i<4;++i){p01[i]=(p0[i]+p1[i])/2;p02[i]=(p0[i]+p2[i])/2;p12[i]=(p1[i]+p2[i])/2;}
+for(var i=0;i<2;++i){p0[i]/=p0[2];p1[i]/=p1[2];p2[i]/=p2[2];p01[i]/=p01[2];p02[i]/=p02[2];p12[i]/=p12[2];}
+for(var i=0;i<2;++i){t01[i]=(t0[i]+t1[i])/2;t02[i]=(t0[i]+t2[i])/2;t12[i]=(t1[i]+t2[i])/2;}
+switch(subdivisionIndex){case 1:drawTriangleSub(ctx,img,p0,p01,p2,t0,t01,t2,depth+1);drawTriangleSub(ctx,img,p01,p1,p2,t01,t1,t2,depth+1);break;case 2:drawTriangleSub(ctx,img,p0,p1,p02,t0,t1,t02,depth+1);drawTriangleSub(ctx,img,p1,p02,p2,t1,t02,t2,depth+1);break;case 3:drawTriangleSub(ctx,img,p0,p01,p02,t0,t01,t02,depth+1);drawTriangleSub(ctx,img,p02,p01,p2,t02,t01,t2,depth+1);drawTriangleSub(ctx,img,p01,p1,p2,t01,t1,t2,depth+1);break;case 4:drawTriangleSub(ctx,img,p0,p12,p2,t0,t12,t2,depth+1);drawTriangleSub(ctx,img,p0,p1,p12,t0,t1,t12,depth+1);break;case 5:drawTriangleSub(ctx,img,p0,p01,p2,t0,t01,t2,depth+1);drawTriangleSub(ctx,img,p2,p01,p12,t2,t01,t12,depth+1);drawTriangleSub(ctx,img,p01,p1,p12,t01,t1,t12,depth+1);break;case 6:drawTriangleSub(ctx,img,p0,p12,p02,t0,t12,t02,depth+1);drawTriangleSub(ctx,img,p0,p1,p12,t0,t1,t12,depth+1);drawTriangleSub(ctx,img,p02,p12,p2,t02,t12,t2,depth+1);break;case 7:drawTriangleSub(ctx,img,p0,p01,p02,t0,t01,t02,depth+1);drawTriangleSub(ctx,img,p01,p12,p02,t01,t12,t02,depth+1);drawTriangleSub(ctx,img,p01,p1,p12,t01,t1,t12,depth+1);drawTriangleSub(ctx,img,p02,p12,p2,t02,t12,t2,depth+1);break;default:drawTexturedTriangle(ctx,img,p0,p1,p2,t0,t1,t2);break;}}
+var tmp_vec4=vec4.create();function transform(transformed,point,matrix,viewport){vec4.set(tmp_vec4,point[0],point[1],0,1);vec4.transformMat4(tmp_vec4,tmp_vec4,matrix);var w=tmp_vec4[3];if(w<1e-6)w=1e-6;transformed[0]=((tmp_vec4[0]/w)+1)*viewport.width/2;transformed[1]=((tmp_vec4[1]/w)+1)*viewport.height/2;transformed[2]=w;}
+function drawProjectedQuadBackgroundToContext(quad,p1,p2,p3,p4,ctx,quadCanvas){if(quad.imageData){quadCanvas.width=quad.imageData.width;quadCanvas.height=quad.imageData.height;quadCanvas.getContext('2d').putImageData(quad.imageData,0,0);var quadBBox=new tr.b.BBox2();quadBBox.addQuad(quad);var iw=quadCanvas.width;var ih=quadCanvas.height;drawTriangleSub(ctx,quadCanvas,p1,p2,p4,[0,0],[iw,0],[0,ih]);drawTriangleSub(ctx,quadCanvas,p2,p3,p4,[iw,0],[iw,ih],[0,ih]);}
+if(quad.backgroundColor){ctx.fillStyle=quad.backgroundColor;ctx.beginPath();ctx.moveTo(p1[0],p1[1]);ctx.lineTo(p2[0],p2[1]);ctx.lineTo(p3[0],p3[1]);ctx.lineTo(p4[0],p4[1]);ctx.closePath();ctx.fill();}}
+function drawProjectedQuadOutlineToContext(quad,p1,p2,p3,p4,ctx,quadCanvas){ctx.beginPath();ctx.moveTo(p1[0],p1[1]);ctx.lineTo(p2[0],p2[1]);ctx.lineTo(p3[0],p3[1]);ctx.lineTo(p4[0],p4[1]);ctx.closePath();ctx.save();if(quad.borderColor)
+ctx.strokeStyle=quad.borderColor;else
+ctx.strokeStyle='rgb(128,128,128)';if(quad.shadowOffset){ctx.shadowColor='rgb(0, 0, 0)';ctx.shadowOffsetX=quad.shadowOffset[0];ctx.shadowOffsetY=quad.shadowOffset[1];if(quad.shadowBlur)
+ctx.shadowBlur=quad.shadowBlur;}
+if(quad.borderWidth)
+ctx.lineWidth=quad.borderWidth;else
+ctx.lineWidth=1;ctx.stroke();ctx.restore();}
+function drawProjectedQuadSelectionOutlineToContext(quad,p1,p2,p3,p4,ctx,quadCanvas){if(!quad.upperBorderColor)
+return;ctx.lineWidth=8;ctx.strokeStyle=quad.upperBorderColor;ctx.beginPath();ctx.moveTo(p1[0],p1[1]);ctx.lineTo(p2[0],p2[1]);ctx.lineTo(p3[0],p3[1]);ctx.lineTo(p4[0],p4[1]);ctx.closePath();ctx.stroke();}
+function drawProjectedQuadToContext(passNumber,quad,p1,p2,p3,p4,ctx,quadCanvas){if(passNumber===0){drawProjectedQuadBackgroundToContext(quad,p1,p2,p3,p4,ctx,quadCanvas);}else if(passNumber===1){drawProjectedQuadOutlineToContext(quad,p1,p2,p3,p4,ctx,quadCanvas);}else if(passNumber===2){drawProjectedQuadSelectionOutlineToContext(quad,p1,p2,p3,p4,ctx,quadCanvas);}else{throw new Error('Invalid pass number');}}
+var tmp_p1=vec3.create();var tmp_p2=vec3.create();var tmp_p3=vec3.create();var tmp_p4=vec3.create();function transformAndProcessQuads(matrix,viewport,quads,numPasses,handleQuadFunc,opt_arg1,opt_arg2){for(var passNumber=0;passNumber<numPasses;passNumber++){for(var i=0;i<quads.length;i++){var quad=quads[i];transform(tmp_p1,quad.p1,matrix,viewport);transform(tmp_p2,quad.p2,matrix,viewport);transform(tmp_p3,quad.p3,matrix,viewport);transform(tmp_p4,quad.p4,matrix,viewport);handleQuadFunc(passNumber,quad,tmp_p1,tmp_p2,tmp_p3,tmp_p4,opt_arg1,opt_arg2);}}}
+var QuadStackView=tr.ui.b.define('quad-stack-view');QuadStackView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.className='quad-stack-view';var node=tr.ui.b.instantiateTemplate('#quad-stack-view-template',THIS_DOC);this.appendChild(node);this.updateHeaderVisibility_();this.canvas_=this.querySelector('#canvas');this.chromeImages_={left:this.querySelector('#chrome-left'),mid:this.querySelector('#chrome-mid'),right:this.querySelector('#chrome-right')};var stackingDistanceSlider=this.querySelector('#stacking-distance-slider');stackingDistanceSlider.value=tr.b.Settings.get('quadStackView.stackingDistance',45);stackingDistanceSlider.addEventListener('change',this.onStackingDistanceChange_.bind(this));stackingDistanceSlider.addEventListener('input',this.onStackingDistanceChange_.bind(this));this.trackMouse_();this.camera_=new tr.ui.b.Camera(this.mouseModeSelector_);this.camera_.addEventListener('renderrequired',this.onRenderRequired_.bind(this));this.cameraWasReset_=false;this.camera_.canvas=this.canvas_;this.viewportRect_=tr.b.Rect.fromXYWH(0,0,0,0);this.pixelRatio_=window.devicePixelRatio||1;},updateHeaderVisibility_:function(){if(this.headerText)
+this.querySelector('#header').style.display='';else
+this.querySelector('#header').style.display='none';},get headerText(){return this.querySelector('#header').textContent;},set headerText(headerText){this.querySelector('#header').textContent=headerText;this.updateHeaderVisibility_();},onStackingDistanceChange_:function(e){tr.b.Settings.set('quadStackView.stackingDistance',this.stackingDistance);this.scheduleRender();e.stopPropagation();},get stackingDistance(){return this.querySelector('#stacking-distance-slider').value;},get mouseModeSelector(){return this.mouseModeSelector_;},get camera(){return this.camera_;},set quads(q){this.quads_=q;this.scheduleRender();},set deviceRect(rect){if(!rect||rect.equalTo(this.deviceRect_))
+return;this.deviceRect_=rect;this.camera_.deviceRect=rect;this.chromeQuad_=undefined;},resize:function(){if(!this.offsetParent)
+return true;var width=parseInt(window.getComputedStyle(this.offsetParent).width);var height=parseInt(window.getComputedStyle(this.offsetParent).height);var rect=tr.b.Rect.fromXYWH(0,0,width,height);if(rect.equalTo(this.viewportRect_))
+return false;this.viewportRect_=rect;this.style.width=width+'px';this.style.height=height+'px';this.canvas_.style.width=width+'px';this.canvas_.style.height=height+'px';this.canvas_.width=this.pixelRatio_*width;this.canvas_.height=this.pixelRatio_*height;if(!this.cameraWasReset_){this.camera_.resetCamera();this.cameraWasReset_=true;}
+return true;},readyToDraw:function(){if(!this.chromeImages_.left.src){var leftContent=window.getComputedStyle(this.chromeImages_.left).content;leftContent=leftContent.replace(/url\((.*)\)/,'$1');var midContent=window.getComputedStyle(this.chromeImages_.mid).content;midContent=midContent.replace(/url\((.*)\)/,'$1');var rightContent=window.getComputedStyle(this.chromeImages_.right).content;rightContent=rightContent.replace(/url\((.*)\)/,'$1');this.chromeImages_.left.src=leftContent;this.chromeImages_.mid.src=midContent;this.chromeImages_.right.src=rightContent;}
+return(this.chromeImages_.left.height>0)&&(this.chromeImages_.mid.height>0)&&(this.chromeImages_.right.height>0);},get chromeQuad(){if(this.chromeQuad_)
+return this.chromeQuad_;var chromeCanvas=document.createElement('canvas');var offsetY=this.chromeImages_.left.height;chromeCanvas.width=this.deviceRect_.width;chromeCanvas.height=this.deviceRect_.height+offsetY;var leftWidth=this.chromeImages_.left.width;var midWidth=this.chromeImages_.mid.width;var rightWidth=this.chromeImages_.right.width;var chromeCtx=chromeCanvas.getContext('2d');chromeCtx.drawImage(this.chromeImages_.left,0,0);chromeCtx.save();chromeCtx.translate(leftWidth,0);var s=(this.deviceRect_.width-leftWidth-rightWidth)/midWidth;chromeCtx.scale(s,1);chromeCtx.drawImage(this.chromeImages_.mid,0,0);chromeCtx.restore();chromeCtx.drawImage(this.chromeImages_.right,leftWidth+s*midWidth,0);var chromeRect=tr.b.Rect.fromXYWH(this.deviceRect_.x,this.deviceRect_.y-offsetY,this.deviceRect_.width,this.deviceRect_.height+offsetY);var chromeQuad=tr.b.Quad.fromRect(chromeRect);chromeQuad.stackingGroupId=this.maxStackingGroupId_+1;chromeQuad.imageData=chromeCtx.getImageData(0,0,chromeCanvas.width,chromeCanvas.height);chromeQuad.shadowOffset=[0,0];chromeQuad.shadowBlur=5;chromeQuad.borderWidth=3;this.chromeQuad_=chromeQuad;return this.chromeQuad_;},scheduleRender:function(){if(this.redrawScheduled_)
+return false;this.redrawScheduled_=true;tr.b.requestAnimationFrame(this.render,this);},onRenderRequired_:function(e){this.scheduleRender();},stackTransformAndProcessQuads_:function(numPasses,handleQuadFunc,includeChromeQuad,opt_arg1,opt_arg2){var mv=this.camera_.modelViewMatrix;var p=this.camera_.projectionMatrix;var viewport=tr.b.Rect.fromXYWH(0,0,this.canvas_.width,this.canvas_.height);var quadStacks=[];for(var i=0;i<this.quads_.length;++i){var quad=this.quads_[i];var stackingId=quad.stackingGroupId||0;while(stackingId>=quadStacks.length)
+quadStacks.push([]);quadStacks[stackingId].push(quad);}
+var mvp=mat4.create();this.maxStackingGroupId_=quadStacks.length;var effectiveStackingDistance=this.stackingDistance*this.camera_.stackingDistanceDampening;mat4.multiply(mvp,p,mv);for(var i=0;i<quadStacks.length;++i){transformAndProcessQuads(mvp,viewport,quadStacks[i],numPasses,handleQuadFunc,opt_arg1,opt_arg2);mat4.translate(mv,mv,[0,0,effectiveStackingDistance]);mat4.multiply(mvp,p,mv);}
+if(includeChromeQuad&&this.deviceRect_){transformAndProcessQuads(mvp,viewport,[this.chromeQuad],numPasses,drawProjectedQuadToContext,opt_arg1,opt_arg2);}},render:function(){this.redrawScheduled_=false;if(!this.readyToDraw()){setTimeout(this.scheduleRender.bind(this),constants.IMAGE_LOAD_RETRY_TIME_MS);return;}
+if(!this.quads_)
+return;var canvasCtx=this.canvas_.getContext('2d');if(!this.resize())
+canvasCtx.clearRect(0,0,this.canvas_.width,this.canvas_.height);var quadCanvas=document.createElement('canvas');this.stackTransformAndProcessQuads_(3,drawProjectedQuadToContext,true,canvasCtx,quadCanvas);quadCanvas.width=0;},trackMouse_:function(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this.canvas_;this.mouseModeSelector_.supportedModeMask=tr.ui.b.MOUSE_SELECTOR_MODE.SELECTION|tr.ui.b.MOUSE_SELECTOR_MODE.PANSCAN|tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM|tr.ui.b.MOUSE_SELECTOR_MODE.ROTATE;this.mouseModeSelector_.mode=tr.ui.b.MOUSE_SELECTOR_MODE.PANSCAN;this.mouseModeSelector_.pos={x:0,y:100};this.appendChild(this.mouseModeSelector_);this.mouseModeSelector_.settingsKey='quadStackView.mouseModeSelector';this.mouseModeSelector_.setModifierForAlternateMode(tr.ui.b.MOUSE_SELECTOR_MODE.ROTATE,tr.ui.b.MODIFIER.SHIFT);this.mouseModeSelector_.setModifierForAlternateMode(tr.ui.b.MOUSE_SELECTOR_MODE.PANSCAN,tr.ui.b.MODIFIER.SPACE);this.mouseModeSelector_.setModifierForAlternateMode(tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM,tr.ui.b.MODIFIER.CMD_OR_CTRL);this.mouseModeSelector_.addEventListener('updateselection',this.onSelectionUpdate_.bind(this));this.mouseModeSelector_.addEventListener('endselection',this.onSelectionUpdate_.bind(this));},extractRelativeMousePosition_:function(e){var br=this.canvas_.getBoundingClientRect();return[this.pixelRatio_*(e.clientX-this.canvas_.offsetLeft-br.left),this.pixelRatio_*(e.clientY-this.canvas_.offsetTop-br.top)];},onSelectionUpdate_:function(e){var mousePos=this.extractRelativeMousePosition_(e);var res=[];function handleQuad(passNumber,quad,p1,p2,p3,p4){if(tr.b.pointInImplicitQuad(mousePos,p1,p2,p3,p4))
+res.push(quad);}
+this.stackTransformAndProcessQuads_(1,handleQuad,false);var e=new tr.b.Event('selectionchange');e.quads=res;this.dispatchEvent(e);}};return{QuadStackView:QuadStackView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var ColorScheme=tr.b.ColorScheme;var THIS_DOC=document.currentScript.ownerDocument;var TILE_HEATMAP_TYPE={};TILE_HEATMAP_TYPE.NONE='none';TILE_HEATMAP_TYPE.SCHEDULED_PRIORITY='scheduledPriority';TILE_HEATMAP_TYPE.USING_GPU_MEMORY='usingGpuMemory';var cc=tr.ui.e.chrome.cc;function createTileRectsSelectorBaseOptions(){return[{label:'None',value:'none'},{label:'Coverage Rects',value:'coverage'}];}
+var bytesToRoundedMegabytes=tr.e.cc.bytesToRoundedMegabytes;var LayerTreeQuadStackView=tr.ui.b.define('tr-ui-e-chrome-cc-layer-tree-quad-stack-view');LayerTreeQuadStackView.prototype={__proto__:HTMLDivElement.prototype,decorate:function(){this.isRenderPassQuads_=false;this.pictureAsImageData_={};this.messages_=[];this.controls_=document.createElement('top-controls');this.infoBar_=document.createElement('tr-ui-b-info-bar');this.quadStackView_=new tr.ui.b.QuadStackView();this.quadStackView_.addEventListener('selectionchange',this.onQuadStackViewSelectionChange_.bind(this));this.extraHighlightsByLayerId_=undefined;this.inputEventImageData_=undefined;var m=tr.ui.b.MOUSE_SELECTOR_MODE;var mms=this.quadStackView_.mouseModeSelector;mms.settingsKey='tr.e.cc.layerTreeQuadStackView.mouseModeSelector';mms.setKeyCodeForMode(m.SELECTION,'Z'.charCodeAt(0));mms.setKeyCodeForMode(m.PANSCAN,'X'.charCodeAt(0));mms.setKeyCodeForMode(m.ZOOM,'C'.charCodeAt(0));mms.setKeyCodeForMode(m.ROTATE,'V'.charCodeAt(0));var node=tr.ui.b.instantiateTemplate('#tr-ui-e-chrome-cc-layer-tree-quad-stack-view-template',THIS_DOC);this.appendChild(node);this.appendChild(this.controls_);this.appendChild(this.infoBar_);this.appendChild(this.quadStackView_);this.tileRectsSelector_=tr.ui.b.createSelector(this,'howToShowTiles','layerView.howToShowTiles','none',createTileRectsSelectorBaseOptions());this.controls_.appendChild(this.tileRectsSelector_);var tileHeatmapText=tr.ui.b.createSpan({textContent:'Tile heatmap:'});this.controls_.appendChild(tileHeatmapText);var tileHeatmapSelector=tr.ui.b.createSelector(this,'tileHeatmapType','layerView.tileHeatmapType',TILE_HEATMAP_TYPE.NONE,[{label:'None',value:TILE_HEATMAP_TYPE.NONE},{label:'Scheduled Priority',value:TILE_HEATMAP_TYPE.SCHEDULED_PRIORITY},{label:'Is using GPU memory',value:TILE_HEATMAP_TYPE.USING_GPU_MEMORY}]);this.controls_.appendChild(tileHeatmapSelector);var showOtherLayersCheckbox=tr.ui.b.createCheckBox(this,'showOtherLayers','layerView.showOtherLayers',true,'Other layers/passes');showOtherLayersCheckbox.title='When checked, show all layers, selected or not.';this.controls_.appendChild(showOtherLayersCheckbox);var showInvalidationsCheckbox=tr.ui.b.createCheckBox(this,'showInvalidations','layerView.showInvalidations',true,'Invalidations');showInvalidationsCheckbox.title='When checked, compositing invalidations are highlighted in red';this.controls_.appendChild(showInvalidationsCheckbox);var showUnrecordedRegionCheckbox=tr.ui.b.createCheckBox(this,'showUnrecordedRegion','layerView.showUnrecordedRegion',true,'Unrecorded area');showUnrecordedRegionCheckbox.title='When checked, unrecorded areas are highlighted in yellow';this.controls_.appendChild(showUnrecordedRegionCheckbox);var showBottlenecksCheckbox=tr.ui.b.createCheckBox(this,'showBottlenecks','layerView.showBottlenecks',true,'Bottlenecks');showBottlenecksCheckbox.title='When checked, scroll bottlenecks are highlighted';this.controls_.appendChild(showBottlenecksCheckbox);var showLayoutRectsCheckbox=tr.ui.b.createCheckBox(this,'showLayoutRects','layerView.showLayoutRects',false,'Layout rects');showLayoutRectsCheckbox.title='When checked, shows rects for regions where layout happened';this.controls_.appendChild(showLayoutRectsCheckbox);var showContentsCheckbox=tr.ui.b.createCheckBox(this,'showContents','layerView.showContents',true,'Contents');showContentsCheckbox.title='When checked, show the rendered contents inside the layer outlines';this.controls_.appendChild(showContentsCheckbox);var showAnimationBoundsCheckbox=tr.ui.b.createCheckBox(this,'showAnimationBounds','layerView.showAnimationBounds',false,'Animation Bounds');showAnimationBoundsCheckbox.title='When checked, show a border around'+' a layer showing the extent of its animation.';this.controls_.appendChild(showAnimationBoundsCheckbox);var showInputEventsCheckbox=tr.ui.b.createCheckBox(this,'showInputEvents','layerView.showInputEvents',true,'Input events');showInputEventsCheckbox.title='When checked, input events are '+'displayed as circles.';this.controls_.appendChild(showInputEventsCheckbox);this.whatRasterizedLink_=document.createElement('a');this.whatRasterizedLink_.classList.add('what-rasterized');this.whatRasterizedLink_.textContent='What rasterized?';this.whatRasterizedLink_.addEventListener('click',this.onWhatRasterizedLinkClicked_.bind(this));this.appendChild(this.whatRasterizedLink_);},get layerTreeImpl(){return this.layerTreeImpl_;},set isRenderPassQuads(newValue){this.isRenderPassQuads_=newValue;},set layerTreeImpl(layerTreeImpl){if(this.layerTreeImpl_===layerTreeImpl)
+return;this.layerTreeImpl_=layerTreeImpl;this.selection=undefined;},get extraHighlightsByLayerId(){return this.extraHighlightsByLayerId_;},set extraHighlightsByLayerId(extraHighlightsByLayerId){this.extraHighlightsByLayerId_=extraHighlightsByLayerId;this.scheduleUpdateContents_();},get showOtherLayers(){return this.showOtherLayers_;},set showOtherLayers(show){this.showOtherLayers_=show;this.updateContents_();},get showAnimationBounds(){return this.showAnimationBounds_;},set showAnimationBounds(show){this.showAnimationBounds_=show;this.updateContents_();},get showInputEvents(){return this.showInputEvents_;},set showInputEvents(show){this.showInputEvents_=show;this.updateContents_();},get showContents(){return this.showContents_;},set showContents(show){this.showContents_=show;this.updateContents_();},get showInvalidations(){return this.showInvalidations_;},set showInvalidations(show){this.showInvalidations_=show;this.updateContents_();},get showUnrecordedRegion(){return this.showUnrecordedRegion_;},set showUnrecordedRegion(show){this.showUnrecordedRegion_=show;this.updateContents_();},get showBottlenecks(){return this.showBottlenecks_;},set showBottlenecks(show){this.showBottlenecks_=show;this.updateContents_();},get showLayoutRects(){return this.showLayoutRects_;},set showLayoutRects(show){this.showLayoutRects_=show;this.updateContents_();},get howToShowTiles(){return this.howToShowTiles_;},set howToShowTiles(val){console.assert((val==='none')||(val==='coverage')||!isNaN(parseFloat(val)));this.howToShowTiles_=val;this.updateContents_();},get tileHeatmapType(){return this.tileHeatmapType_;},set tileHeatmapType(val){this.tileHeatmapType_=val;this.updateContents_();},get selection(){return this.selection_;},set selection(selection){if(this.selection===selection)
+return;this.selection_=selection;tr.b.dispatchSimpleEvent(this,'selection-change');this.updateContents_();},regenerateContent:function(){this.updateTilesSelector_();this.updateContents_();},loadDataForImageElement_:function(image,callback){var imageContent=window.getComputedStyle(image).content;image.src=imageContent.replace(/url\((.*)\)/,'$1');image.onload=function(){var canvas=document.createElement('canvas');var ctx=canvas.getContext('2d');canvas.width=image.width;canvas.height=image.height;ctx.drawImage(image,0,0);var imageData=ctx.getImageData(0,0,canvas.width,canvas.height);callback(imageData);}},onQuadStackViewSelectionChange_:function(e){var selectableQuads=e.quads.filter(function(q){return q.selectionToSetIfClicked!==undefined;});if(selectableQuads.length==0){this.selection=undefined;return;}
+selectableQuads.sort(function(x,y){var z=x.stackingGroupId-y.stackingGroupId;if(z!=0)
+return z;return x.selectionToSetIfClicked.specicifity-
+y.selectionToSetIfClicked.specicifity;});var quadToSelect=selectableQuads[selectableQuads.length-1];this.selection=quadToSelect.selectionToSetIfClicked;},scheduleUpdateContents_:function(){if(this.updateContentsPending_)
+return;this.updateContentsPending_=true;tr.b.requestAnimationFrameInThisFrameIfPossible(this.updateContents_,this);},updateContents_:function(){if(!this.layerTreeImpl_){this.quadStackView_.headerText='No tree';this.quadStackView_.quads=[];return;}
+var status=this.computePictureLoadingStatus_();if(!status.picturesComplete)
+return;var lthi=this.layerTreeImpl_.layerTreeHostImpl;var lthiInstance=lthi.objectInstance;var worldViewportRect=tr.b.Rect.fromXYWH(0,0,lthi.deviceViewportSize.width,lthi.deviceViewportSize.height);this.quadStackView_.deviceRect=worldViewportRect;if(this.isRenderPassQuads_)
+this.quadStackView_.quads=this.generateRenderPassQuads();else
+this.quadStackView_.quads=this.generateLayerQuads();this.updateWhatRasterizedLinkState_();var message='';if(lthi.tilesHaveGpuMemoryUsageInfo){var thisTreeUsageInBytes=this.layerTreeImpl_.gpuMemoryUsageInBytes;var otherTreeUsageInBytes=lthi.gpuMemoryUsageInBytes-
+thisTreeUsageInBytes;message+=bytesToRoundedMegabytes(thisTreeUsageInBytes)+'MB on this tree';if(otherTreeUsageInBytes){message+=', '+
+bytesToRoundedMegabytes(otherTreeUsageInBytes)+'MB on the other tree';}}else{if(this.layerTreeImpl_){var thisTreeUsageInBytes=this.layerTreeImpl_.gpuMemoryUsageInBytes;message+=bytesToRoundedMegabytes(thisTreeUsageInBytes)+'MB on this tree';if(this.layerTreeImpl_.otherTree){message+=', ???MB on other tree. ';}}}
+if(lthi.args.tileManagerBasicState){var tmgs=lthi.args.tileManagerBasicState.globalState;message+=' (softMax='+
+bytesToRoundedMegabytes(tmgs.softMemoryLimitInBytes)+'MB, hardMax='+
+bytesToRoundedMegabytes(tmgs.hardMemoryLimitInBytes)+'MB, '+
+tmgs.memoryLimitPolicy+')';}else{var thread=lthi.snapshottedOnThread;var didManageTilesSlices=thread.sliceGroup.slices.filter(function(s){if(s.category!=='tr.e.cc')
+return false;if(s.title!=='DidManage')
+return false;if(s.end>lthi.ts)
+return false;return true;});didManageTilesSlices.sort(function(x,y){return x.end-y.end;});if(didManageTilesSlices.length>0){var newest=didManageTilesSlices[didManageTilesSlices.length-1];var tmgs=newest.args.state.global_state;message+=' (softMax='+
+bytesToRoundedMegabytes(tmgs.soft_memory_limit_in_bytes)+'MB, hardMax='+
+bytesToRoundedMegabytes(tmgs.hard_memory_limit_in_bytes)+'MB, '+
+tmgs.memory_limit_policy+')';}}
+if(this.layerTreeImpl_.otherTree)
+message+=' (Another tree exists)';if(message.length)
+this.quadStackView_.headerText=message;else
+this.quadStackView_.headerText=undefined;this.updateInfoBar_(status.messages);},updateTilesSelector_:function(){var data=createTileRectsSelectorBaseOptions();if(this.layerTreeImpl_){var lthi=this.layerTreeImpl_.layerTreeHostImpl;var scaleNames=lthi.getContentsScaleNames();for(var scale in scaleNames){data.push({label:'Scale '+scale+' ('+scaleNames[scale]+')',value:scale});}}
+var new_selector=tr.ui.b.createSelector(this,'howToShowTiles','layerView.howToShowTiles','none',data);this.controls_.replaceChild(new_selector,this.tileRectsSelector_);this.tileRectsSelector_=new_selector;},computePictureLoadingStatus_:function(){var layers=this.layers;var status={messages:[],picturesComplete:true};if(this.showContents){var hasPendingRasterizeImage=false;var firstPictureError=undefined;var hasMissingLayerRect=false;var hasUnresolvedPictureRef=false;for(var i=0;i<layers.length;i++){var layer=layers[i];for(var ir=0;ir<layer.pictures.length;++ir){var picture=layer.pictures[ir];if(picture.idRef){hasUnresolvedPictureRef=true;continue;}
+if(!picture.layerRect){hasMissingLayerRect=true;continue;}
+var pictureAsImageData=this.pictureAsImageData_[picture.guid];if(!pictureAsImageData){hasPendingRasterizeImage=true;this.pictureAsImageData_[picture.guid]=tr.e.cc.PictureAsImageData.Pending(this);picture.rasterize({stopIndex:undefined},function(pictureImageData){var picture_=pictureImageData.picture;this.pictureAsImageData_[picture_.guid]=pictureImageData;this.scheduleUpdateContents_();}.bind(this));continue;}
+if(pictureAsImageData.isPending()){hasPendingRasterizeImage=true;continue;}
+if(pictureAsImageData.error){if(!firstPictureError)
+firstPictureError=pictureAsImageData.error;break;}}}
+if(hasPendingRasterizeImage){status.picturesComplete=false;}else{if(hasUnresolvedPictureRef){status.messages.push({header:'Missing picture',details:'Your trace didnt have pictures for every layer. '+'Old chrome versions had this problem'});}
+if(hasMissingLayerRect){status.messages.push({header:'Missing layer rect',details:'Your trace may be corrupt or from a very old '+'Chrome revision.'});}
+if(firstPictureError){status.messages.push({header:'Cannot rasterize',details:firstPictureError});}}}
+if(this.showInputEvents&&this.layerTreeImpl.tracedInputLatencies&&this.inputEventImageData_===undefined){var image=this.querySelector('#input-event');if(!image.src){this.loadDataForImageElement_(image,function(imageData){this.inputEventImageData_=imageData;this.updateContentsPending_=false;this.scheduleUpdateContents_();}.bind(this));}
+status.picturesComplete=false;}
+return status;},get selectedRenderPass(){if(this.selection)
+return this.selection.renderPass_;},get selectedLayer(){if(this.selection){var selectedLayerId=this.selection.associatedLayerId;return this.layerTreeImpl_.findLayerWithId(selectedLayerId);}},get renderPasses(){var renderPasses=this.layerTreeImpl.layerTreeHostImpl.args.frame.renderPasses;if(!this.showOtherLayers){var selectedRenderPass=this.selectedRenderPass;if(selectedRenderPass)
+renderPasses=[selectedRenderPass];}
+return renderPasses;},get layers(){var layers=this.layerTreeImpl.renderSurfaceLayerList;if(!this.showOtherLayers){var selectedLayer=this.selectedLayer;if(selectedLayer)
+layers=[selectedLayer];}
+return layers;},appendImageQuads_:function(quads,layer,layerQuad){for(var ir=0;ir<layer.pictures.length;++ir){var picture=layer.pictures[ir];if(!picture.layerRect)
+continue;var unitRect=picture.layerRect.asUVRectInside(layer.bounds);var iq=layerQuad.projectUnitRect(unitRect);var pictureData=this.pictureAsImageData_[picture.guid];if(this.showContents&&pictureData&&pictureData.imageData){iq.imageData=pictureData.imageData;iq.borderColor='rgba(0,0,0,0)';}else{iq.imageData=undefined;}
+iq.stackingGroupId=layerQuad.stackingGroupId;quads.push(iq);}},appendAnimationQuads_:function(quads,layer,layerQuad){if(!layer.animationBoundsRect)
+return;var rect=layer.animationBoundsRect;var abq=tr.b.Quad.fromRect(rect);abq.backgroundColor='rgba(164,191,48,0.5)';abq.borderColor='rgba(205,255,0,0.75)';abq.borderWidth=3.0;abq.stackingGroupId=layerQuad.stackingGroupId;abq.selectionToSetIfClicked=new cc.AnimationRectSelection(layer,rect);quads.push(abq);},appendInvalidationQuads_:function(quads,layer,layerQuad){if(layer.layerTreeImpl.hasSourceFrameBeenDrawnBefore)
+return;for(var ir=0;ir<layer.annotatedInvalidation.rects.length;ir++){var rect=layer.annotatedInvalidation.rects[ir];var unitRect=rect.asUVRectInside(layer.bounds);var iq=layerQuad.projectUnitRect(unitRect);iq.backgroundColor='rgba(0, 255, 0, 0.1)';if(rect.reason==='renderer insertion')
+iq.backgroundColor='rgba(0, 255, 128, 0.1)';iq.borderColor='rgba(0, 255, 0, 1)';iq.stackingGroupId=layerQuad.stackingGroupId;iq.selectionToSetIfClicked=new cc.LayerRectSelection(layer,'Invalidation rect ('+rect.reason+')',rect,rect);quads.push(iq);}
+if(layer.annotatedInvalidation.rects.length===0){for(var ir=0;ir<layer.invalidation.rects.length;ir++){var rect=layer.invalidation.rects[ir];var unitRect=rect.asUVRectInside(layer.bounds);var iq=layerQuad.projectUnitRect(unitRect);iq.backgroundColor='rgba(0, 255, 0, 0.1)';iq.borderColor='rgba(0, 255, 0, 1)';iq.stackingGroupId=layerQuad.stackingGroupId;iq.selectionToSetIfClicked=new cc.LayerRectSelection(layer,'Invalidation rect',rect,rect);quads.push(iq);}}},appendUnrecordedRegionQuads_:function(quads,layer,layerQuad){for(var ir=0;ir<layer.unrecordedRegion.rects.length;ir++){var rect=layer.unrecordedRegion.rects[ir];var unitRect=rect.asUVRectInside(layer.bounds);var iq=layerQuad.projectUnitRect(unitRect);iq.backgroundColor='rgba(240, 230, 140, 0.3)';iq.borderColor='rgba(240, 230, 140, 1)';iq.stackingGroupId=layerQuad.stackingGroupId;iq.selectionToSetIfClicked=new cc.LayerRectSelection(layer,'Unrecorded area',rect,rect);quads.push(iq);}},appendBottleneckQuads_:function(quads,layer,layerQuad,stackingGroupId){function processRegion(region,label,borderColor){var backgroundColor=borderColor.clone();backgroundColor.a=0.4*(borderColor.a||1.0);if(!region||!region.rects)
+return;for(var ir=0;ir<region.rects.length;ir++){var rect=region.rects[ir];var unitRect=rect.asUVRectInside(layer.bounds);var iq=layerQuad.projectUnitRect(unitRect);iq.backgroundColor=backgroundColor.toString();iq.borderColor=borderColor.toString();iq.borderWidth=4.0;iq.stackingGroupId=stackingGroupId;iq.selectionToSetIfClicked=new cc.LayerRectSelection(layer,label,rect,rect);quads.push(iq);}}
+processRegion(layer.touchEventHandlerRegion,'Touch listener',tr.b.Color.fromString('rgb(228, 226, 27)'));processRegion(layer.wheelEventHandlerRegion,'Wheel listener',tr.b.Color.fromString('rgb(176, 205, 29)'));processRegion(layer.nonFastScrollableRegion,'Repaints on scroll',tr.b.Color.fromString('rgb(213, 134, 32)'));},appendTileCoverageRectQuads_:function(quads,layer,layerQuad,heatmapType){if(!layer.tileCoverageRects)
+return;var tiles=[];for(var ct=0;ct<layer.tileCoverageRects.length;++ct){var tile=layer.tileCoverageRects[ct].tile;if(tile!==undefined)
+tiles.push(tile);}
+var lthi=this.layerTreeImpl_.layerTreeHostImpl;var minMax=this.getMinMaxForHeatmap_(lthi.activeTiles,heatmapType);var heatmapResult=this.computeHeatmapColors_(tiles,minMax,heatmapType);var heatIndex=0;for(var ct=0;ct<layer.tileCoverageRects.length;++ct){var rect=layer.tileCoverageRects[ct].geometryRect;rect=rect.scale(1.0/layer.geometryContentsScale);var tile=layer.tileCoverageRects[ct].tile;var unitRect=rect.asUVRectInside(layer.bounds);var quad=layerQuad.projectUnitRect(unitRect);quad.backgroundColor='rgba(0, 0, 0, 0)';quad.stackingGroupId=layerQuad.stackingGroupId;var type=tr.e.cc.tileTypes.missing;if(tile){type=tile.getTypeForLayer(layer);quad.backgroundColor=heatmapResult[heatIndex].color;++heatIndex;}
+quad.borderColor=tr.e.cc.tileBorder[type].color;quad.borderWidth=tr.e.cc.tileBorder[type].width;var label;if(tile)
+label='coverageRect';else
+label='checkerboard coverageRect';quad.selectionToSetIfClicked=new cc.LayerRectSelection(layer,label,rect,layer.tileCoverageRects[ct]);quads.push(quad);}},appendLayoutRectQuads_:function(quads,layer,layerQuad){if(!layer.layoutRects){return;}
+for(var ct=0;ct<layer.layoutRects.length;++ct){var rect=layer.layoutRects[ct].geometryRect;rect=rect.scale(1.0/layer.geometryContentsScale);var unitRect=rect.asUVRectInside(layer.bounds);var quad=layerQuad.projectUnitRect(unitRect);quad.backgroundColor='rgba(0, 0, 0, 0)';quad.stackingGroupId=layerQuad.stackingGroupId;quad.borderColor='rgba(0, 0, 200, 0.7)';quad.borderWidth=2;var label;label='Layout rect';quad.selectionToSetIfClicked=new cc.LayerRectSelection(layer,label,rect);quads.push(quad);}},getValueForHeatmap_:function(tile,heatmapType){if(heatmapType==TILE_HEATMAP_TYPE.SCHEDULED_PRIORITY){return tile.scheduledPriority==0?undefined:tile.scheduledPriority;}else if(heatmapType==TILE_HEATMAP_TYPE.USING_GPU_MEMORY){if(tile.isSolidColor)
+return 0.5;return tile.isUsingGpuMemory?0:1;}},getMinMaxForHeatmap_:function(tiles,heatmapType){var range=new tr.b.Range();if(heatmapType==TILE_HEATMAP_TYPE.USING_GPU_MEMORY){range.addValue(0);range.addValue(1);return range;}
+for(var i=0;i<tiles.length;++i){var value=this.getValueForHeatmap_(tiles[i],heatmapType);if(value===undefined)
+continue;range.addValue(value);}
+if(range.range===0)
+range.addValue(1);return range;},computeHeatmapColors_:function(tiles,minMax,heatmapType){var min=minMax.min;var max=minMax.max;var color=function(value){var hue=120*(1-(value-min)/(max-min));if(hue<0)
+hue=0;return'hsla('+hue+', 100%, 50%, 0.5)';};var values=[];for(var i=0;i<tiles.length;++i){var tile=tiles[i];var value=this.getValueForHeatmap_(tile,heatmapType);var res={value:value,color:value!==undefined?color(value):undefined};values.push(res);}
+return values;},appendTilesWithScaleQuads_:function(quads,layer,layerQuad,scale,heatmapType){var lthi=this.layerTreeImpl_.layerTreeHostImpl;var tiles=[];for(var i=0;i<lthi.activeTiles.length;++i){var tile=lthi.activeTiles[i];if(Math.abs(tile.contentsScale-scale)>1e-6)
+continue;if(layer.layerId!=tile.layerId)
+continue;tiles.push(tile);}
+var minMax=this.getMinMaxForHeatmap_(lthi.activeTiles,heatmapType);var heatmapResult=this.computeHeatmapColors_(tiles,minMax,heatmapType);for(var i=0;i<tiles.length;++i){var tile=tiles[i];var rect=tile.layerRect;if(!tile.layerRect)
+continue;var unitRect=rect.asUVRectInside(layer.bounds);var quad=layerQuad.projectUnitRect(unitRect);quad.backgroundColor='rgba(0, 0, 0, 0)';quad.stackingGroupId=layerQuad.stackingGroupId;var type=tile.getTypeForLayer(layer);quad.borderColor=tr.e.cc.tileBorder[type].color;quad.borderWidth=tr.e.cc.tileBorder[type].width;quad.backgroundColor=heatmapResult[i].color;var data={tileType:type};if(heatmapType!==TILE_HEATMAP_TYPE.NONE)
+data[heatmapType]=heatmapResult[i].value;quad.selectionToSetIfClicked=new cc.TileSelection(tile,data);quads.push(quad);}},appendHighlightQuadsForLayer_:function(quads,layer,layerQuad,highlights){highlights.forEach(function(highlight){var rect=highlight.rect;var unitRect=rect.asUVRectInside(layer.bounds);var quad=layerQuad.projectUnitRect(unitRect);var colorId=ColorScheme.getColorIdForGeneralPurposeString(highlight.colorKey);colorId+=ColorScheme.properties.brightenedOffsets[0];var color=ColorScheme.colors[colorId];var quadForDrawing=quad.clone();quadForDrawing.backgroundColor=color.withAlpha(0.5).toString();quadForDrawing.borderColor=color.withAlpha(1.0).darken().toString();quadForDrawing.stackingGroupId=layerQuad.stackingGroupId;quads.push(quadForDrawing);},this);},generateRenderPassQuads:function(){if(!this.layerTreeImpl.layerTreeHostImpl.args.frame)
+return[];var renderPasses=this.renderPasses;if(!renderPasses)
+return[];var quads=[];for(var i=0;i<renderPasses.length;++i){var quadList=renderPasses[i].quadList;for(var j=0;j<quadList.length;++j){var drawQuad=quadList[j];var quad=drawQuad.rectAsTargetSpaceQuad.clone();quad.borderColor='rgb(170, 204, 238)';quad.borderWidth=2;quad.stackingGroupId=i;quads.push(quad);}}
+return quads;},generateLayerQuads:function(){this.updateContentsPending_=false;var layers=this.layers;var quads=[];var nextStackingGroupId=0;var alreadyVisitedLayerIds={};var selectionHighlightsByLayerId;if(this.selection)
+selectionHighlightsByLayerId=this.selection.highlightsByLayerId;else
+selectionHighlightsByLayerId={};var extraHighlightsByLayerId=this.extraHighlightsByLayerId||{};for(var i=1;i<=layers.length;i++){var layer=layers[layers.length-i];alreadyVisitedLayerIds[layer.layerId]=true;if(layer.objectInstance.name=='cc::NinePatchLayerImpl')
+continue;var layerQuad=layer.layerQuad.clone();if(layer.usingGpuRasterization){var pixelRatio=window.devicePixelRatio||1;layerQuad.borderWidth=2.0*pixelRatio;layerQuad.borderColor='rgba(154,205,50,0.75)';}else{layerQuad.borderColor='rgba(0,0,0,0.75)';}
+layerQuad.stackingGroupId=nextStackingGroupId++;layerQuad.selectionToSetIfClicked=new cc.LayerSelection(layer);layerQuad.layer=layer;if(this.showOtherLayers&&this.selectedLayer==layer)
+layerQuad.upperBorderColor='rgb(156,189,45)';if(this.showAnimationBounds)
+this.appendAnimationQuads_(quads,layer,layerQuad);this.appendImageQuads_(quads,layer,layerQuad);quads.push(layerQuad);if(this.showInvalidations)
+this.appendInvalidationQuads_(quads,layer,layerQuad);if(this.showUnrecordedRegion)
+this.appendUnrecordedRegionQuads_(quads,layer,layerQuad);if(this.showBottlenecks)
+this.appendBottleneckQuads_(quads,layer,layerQuad,layerQuad.stackingGroupId);if(this.showLayoutRects)
+this.appendLayoutRectQuads_(quads,layer,layerQuad);if(this.howToShowTiles==='coverage'){this.appendTileCoverageRectQuads_(quads,layer,layerQuad,this.tileHeatmapType);}else if(this.howToShowTiles!=='none'){this.appendTilesWithScaleQuads_(quads,layer,layerQuad,this.howToShowTiles,this.tileHeatmapType);}
+var highlights;highlights=extraHighlightsByLayerId[layer.layerId];if(highlights){this.appendHighlightQuadsForLayer_(quads,layer,layerQuad,highlights);}
+highlights=selectionHighlightsByLayerId[layer.layerId];if(highlights){this.appendHighlightQuadsForLayer_(quads,layer,layerQuad,highlights);}}
+this.layerTreeImpl.iterLayers(function(layer,depth,isMask,isReplica){if(!this.showOtherLayers&&this.selectedLayer!=layer)
+return;if(alreadyVisitedLayerIds[layer.layerId])
+return;var layerQuad=layer.layerQuad;var stackingGroupId=nextStackingGroupId++;if(this.showBottlenecks)
+this.appendBottleneckQuads_(quads,layer,layerQuad,stackingGroupId);},this);var tracedInputLatencies=this.layerTreeImpl.tracedInputLatencies;if(this.showInputEvents&&tracedInputLatencies){for(var i=0;i<tracedInputLatencies.length;i++){var coordinatesArray=tracedInputLatencies[i].args.data.coordinates;for(var j=0;j<coordinatesArray.length;j++){var inputQuad=tr.b.Quad.fromXYWH(coordinatesArray[j].x-25,coordinatesArray[j].y-25,50,50);inputQuad.borderColor='rgba(0, 0, 0, 0)';inputQuad.imageData=this.inputEventImageData_;quads.push(inputQuad);}}}
+return quads;},updateInfoBar_:function(infoBarMessages){if(infoBarMessages.length){this.infoBar_.removeAllButtons();this.infoBar_.message='Some problems were encountered...';this.infoBar_.addButton('More info...',function(e){var overlay=new tr.ui.b.Overlay();overlay.textContent='';infoBarMessages.forEach(function(message){var title=document.createElement('h3');title.textContent=message.header;var details=document.createElement('div');details.textContent=message.details;overlay.appendChild(title);overlay.appendChild(details);});overlay.visible=true;e.stopPropagation();return false;});this.infoBar_.visible=true;}else{this.infoBar_.removeAllButtons();this.infoBar_.message='';this.infoBar_.visible=false;}},getWhatRasterized_:function(){var lthi=this.layerTreeImpl_.layerTreeHostImpl;var renderProcess=lthi.objectInstance.parent;var tasks=[];renderProcess.iterateAllEvents(function(event){if(!(event instanceof tr.model.Slice))
+return;var tile=tr.e.cc.getTileFromRasterTaskSlice(event);if(tile===undefined)
+return false;if(tile.containingSnapshot==lthi)
+tasks.push(event);},this);return tasks;},updateWhatRasterizedLinkState_:function(){var tasks=this.getWhatRasterized_();if(tasks.length){this.whatRasterizedLink_.textContent=tasks.length+' raster tasks';this.whatRasterizedLink_.style.display='';}else{this.whatRasterizedLink_.textContent='';this.whatRasterizedLink_.style.display='none';}},onWhatRasterizedLinkClicked_:function(){var tasks=this.getWhatRasterized_();var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(tasks);this.dispatchEvent(event);}};return{LayerTreeQuadStackView:LayerTreeQuadStackView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var constants=tr.e.cc.constants;var LayerView=tr.ui.b.define('tr-ui-e-chrome-cc-layer-view');LayerView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.layerTreeQuadStackView_=new tr.ui.e.chrome.cc.LayerTreeQuadStackView();this.dragBar_=new tr.ui.b.DragHandle();this.analysisEl_=document.createElement('tr-ui-e-chrome-cc-layer-view-analysis');this.analysisEl_.addEventListener('requestSelectionChange',this.onRequestSelectionChangeFromAnalysisEl_.bind(this));this.dragBar_.target=this.analysisEl_;this.appendChild(this.layerTreeQuadStackView_);this.appendChild(this.dragBar_);this.appendChild(this.analysisEl_);this.layerTreeQuadStackView_.addEventListener('selection-change',function(){this.layerTreeQuadStackViewSelectionChanged_();}.bind(this));this.layerTreeQuadStackViewSelectionChanged_();},get layerTreeImpl(){return this.layerTreeQuadStackView_.layerTreeImpl;},set layerTreeImpl(newValue){return this.layerTreeQuadStackView_.layerTreeImpl=newValue;},set isRenderPassQuads(newValue){return this.layerTreeQuadStackView_.isRenderPassQuads=newValue;},get selection(){return this.layerTreeQuadStackView_.selection;},set selection(newValue){this.layerTreeQuadStackView_.selection=newValue;},regenerateContent:function(){this.layerTreeQuadStackView_.regenerateContent();},layerTreeQuadStackViewSelectionChanged_:function(){var selection=this.layerTreeQuadStackView_.selection;if(selection){this.dragBar_.style.display='';this.analysisEl_.style.display='';this.analysisEl_.textContent='';var layer=selection.layer;if(layer&&layer.args&&layer.args.pictures){this.analysisEl_.appendChild(this.createPictureBtn_(layer.args.pictures));}
+var analysis=selection.createAnalysis();this.analysisEl_.appendChild(analysis);}else{this.dragBar_.style.display='none';this.analysisEl_.style.display='none';var analysis=this.analysisEl_.firstChild;if(analysis)
+this.analysisEl_.removeChild(analysis);this.layerTreeQuadStackView_.style.height=window.getComputedStyle(this).height;}
+tr.b.dispatchSimpleEvent(this,'selection-change');},createPictureBtn_:function(pictures){if(!(pictures instanceof Array))
+pictures=[pictures];var link=document.createElement('tr-ui-a-analysis-link');link.selection=function(){var layeredPicture=new tr.e.cc.LayeredPicture(pictures);var snapshot=new tr.e.cc.PictureSnapshot(layeredPicture);snapshot.picture=layeredPicture;var selection=new tr.model.EventSet();selection.push(snapshot);return selection;};link.textContent='View in Picture Debugger';return link;},onRequestSelectionChangeFromAnalysisEl_:function(e){if(!(e.selection instanceof tr.ui.e.chrome.cc.Selection))
+return;e.stopPropagation();this.selection=e.selection;},get extraHighlightsByLayerId(){return this.layerTreeQuadStackView_.extraHighlightsByLayerId;},set extraHighlightsByLayerId(extraHighlightsByLayerId){this.layerTreeQuadStackView_.extraHighlightsByLayerId=extraHighlightsByLayerId;}};return{LayerView:LayerView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var LayerTreeHostImplSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-layer-tree-host-impl-snapshot-view',tr.ui.analysis.ObjectSnapshotView);LayerTreeHostImplSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-chrome-cc-lthi-s-view');this.selection_=undefined;this.layerPicker_=new tr.ui.e.chrome.cc.LayerPicker();this.layerPicker_.addEventListener('selection-change',this.onLayerPickerSelectionChanged_.bind(this));this.layerView_=new tr.ui.e.chrome.cc.LayerView();this.layerView_.addEventListener('selection-change',this.onLayerViewSelectionChanged_.bind(this));this.dragHandle_=new tr.ui.b.DragHandle();this.dragHandle_.horizontal=false;this.dragHandle_.target=this.layerView_;this.appendChild(this.layerPicker_);this.appendChild(this.dragHandle_);this.appendChild(this.layerView_);this.onLayerViewSelectionChanged_();this.onLayerPickerSelectionChanged_();},get objectSnapshot(){return this.objectSnapshot_;},set objectSnapshot(objectSnapshot){this.objectSnapshot_=objectSnapshot;var lthi=this.objectSnapshot;var layerTreeImpl;if(lthi)
+layerTreeImpl=lthi.getTree(this.layerPicker_.whichTree);this.layerPicker_.lthiSnapshot=lthi;this.layerView_.layerTreeImpl=layerTreeImpl;this.layerView_.regenerateContent();if(!this.selection_)
+return;this.selection=this.selection_.findEquivalent(lthi);},get selection(){return this.selection_;},set selection(selection){if(this.selection_==selection)
+return;this.selection_=selection;this.layerPicker_.selection=selection;this.layerView_.selection=selection;tr.b.dispatchSimpleEvent(this,'cc-selection-change');},onLayerPickerSelectionChanged_:function(){this.selection_=this.layerPicker_.selection;this.layerView_.selection=this.selection;this.layerView_.layerTreeImpl=this.layerPicker_.layerTreeImpl;this.layerView_.isRenderPassQuads=this.layerPicker_.isRenderPassQuads;this.layerView_.regenerateContent();tr.b.dispatchSimpleEvent(this,'cc-selection-change');},onLayerViewSelectionChanged_:function(){this.selection_=this.layerView_.selection;this.layerPicker_.selection=this.selection;tr.b.dispatchSimpleEvent(this,'cc-selection-change');},get extraHighlightsByLayerId(){return this.layerView_.extraHighlightsByLayerId;},set extraHighlightsByLayerId(extraHighlightsByLayerId){this.layerView_.extraHighlightsByLayerId=extraHighlightsByLayerId;}};tr.ui.analysis.ObjectSnapshotView.register(LayerTreeHostImplSnapshotView,{typeName:'cc::LayerTreeHostImpl'});return{LayerTreeHostImplSnapshotView:LayerTreeHostImplSnapshotView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var OPS_TIMING_ITERATIONS=3;var CHART_PADDING_LEFT=65;var CHART_PADDING_RIGHT=40;var AXIS_PADDING_LEFT=60;var AXIS_PADDING_RIGHT=35;var AXIS_PADDING_TOP=25;var AXIS_PADDING_BOTTOM=45;var AXIS_LABEL_PADDING=5;var AXIS_TICK_SIZE=10;var LABEL_PADDING=5;var LABEL_INTERLEAVE_OFFSET=15;var BAR_PADDING=5;var VERTICAL_TICKS=5;var HUE_CHAR_CODE_ADJUSTMENT=5.7;var PictureOpsChartSummaryView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-ops-chart-summary-view');PictureOpsChartSummaryView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.picture_=undefined;this.pictureDataProcessed_=false;this.chartScale_=window.devicePixelRatio;this.chart_=document.createElement('canvas');this.chartCtx_=this.chart_.getContext('2d');this.appendChild(this.chart_);this.opsTimingData_=[];this.chartWidth_=0;this.chartHeight_=0;this.requiresRedraw_=true;this.currentBarMouseOverTarget_=null;this.chart_.addEventListener('mousemove',this.onMouseMove_.bind(this));},get requiresRedraw(){return this.requiresRedraw_;},set requiresRedraw(requiresRedraw){this.requiresRedraw_=requiresRedraw;},get picture(){return this.picture_;},set picture(picture){this.picture_=picture;this.pictureDataProcessed_=false;if(this.classList.contains('hidden'))
+return;this.processPictureData_();this.requiresRedraw=true;this.updateChartContents();},hide:function(){this.classList.add('hidden');},show:function(){this.classList.remove('hidden');if(this.pictureDataProcessed_)
+return;this.processPictureData_();this.requiresRedraw=true;this.updateChartContents();},onMouseMove_:function(e){var lastBarMouseOverTarget=this.currentBarMouseOverTarget_;this.currentBarMouseOverTarget_=null;var x=e.offsetX;var y=e.offsetY;var chartLeft=CHART_PADDING_LEFT;var chartRight=this.chartWidth_-CHART_PADDING_RIGHT;var chartTop=AXIS_PADDING_TOP;var chartBottom=this.chartHeight_-AXIS_PADDING_BOTTOM;var chartInnerWidth=chartRight-chartLeft;if(x>chartLeft&&x<chartRight&&y>chartTop&&y<chartBottom){this.currentBarMouseOverTarget_=Math.floor((x-chartLeft)/chartInnerWidth*this.opsTimingData_.length);this.currentBarMouseOverTarget_=tr.b.clamp(this.currentBarMouseOverTarget_,0,this.opsTimingData_.length-1);}
+if(this.currentBarMouseOverTarget_===lastBarMouseOverTarget)
+return;this.drawChartContents_();},updateChartContents:function(){if(this.requiresRedraw)
+this.updateChartDimensions_();this.drawChartContents_();},updateChartDimensions_:function(){this.chartWidth_=this.offsetWidth;this.chartHeight_=this.offsetHeight;this.chart_.width=this.chartWidth_*this.chartScale_;this.chart_.height=this.chartHeight_*this.chartScale_;this.chart_.style.width=this.chartWidth_+'px';this.chart_.style.height=this.chartHeight_+'px';this.chartCtx_.scale(this.chartScale_,this.chartScale_);},processPictureData_:function(){this.resetOpsTimingData_();this.pictureDataProcessed_=true;if(!this.picture_)
+return;var ops=this.picture_.getOps();if(!ops)
+return;ops=this.picture_.tagOpsWithTimings(ops);if(ops[0].cmd_time===undefined)
+return;this.collapseOpsToTimingBuckets_(ops);},drawChartContents_:function(){this.clearChartContents_();if(this.opsTimingData_.length===0){this.showNoTimingDataMessage_();return;}
+this.drawChartAxes_();this.drawBars_();this.drawLineAtBottomOfChart_();if(this.currentBarMouseOverTarget_===null)
+return;this.drawTooltip_();},drawLineAtBottomOfChart_:function(){this.chartCtx_.strokeStyle='#AAA';this.chartCtx_.moveTo(0,this.chartHeight_-0.5);this.chartCtx_.lineTo(this.chartWidth_,this.chartHeight_-0.5);this.chartCtx_.stroke();},drawTooltip_:function(){var tooltipData=this.opsTimingData_[this.currentBarMouseOverTarget_];var tooltipTitle=tooltipData.cmd_string;var tooltipTime=tooltipData.cmd_time.toFixed(4);var tooltipWidth=110;var tooltipHeight=40;var chartInnerWidth=this.chartWidth_-CHART_PADDING_RIGHT-
+CHART_PADDING_LEFT;var barWidth=chartInnerWidth/this.opsTimingData_.length;var tooltipOffset=Math.round((tooltipWidth-barWidth)*0.5);var left=CHART_PADDING_LEFT+this.currentBarMouseOverTarget_*barWidth-tooltipOffset;var top=Math.round((this.chartHeight_-tooltipHeight)*0.5);this.chartCtx_.save();this.chartCtx_.shadowOffsetX=0;this.chartCtx_.shadowOffsetY=5;this.chartCtx_.shadowBlur=4;this.chartCtx_.shadowColor='rgba(0,0,0,0.4)';this.chartCtx_.strokeStyle='#888';this.chartCtx_.fillStyle='#EEE';this.chartCtx_.fillRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.shadowColor='transparent';this.chartCtx_.translate(0.5,0.5);this.chartCtx_.strokeRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.restore();this.chartCtx_.fillStyle='#222';this.chartCtx_.textBaseline='top';this.chartCtx_.font='800 12px Arial';this.chartCtx_.fillText(tooltipTitle,left+8,top+8);this.chartCtx_.fillStyle='#555';this.chartCtx_.textBaseline='top';this.chartCtx_.font='400 italic 10px Arial';this.chartCtx_.fillText('Total: '+tooltipTime+'ms',left+8,top+22);},drawBars_:function(){var len=this.opsTimingData_.length;var max=this.opsTimingData_[0].cmd_time;var min=this.opsTimingData_[len-1].cmd_time;var width=this.chartWidth_-CHART_PADDING_LEFT-CHART_PADDING_RIGHT;var height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;var barWidth=Math.floor(width/len);var opData;var opTiming;var opHeight;var opLabel;var barLeft;for(var b=0;b<len;b++){opData=this.opsTimingData_[b];opTiming=opData.cmd_time/max;opHeight=Math.round(Math.max(1,opTiming*height));opLabel=opData.cmd_string;barLeft=CHART_PADDING_LEFT+b*barWidth;this.chartCtx_.fillStyle=this.getOpColor_(opLabel);this.chartCtx_.fillRect(barLeft+BAR_PADDING,AXIS_PADDING_TOP+
+height-opHeight,barWidth-2*BAR_PADDING,opHeight);}},getOpColor_:function(opName){var characters=opName.split('');var hue=characters.reduce(this.reduceNameToHue,0)%360;return'hsl('+hue+', 30%, 50%)';},reduceNameToHue:function(previousValue,currentValue,index,array){return Math.round(previousValue+currentValue.charCodeAt(0)*HUE_CHAR_CODE_ADJUSTMENT);},drawChartAxes_:function(){var len=this.opsTimingData_.length;var max=this.opsTimingData_[0].cmd_time;var min=this.opsTimingData_[len-1].cmd_time;var width=this.chartWidth_-AXIS_PADDING_LEFT-AXIS_PADDING_RIGHT;var height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;var totalBarWidth=this.chartWidth_-CHART_PADDING_LEFT-
+CHART_PADDING_RIGHT;var barWidth=Math.floor(totalBarWidth/len);var tickYInterval=height/(VERTICAL_TICKS-1);var tickYPosition=0;var tickValInterval=(max-min)/(VERTICAL_TICKS-1);var tickVal=0;this.chartCtx_.fillStyle='#333';this.chartCtx_.strokeStyle='#777';this.chartCtx_.save();this.chartCtx_.translate(0.5,0.5);this.chartCtx_.save();this.chartCtx_.translate(AXIS_PADDING_LEFT,AXIS_PADDING_TOP);this.chartCtx_.moveTo(0,0);this.chartCtx_.lineTo(0,height);this.chartCtx_.lineTo(width,height);this.chartCtx_.font='10px Arial';this.chartCtx_.textAlign='right';this.chartCtx_.textBaseline='middle';for(var t=0;t<VERTICAL_TICKS;t++){tickYPosition=Math.round(t*tickYInterval);tickVal=(max-t*tickValInterval).toFixed(4);this.chartCtx_.moveTo(0,tickYPosition);this.chartCtx_.lineTo(-AXIS_TICK_SIZE,tickYPosition);this.chartCtx_.fillText(tickVal,-AXIS_TICK_SIZE-AXIS_LABEL_PADDING,tickYPosition);}
+this.chartCtx_.stroke();this.chartCtx_.restore();this.chartCtx_.save();this.chartCtx_.translate(CHART_PADDING_LEFT+Math.round(barWidth*0.5),AXIS_PADDING_TOP+height+LABEL_PADDING);this.chartCtx_.font='10px Arial';this.chartCtx_.textAlign='center';this.chartCtx_.textBaseline='top';var labelTickLeft;var labelTickBottom;for(var l=0;l<len;l++){labelTickLeft=Math.round(l*barWidth);labelTickBottom=l%2*LABEL_INTERLEAVE_OFFSET;this.chartCtx_.save();this.chartCtx_.moveTo(labelTickLeft,-LABEL_PADDING);this.chartCtx_.lineTo(labelTickLeft,labelTickBottom);this.chartCtx_.stroke();this.chartCtx_.restore();this.chartCtx_.fillText(this.opsTimingData_[l].cmd_string,labelTickLeft,labelTickBottom);}
+this.chartCtx_.restore();this.chartCtx_.restore();},clearChartContents_:function(){this.chartCtx_.clearRect(0,0,this.chartWidth_,this.chartHeight_);},showNoTimingDataMessage_:function(){this.chartCtx_.font='800 italic 14px Arial';this.chartCtx_.fillStyle='#333';this.chartCtx_.textAlign='center';this.chartCtx_.textBaseline='middle';this.chartCtx_.fillText('No timing data available.',this.chartWidth_*0.5,this.chartHeight_*0.5);},collapseOpsToTimingBuckets_:function(ops){var opsTimingDataIndexHash_={};var timingData=this.opsTimingData_;var op;var opIndex;for(var i=0;i<ops.length;i++){op=ops[i];if(op.cmd_time===undefined)
+continue;opIndex=opsTimingDataIndexHash_[op.cmd_string]||null;if(opIndex===null){timingData.push({cmd_time:0,cmd_string:op.cmd_string});opIndex=timingData.length-1;opsTimingDataIndexHash_[op.cmd_string]=opIndex;}
+timingData[opIndex].cmd_time+=op.cmd_time;}
+timingData.sort(this.sortTimingBucketsByOpTimeDescending_);this.collapseTimingBucketsToOther_(4);},collapseTimingBucketsToOther_:function(count){var timingData=this.opsTimingData_;var otherSource=timingData.splice(count,timingData.length-count);var otherDestination=null;if(!otherSource.length)
+return;timingData.push({cmd_time:0,cmd_string:'Other'});otherDestination=timingData[timingData.length-1];for(var i=0;i<otherSource.length;i++){otherDestination.cmd_time+=otherSource[i].cmd_time;}},sortTimingBucketsByOpTimeDescending_:function(a,b){return b.cmd_time-a.cmd_time;},resetOpsTimingData_:function(){this.opsTimingData_.length=0;}};return{PictureOpsChartSummaryView:PictureOpsChartSummaryView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var BAR_PADDING=1;var BAR_WIDTH=5;var CHART_PADDING_LEFT=65;var CHART_PADDING_RIGHT=30;var CHART_PADDING_BOTTOM=35;var CHART_PADDING_TOP=20;var AXIS_PADDING_LEFT=55;var AXIS_PADDING_RIGHT=30;var AXIS_PADDING_BOTTOM=35;var AXIS_PADDING_TOP=20;var AXIS_TICK_SIZE=5;var AXIS_LABEL_PADDING=5;var VERTICAL_TICKS=5;var HUE_CHAR_CODE_ADJUSTMENT=5.7;var PictureOpsChartView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-ops-chart-view');PictureOpsChartView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.picture_=undefined;this.pictureOps_=undefined;this.opCosts_=undefined;this.chartScale_=window.devicePixelRatio;this.chart_=document.createElement('canvas');this.chartCtx_=this.chart_.getContext('2d');this.appendChild(this.chart_);this.selectedOpIndex_=undefined;this.chartWidth_=0;this.chartHeight_=0;this.dimensionsHaveChanged_=true;this.currentBarMouseOverTarget_=undefined;this.ninetyFifthPercentileCost_=0;this.totalOpCost_=0;this.chart_.addEventListener('click',this.onClick_.bind(this));this.chart_.addEventListener('mousemove',this.onMouseMove_.bind(this));this.usePercentileScale_=false;this.usePercentileScaleCheckbox_=tr.ui.b.createCheckBox(this,'usePercentileScale','PictureOpsChartView.usePercentileScale',false,'Limit to 95%-ile');this.usePercentileScaleCheckbox_.classList.add('use-percentile-scale');this.appendChild(this.usePercentileScaleCheckbox_);},get dimensionsHaveChanged(){return this.dimensionsHaveChanged_;},set dimensionsHaveChanged(dimensionsHaveChanged){this.dimensionsHaveChanged_=dimensionsHaveChanged;},get usePercentileScale(){return this.usePercentileScale_;},set usePercentileScale(usePercentileScale){this.usePercentileScale_=usePercentileScale;this.drawChartContents_();},get numOps(){return this.opCosts_.length;},get selectedOpIndex(){return this.selectedOpIndex_;},set selectedOpIndex(selectedOpIndex){if(selectedOpIndex<0)throw new Error('Invalid index');if(selectedOpIndex>=this.numOps)throw new Error('Invalid index');this.selectedOpIndex_=selectedOpIndex;},get picture(){return this.picture_;},set picture(picture){this.picture_=picture;this.pictureOps_=picture.tagOpsWithTimings(picture.getOps());this.currentBarMouseOverTarget_=undefined;this.processPictureData_();this.dimensionsHaveChanged=true;},processPictureData_:function(){if(this.pictureOps_===undefined)
+return;var totalOpCost=0;this.opCosts_=this.pictureOps_.map(function(op){totalOpCost+=op.cmd_time;return op.cmd_time;});this.opCosts_.sort();var ninetyFifthPercentileCostIndex=Math.floor(this.opCosts_.length*0.95);this.ninetyFifthPercentileCost_=this.opCosts_[ninetyFifthPercentileCostIndex];this.maxCost_=this.opCosts_[this.opCosts_.length-1];this.totalOpCost_=totalOpCost;},extractBarIndex_:function(e){var index=undefined;if(this.pictureOps_===undefined||this.pictureOps_.length===0)
+return index;var x=e.offsetX;var y=e.offsetY;var totalBarWidth=(BAR_WIDTH+BAR_PADDING)*this.pictureOps_.length;var chartLeft=CHART_PADDING_LEFT;var chartTop=0;var chartBottom=this.chartHeight_-CHART_PADDING_BOTTOM;var chartRight=chartLeft+totalBarWidth;if(x<chartLeft||x>chartRight||y<chartTop||y>chartBottom)
+return index;index=Math.floor((x-chartLeft)/totalBarWidth*this.pictureOps_.length);index=tr.b.clamp(index,0,this.pictureOps_.length-1);return index;},onClick_:function(e){var barClicked=this.extractBarIndex_(e);if(barClicked===undefined)
+return;if(barClicked===this.selectedOpIndex)
+this.selectedOpIndex=undefined;else
+this.selectedOpIndex=barClicked;e.preventDefault();tr.b.dispatchSimpleEvent(this,'selection-changed',false);},onMouseMove_:function(e){var lastBarMouseOverTarget=this.currentBarMouseOverTarget_;this.currentBarMouseOverTarget_=this.extractBarIndex_(e);if(this.currentBarMouseOverTarget_===lastBarMouseOverTarget)
+return;this.drawChartContents_();},scrollSelectedItemIntoViewIfNecessary:function(){if(this.selectedOpIndex===undefined)
+return;var width=this.offsetWidth;var left=this.scrollLeft;var right=left+width;var targetLeft=CHART_PADDING_LEFT+
+(BAR_WIDTH+BAR_PADDING)*this.selectedOpIndex;if(targetLeft>left&&targetLeft<right)
+return;this.scrollLeft=(targetLeft-width*0.5);},updateChartContents:function(){if(this.dimensionsHaveChanged)
+this.updateChartDimensions_();this.drawChartContents_();},updateChartDimensions_:function(){if(!this.pictureOps_)
+return;var width=CHART_PADDING_LEFT+CHART_PADDING_RIGHT+
+((BAR_WIDTH+BAR_PADDING)*this.pictureOps_.length);if(width<this.offsetWidth)
+width=this.offsetWidth;this.chartWidth_=width;this.chartHeight_=this.getBoundingClientRect().height;this.chart_.width=this.chartWidth_*this.chartScale_;this.chart_.height=this.chartHeight_*this.chartScale_;this.chart_.style.width=this.chartWidth_+'px';this.chart_.style.height=this.chartHeight_+'px';this.chartCtx_.scale(this.chartScale_,this.chartScale_);this.dimensionsHaveChanged=false;},drawChartContents_:function(){this.clearChartContents_();if(this.pictureOps_===undefined||this.pictureOps_.length===0||this.pictureOps_[0].cmd_time===undefined){this.showNoTimingDataMessage_();return;}
+this.drawSelection_();this.drawBars_();this.drawChartAxes_();this.drawLinesAtTickMarks_();this.drawLineAtBottomOfChart_();if(this.currentBarMouseOverTarget_===undefined)
+return;this.drawTooltip_();},drawSelection_:function(){if(this.selectedOpIndex===undefined)
+return;var width=(BAR_WIDTH+BAR_PADDING)*this.selectedOpIndex;this.chartCtx_.fillStyle='rgb(223, 235, 230)';this.chartCtx_.fillRect(CHART_PADDING_LEFT,CHART_PADDING_TOP,width,this.chartHeight_-CHART_PADDING_TOP-CHART_PADDING_BOTTOM);},drawChartAxes_:function(){var min=this.opCosts_[0];var max=this.opCosts_[this.opCosts_.length-1];var height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;var tickYInterval=height/(VERTICAL_TICKS-1);var tickYPosition=0;var tickValInterval=(max-min)/(VERTICAL_TICKS-1);var tickVal=0;this.chartCtx_.fillStyle='#333';this.chartCtx_.strokeStyle='#777';this.chartCtx_.save();this.chartCtx_.translate(0.5,0.5);this.chartCtx_.beginPath();this.chartCtx_.moveTo(AXIS_PADDING_LEFT,AXIS_PADDING_TOP);this.chartCtx_.lineTo(AXIS_PADDING_LEFT,this.chartHeight_-
+AXIS_PADDING_BOTTOM);this.chartCtx_.lineTo(this.chartWidth_-AXIS_PADDING_RIGHT,this.chartHeight_-AXIS_PADDING_BOTTOM);this.chartCtx_.stroke();this.chartCtx_.closePath();this.chartCtx_.translate(AXIS_PADDING_LEFT,AXIS_PADDING_TOP);this.chartCtx_.font='10px Arial';this.chartCtx_.textAlign='right';this.chartCtx_.textBaseline='middle';this.chartCtx_.beginPath();for(var t=0;t<VERTICAL_TICKS;t++){tickYPosition=Math.round(t*tickYInterval);tickVal=(max-t*tickValInterval).toFixed(4);this.chartCtx_.moveTo(0,tickYPosition);this.chartCtx_.lineTo(-AXIS_TICK_SIZE,tickYPosition);this.chartCtx_.fillText(tickVal,-AXIS_TICK_SIZE-AXIS_LABEL_PADDING,tickYPosition);}
+this.chartCtx_.stroke();this.chartCtx_.closePath();this.chartCtx_.restore();},drawLinesAtTickMarks_:function(){var height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;var width=this.chartWidth_-AXIS_PADDING_LEFT-AXIS_PADDING_RIGHT;var tickYInterval=height/(VERTICAL_TICKS-1);var tickYPosition=0;this.chartCtx_.save();this.chartCtx_.translate(AXIS_PADDING_LEFT+0.5,AXIS_PADDING_TOP+0.5);this.chartCtx_.beginPath();this.chartCtx_.strokeStyle='rgba(0,0,0,0.05)';for(var t=0;t<VERTICAL_TICKS;t++){tickYPosition=Math.round(t*tickYInterval);this.chartCtx_.moveTo(0,tickYPosition);this.chartCtx_.lineTo(width,tickYPosition);this.chartCtx_.stroke();}
+this.chartCtx_.restore();this.chartCtx_.closePath();},drawLineAtBottomOfChart_:function(){this.chartCtx_.strokeStyle='#AAA';this.chartCtx_.beginPath();this.chartCtx_.moveTo(0,this.chartHeight_-0.5);this.chartCtx_.lineTo(this.chartWidth_,this.chartHeight_-0.5);this.chartCtx_.stroke();this.chartCtx_.closePath();},drawTooltip_:function(){var tooltipData=this.pictureOps_[this.currentBarMouseOverTarget_];var tooltipTitle=tooltipData.cmd_string;var tooltipTime=tooltipData.cmd_time.toFixed(4);var toolTipTimePercentage=((tooltipData.cmd_time/this.totalOpCost_)*100).toFixed(2);var tooltipWidth=120;var tooltipHeight=40;var chartInnerWidth=this.chartWidth_-CHART_PADDING_RIGHT-
+CHART_PADDING_LEFT;var barWidth=BAR_WIDTH+BAR_PADDING;var tooltipOffset=Math.round((tooltipWidth-barWidth)*0.5);var left=CHART_PADDING_LEFT+this.currentBarMouseOverTarget_*barWidth-tooltipOffset;var top=Math.round((this.chartHeight_-tooltipHeight)*0.5);this.chartCtx_.save();this.chartCtx_.shadowOffsetX=0;this.chartCtx_.shadowOffsetY=5;this.chartCtx_.shadowBlur=4;this.chartCtx_.shadowColor='rgba(0,0,0,0.4)';this.chartCtx_.strokeStyle='#888';this.chartCtx_.fillStyle='#EEE';this.chartCtx_.fillRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.shadowColor='transparent';this.chartCtx_.translate(0.5,0.5);this.chartCtx_.strokeRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.restore();this.chartCtx_.fillStyle='#222';this.chartCtx_.textAlign='left';this.chartCtx_.textBaseline='top';this.chartCtx_.font='800 12px Arial';this.chartCtx_.fillText(tooltipTitle,left+8,top+8);this.chartCtx_.fillStyle='#555';this.chartCtx_.font='400 italic 10px Arial';this.chartCtx_.fillText(tooltipTime+'ms ('+
+toolTipTimePercentage+'%)',left+8,top+22);},drawBars_:function(){var op;var opColor=0;var opHeight=0;var opWidth=BAR_WIDTH+BAR_PADDING;var opHover=false;var bottom=this.chartHeight_-CHART_PADDING_BOTTOM;var maxHeight=this.chartHeight_-CHART_PADDING_BOTTOM-
+CHART_PADDING_TOP;var maxValue;if(this.usePercentileScale)
+maxValue=this.ninetyFifthPercentileCost_;else
+maxValue=this.maxCost_;for(var b=0;b<this.pictureOps_.length;b++){op=this.pictureOps_[b];opHeight=Math.round((op.cmd_time/maxValue)*maxHeight);opHeight=Math.max(opHeight,1);opHover=(b===this.currentBarMouseOverTarget_);opColor=this.getOpColor_(op.cmd_string,opHover);if(b===this.selectedOpIndex)
+this.chartCtx_.fillStyle='#FFFF00';else
+this.chartCtx_.fillStyle=opColor;this.chartCtx_.fillRect(CHART_PADDING_LEFT+b*opWidth,bottom-opHeight,BAR_WIDTH,opHeight);}},getOpColor_:function(opName,hover){var characters=opName.split('');var hue=characters.reduce(this.reduceNameToHue,0)%360;var saturation=30;var lightness=hover?'75%':'50%';return'hsl('+hue+', '+saturation+'%, '+lightness+'%)';},reduceNameToHue:function(previousValue,currentValue,index,array){return Math.round(previousValue+currentValue.charCodeAt(0)*HUE_CHAR_CODE_ADJUSTMENT);},clearChartContents_:function(){this.chartCtx_.clearRect(0,0,this.chartWidth_,this.chartHeight_);},showNoTimingDataMessage_:function(){this.chartCtx_.font='800 italic 14px Arial';this.chartCtx_.fillStyle='#333';this.chartCtx_.textAlign='center';this.chartCtx_.textBaseline='middle';this.chartCtx_.fillText('No timing data available.',this.chartWidth_*0.5,this.chartHeight_*0.5);}};return{PictureOpsChartView:PictureOpsChartView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var THIS_DOC=document.currentScript.ownerDocument;var PictureDebugger=tr.ui.b.define('tr-ui-e-chrome-cc-picture-debugger');PictureDebugger.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){var node=tr.ui.b.instantiateTemplate('#tr-ui-e-chrome-cc-picture-debugger-template',THIS_DOC);this.appendChild(node);this.pictureAsImageData_=undefined;this.showOverdraw_=false;this.zoomScaleValue_=1;this.sizeInfo_=this.querySelector('.size');this.rasterArea_=this.querySelector('raster-area');this.rasterCanvas_=this.rasterArea_.querySelector('canvas');this.rasterCtx_=this.rasterCanvas_.getContext('2d');this.filename_=this.querySelector('.filename');this.drawOpsChartSummaryView_=new tr.ui.e.chrome.cc.PictureOpsChartSummaryView();this.drawOpsChartView_=new tr.ui.e.chrome.cc.PictureOpsChartView();this.drawOpsChartView_.addEventListener('selection-changed',this.onChartBarClicked_.bind(this));this.exportButton_=this.querySelector('.export');this.exportButton_.addEventListener('click',this.onSaveAsSkPictureClicked_.bind(this));this.trackMouse_();var overdrawCheckbox=tr.ui.b.createCheckBox(this,'showOverdraw','pictureView.showOverdraw',false,'Show overdraw');var chartCheckbox=tr.ui.b.createCheckBox(this,'showSummaryChart','pictureView.showSummaryChart',false,'Show timing summary');var pictureInfo=this.querySelector('picture-info');pictureInfo.appendChild(overdrawCheckbox);pictureInfo.appendChild(chartCheckbox);this.drawOpsView_=new tr.ui.e.chrome.cc.PictureOpsListView();this.drawOpsView_.addEventListener('selection-changed',this.onChangeDrawOps_.bind(this));var leftPanel=this.querySelector('left-panel');leftPanel.appendChild(this.drawOpsChartSummaryView_);leftPanel.appendChild(this.drawOpsView_);var middleDragHandle=new tr.ui.b.DragHandle();middleDragHandle.horizontal=false;middleDragHandle.target=leftPanel;var rightPanel=this.querySelector('right-panel');rightPanel.replaceChild(this.drawOpsChartView_,rightPanel.querySelector('tr-ui-e-chrome-cc-picture-ops-chart-view'));this.infoBar_=document.createElement('tr-ui-b-info-bar');this.rasterArea_.appendChild(this.infoBar_);this.insertBefore(middleDragHandle,rightPanel);this.picture_=undefined;var hkc=document.createElement('tv-ui-b-hotkey-controller');hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',thisArg:this,keyCode:'h'.charCodeAt(0),callback:function(e){this.moveSelectedOpBy(-1);e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',thisArg:this,keyCode:'l'.charCodeAt(0),callback:function(e){this.moveSelectedOpBy(1);e.stopPropagation();}}));this.appendChild(hkc);this.mutationObserver_=new MutationObserver(this.onMutation_.bind(this));this.mutationObserver_.observe(leftPanel,{attributes:true});},onMutation_:function(mutations){for(var m=0;m<mutations.length;m++){if(mutations[m].attributeName==='style'){this.drawOpsChartSummaryView_.requiresRedraw=true;this.drawOpsChartSummaryView_.updateChartContents();this.drawOpsChartView_.dimensionsHaveChanged=true;this.drawOpsChartView_.updateChartContents();break;}}},onSaveAsSkPictureClicked_:function(){var rawData=atob(this.picture_.getBase64SkpData());var length=rawData.length;var arrayBuffer=new ArrayBuffer(length);var uint8Array=new Uint8Array(arrayBuffer);for(var c=0;c<length;c++)
+uint8Array[c]=rawData.charCodeAt(c);var blob=new Blob([uint8Array],{type:'application/octet-binary'});var blobUrl=window.webkitURL.createObjectURL(blob);var link=document.createElementNS('http://www.w3.org/1999/xhtml','a');link.href=blobUrl;link.download=this.filename_.value;var event=document.createEvent('MouseEvents');event.initMouseEvent('click',true,false,window,0,0,0,0,0,false,false,false,false,0,null);link.dispatchEvent(event);},get picture(){return this.picture_;},set picture(picture){this.drawOpsView_.picture=picture;this.drawOpsChartView_.picture=picture;this.drawOpsChartSummaryView_.picture=picture;this.picture_=picture;this.exportButton_.disabled=!this.picture_.canSave;if(picture){var size=this.getRasterCanvasSize_();this.rasterCanvas_.width=size.width;this.rasterCanvas_.height=size.height;}
+var bounds=this.rasterArea_.getBoundingClientRect();var selectorBounds=this.mouseModeSelector_.getBoundingClientRect();this.mouseModeSelector_.pos={x:(bounds.right-selectorBounds.width-10),y:bounds.top};this.rasterize_();this.scheduleUpdateContents_();},getRasterCanvasSize_:function(){var style=window.getComputedStyle(this.rasterArea_);var width=Math.max(parseInt(style.width),this.picture_.layerRect.width);var height=Math.max(parseInt(style.height),this.picture_.layerRect.height);return{width:width,height:height};},scheduleUpdateContents_:function(){if(this.updateContentsPending_)
+return;this.updateContentsPending_=true;tr.b.requestAnimationFrameInThisFrameIfPossible(this.updateContents_.bind(this));},updateContents_:function(){this.updateContentsPending_=false;if(this.picture_){this.sizeInfo_.textContent='('+
+this.picture_.layerRect.width+' x '+
+this.picture_.layerRect.height+')';}
+this.drawOpsChartView_.updateChartContents();this.drawOpsChartView_.scrollSelectedItemIntoViewIfNecessary();if(!this.pictureAsImageData_)
+return;this.infoBar_.visible=false;this.infoBar_.removeAllButtons();if(this.pictureAsImageData_.error){this.infoBar_.message='Cannot rasterize...';this.infoBar_.addButton('More info...',function(e){var overlay=new tr.ui.b.Overlay();overlay.textContent=this.pictureAsImageData_.error;overlay.visible=true;e.stopPropagation();return false;}.bind(this));this.infoBar_.visible=true;}
+this.drawPicture_();},drawPicture_:function(){var size=this.getRasterCanvasSize_();if(size.width!==this.rasterCanvas_.width)
+this.rasterCanvas_.width=size.width;if(size.height!==this.rasterCanvas_.height)
+this.rasterCanvas_.height=size.height;this.rasterCtx_.clearRect(0,0,size.width,size.height);if(!this.pictureAsImageData_.imageData)
+return;var imgCanvas=this.pictureAsImageData_.asCanvas();var w=imgCanvas.width;var h=imgCanvas.height;this.rasterCtx_.drawImage(imgCanvas,0,0,w,h,0,0,w*this.zoomScaleValue_,h*this.zoomScaleValue_);},rasterize_:function(){if(this.picture_){this.picture_.rasterize({stopIndex:this.drawOpsView_.selectedOpIndex,showOverdraw:this.showOverdraw_},this.onRasterComplete_.bind(this));}},onRasterComplete_:function(pictureAsImageData){this.pictureAsImageData_=pictureAsImageData;this.scheduleUpdateContents_();},moveSelectedOpBy:function(increment){if(this.selectedOpIndex===undefined){this.selectedOpIndex=0;return;}
+this.selectedOpIndex=tr.b.clamp(this.selectedOpIndex+increment,0,this.numOps);},get numOps(){return this.drawOpsView_.numOps;},get selectedOpIndex(){return this.drawOpsView_.selectedOpIndex;},set selectedOpIndex(index){this.drawOpsView_.selectedOpIndex=index;this.drawOpsChartView_.selectedOpIndex=index;},onChartBarClicked_:function(e){this.drawOpsView_.selectedOpIndex=this.drawOpsChartView_.selectedOpIndex;},onChangeDrawOps_:function(e){this.rasterize_();this.scheduleUpdateContents_();this.drawOpsChartView_.selectedOpIndex=this.drawOpsView_.selectedOpIndex;},set showOverdraw(v){this.showOverdraw_=v;this.rasterize_();},set showSummaryChart(chartShouldBeVisible){if(chartShouldBeVisible)
+this.drawOpsChartSummaryView_.show();else
+this.drawOpsChartSummaryView_.hide();},trackMouse_:function(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this.rasterArea_;this.rasterArea_.appendChild(this.mouseModeSelector_);this.mouseModeSelector_.supportedModeMask=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.mode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.defaultMode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.settingsKey='pictureDebugger.mouseModeSelector';this.mouseModeSelector_.addEventListener('beginzoom',this.onBeginZoom_.bind(this));this.mouseModeSelector_.addEventListener('updatezoom',this.onUpdateZoom_.bind(this));this.mouseModeSelector_.addEventListener('endzoom',this.onEndZoom_.bind(this));},onBeginZoom_:function(e){this.isZooming_=true;this.lastMouseViewPos_=this.extractRelativeMousePosition_(e);e.preventDefault();},onUpdateZoom_:function(e){if(!this.isZooming_)
+return;var currentMouseViewPos=this.extractRelativeMousePosition_(e);this.zoomScaleValue_+=((this.lastMouseViewPos_.y-currentMouseViewPos.y)*0.001);this.zoomScaleValue_=Math.max(this.zoomScaleValue_,0.1);this.drawPicture_();this.lastMouseViewPos_=currentMouseViewPos;},onEndZoom_:function(e){this.lastMouseViewPos_=undefined;this.isZooming_=false;e.preventDefault();},extractRelativeMousePosition_:function(e){return{x:e.clientX-this.rasterArea_.offsetLeft,y:e.clientY-this.rasterArea_.offsetTop};}};return{PictureDebugger:PictureDebugger};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var PictureSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-snapshot-view',tr.ui.analysis.ObjectSnapshotView);PictureSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-chrome-cc-picture-snapshot-view');this.pictureDebugger_=new tr.ui.e.chrome.cc.PictureDebugger();this.appendChild(this.pictureDebugger_);},updateContents:function(){if(this.objectSnapshot_&&this.pictureDebugger_)
+this.pictureDebugger_.picture=this.objectSnapshot_;}};tr.ui.analysis.ObjectSnapshotView.register(PictureSnapshotView,{typeNames:['cc::Picture','cc::LayeredPicture'],showInstances:false});return{PictureSnapshotView:PictureSnapshotView};});'use strict';tr.exportTo('tr.e.cc',function(){var knownRasterTaskNames=['TileManager::RunRasterTask','RasterWorkerPoolTaskImpl::RunRasterOnThread','RasterWorkerPoolTaskImpl::Raster','RasterTaskImpl::Raster','cc::RasterTask','RasterTask'];var knownAnalysisTaskNames=['TileManager::RunAnalyzeTask','RasterWorkerPoolTaskImpl::RunAnalysisOnThread','RasterWorkerPoolTaskImpl::Analyze','RasterTaskImpl::Analyze','cc::AnalyzeTask','AnalyzeTask'];function getTileFromRasterTaskSlice(slice){if(!(isSliceDoingRasterization(slice)||isSliceDoingAnalysis(slice)))
+return undefined;var tileData;if(slice.args.data)
+tileData=slice.args.data;else
+tileData=slice.args.tileData;if(tileData===undefined)
+return undefined;if(tileData.tile_id)
+return tileData.tile_id;var tile=tileData.tileId;if(!(tile instanceof tr.e.cc.TileSnapshot))
+return undefined;return tileData.tileId;}
+function isSliceDoingRasterization(slice){if(knownRasterTaskNames.indexOf(slice.title)!==-1)
+return true;return false;}
+function isSliceDoingAnalysis(slice){if(knownAnalysisTaskNames.indexOf(slice.title)!==-1)
+return true;return false;}
+return{getTileFromRasterTaskSlice:getTileFromRasterTaskSlice,isSliceDoingRasterization:isSliceDoingRasterization,isSliceDoingAnalysis:isSliceDoingAnalysis};});'use strict';Polymer('tr-ui-e-chrome-cc-raster-task-view',{created:function(){this.selection_=undefined;},set selection(selection){this.selection_=selection;this.updateContents_();},updateColumns_:function(hadCpuDurations){var timeSpanConfig={ownerDocument:this.ownerDocument};var columns=[{title:'Layer',value:function(row){if(row.isTotals)
+return'Totals';if(row.layer){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.ui.e.chrome.cc.LayerSelection(costs.layer);},'Layer '+row.layerId);return linkEl;}else{return'Layer '+row.layerId;}},width:'250px'},{title:'Num Tiles',value:function(row){return row.numTiles;},cmp:function(a,b){return a.numTiles-b.numTiles;}},{title:'Num Analysis Tasks',value:function(row){return row.numAnalysisTasks;},cmp:function(a,b){return a.numAnalysisTasks-b.numAnalysisTasks;}},{title:'Num Raster Tasks',value:function(row){return row.numRasterTasks;},cmp:function(a,b){return a.numRasterTasks-b.numRasterTasks;}},{title:'Wall Duration (ms)',value:function(row){return tr.ui.units.createTimeDurationSpan(row.duration,timeSpanConfig);},cmp:function(a,b){return a.duration-b.duration;}}];if(hadCpuDurations){columns.push({title:'CPU Duration (ms)',value:function(row){return tr.ui.units.createTimeDurationSpan(row.duration,timeSpanConfig);},cmp:function(a,b){return a.cpuDuration-b.cpuDuration;}});}
+var colWidthPercentage;if(columns.length==1)
+colWidthPercentage='100%';else
+colWidthPercentage=(100/(columns.length-1)).toFixed(3)+'%';for(var i=1;i<columns.length;i++)
+columns[i].width=colWidthPercentage;this.$.content.tableColumns=columns;this.$.content.sortColumnIndex=columns.length-1;},updateContents_:function(){var table=this.$.content;if(this.selection_.length===0){this.$.link.setSelectionAndContent(undefined,'');table.tableRows=[];table.footerRows=[];table.rebuild();return;}
+var lthi=tr.e.cc.getTileFromRasterTaskSlice(this.selection_[0]).containingSnapshot;this.$.link.setSelectionAndContent(function(){return new tr.model.EventSet(lthi);},lthi.userFriendlyName);var costsByLayerId={};function getCurrentCostsForLayerId(tile){var layerId=tile.layerId;var lthi=tile.containingSnapshot;var layer;if(lthi.activeTree)
+layer=lthi.activeTree.findLayerWithId(layerId);if(layer===undefined&&lthi.pendingTree)
+layer=lthi.pendingTree.findLayerWithId(layerId);if(costsByLayerId[layerId]===undefined){costsByLayerId[layerId]={layerId:layerId,layer:layer,numTiles:0,numAnalysisTasks:0,numRasterTasks:0,duration:0,cpuDuration:0};}
+return costsByLayerId[layerId];}
+var totalDuration=0;var totalCpuDuration=0;var totalNumAnalyzeTasks=0;var totalNumRasterizeTasks=0;var hadCpuDurations=false;var tilesThatWeHaveSeen={};this.selection_.forEach(function(slice){var tile=tr.e.cc.getTileFromRasterTaskSlice(slice);var curCosts=getCurrentCostsForLayerId(tile);if(!tilesThatWeHaveSeen[tile.objectInstance.id]){tilesThatWeHaveSeen[tile.objectInstance.id]=true;curCosts.numTiles+=1;}
+if(tr.e.cc.isSliceDoingAnalysis(slice)){curCosts.numAnalysisTasks+=1;totalNumAnalyzeTasks+=1;}else{curCosts.numRasterTasks+=1;totalNumRasterizeTasks+=1;}
+curCosts.duration+=slice.duration;totalDuration+=slice.duration;if(slice.cpuDuration!==undefined){curCosts.cpuDuration+=slice.cpuDuration;totalCpuDuration+=slice.cpuDuration;hadCpuDurations=true;}});this.updateColumns_(hadCpuDurations);table.tableRows=tr.b.dictionaryValues(costsByLayerId);table.rebuild();table.footerRows=[{isTotals:true,numTiles:tr.b.dictionaryLength(tilesThatWeHaveSeen),numAnalysisTasks:totalNumAnalyzeTasks,numRasterTasks:totalNumRasterizeTasks,duration:totalDuration,cpuDuration:totalCpuDuration}];}});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){function RasterTaskSelection(selection){tr.ui.e.chrome.cc.Selection.call(this);var whySupported=RasterTaskSelection.whySuported(selection);if(!whySupported.ok)
+throw new Error('Fail: '+whySupported.why);this.slices_=tr.b.asArray(selection);this.tiles_=this.slices_.map(function(slice){var tile=tr.e.cc.getTileFromRasterTaskSlice(slice);if(tile===undefined)
+throw new Error('This should never happen due to .supports check.');return tile;});}
+RasterTaskSelection.whySuported=function(selection){if(!(selection instanceof tr.model.EventSet))
+return{ok:false,why:'Must be selection'};if(selection.length===0)
+return{ok:false,why:'Selection must be non empty'};var tile0;for(var i=0;i<selection.length;i++){var event=selection[i];if(!(event instanceof tr.model.Slice))
+return{ok:false,why:'Not a slice'};var tile=tr.e.cc.getTileFromRasterTaskSlice(selection[i]);if(tile===undefined)
+return{ok:false,why:'No tile found'};if(i===0){tile0=tile;}else{if(tile.containingSnapshot!=tile0.containingSnapshot){return{ok:false,why:'Raster tasks are from different compositor instances'};}}}
+return{ok:true};}
+RasterTaskSelection.supports=function(selection){return RasterTaskSelection.whySuported(selection).ok;};RasterTaskSelection.prototype={__proto__:tr.ui.e.chrome.cc.Selection.prototype,get specicifity(){return 3;},get associatedLayerId(){var tile0=this.tiles_[0];var allSameLayer=this.tiles_.every(function(tile){tile.layerId==tile0.layerId;});if(allSameLayer)
+return tile0.layerId;return undefined;},get extraHighlightsByLayerId(){var highlights={};this.tiles_.forEach(function(tile,i){if(highlights[tile.layerId]===undefined)
+highlights[tile.layerId]=[];var slice=this.slices_[i];highlights[tile.layerId].push({colorKey:slice.title,rect:tile.layerRect});},this);return highlights;},createAnalysis:function(){var sel=new tr.model.EventSet();this.slices_.forEach(function(slice){sel.push(slice);});var analysis;if(sel.length==1)
+analysis=document.createElement('tr-ui-a-single-event-sub-view');else
+analysis=document.createElement('tr-ui-e-chrome-cc-raster-task-view');analysis.selection=sel;return analysis;},findEquivalent:function(lthi){return undefined;},get containingSnapshot(){return this.tiles_[0].containingSnapshot;}};return{RasterTaskSelection:RasterTaskSelection};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var TileSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-tile-snapshot-view',tr.ui.analysis.ObjectSnapshotView);TileSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-chrome-cc-tile-snapshot-view');this.layerTreeView_=new tr.ui.e.chrome.cc.LayerTreeHostImplSnapshotView();this.appendChild(this.layerTreeView_);},updateContents:function(){var tile=this.objectSnapshot_;var layerTreeHostImpl=tile.containingSnapshot;if(!layerTreeHostImpl)
+return;this.layerTreeView_.objectSnapshot=layerTreeHostImpl;this.layerTreeView_.selection=new tr.ui.e.chrome.cc.TileSelection(tile);}};tr.ui.analysis.ObjectSnapshotView.register(TileSnapshotView,{typeName:'cc::Tile',showInTrackView:false});return{TileSnapshotView:TileSnapshotView};});'use strict';tr.exportTo('tr.e.gpu',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function StateSnapshot(){ObjectSnapshot.apply(this,arguments);}
+StateSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){this.screenshot_=undefined;},initialize:function(){if(this.args.screenshot)
+this.screenshot_=this.args.screenshot;},get screenshot(){return this.screenshot_;}};ObjectSnapshot.register(StateSnapshot,{typeName:'gpu::State'});return{StateSnapshot:StateSnapshot};});'use strict';tr.exportTo('tr.e.gpu',function(){var AsyncSlice=tr.model.AsyncSlice;function GpuAsyncSlice(){AsyncSlice.apply(this,arguments);}
+GpuAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get viewSubGroupTitle(){if(this.args.channel){if(this.category=='disabled-by-default-gpu.device')
+return'Device.'+this.args.channel;else
+return'Service.'+this.args.channel;}
+return this.title;}};AsyncSlice.register(GpuAsyncSlice,{categoryParts:['disabled-by-default-gpu.device','disabled-by-default-gpu.service']});return{GpuAsyncSlice:GpuAsyncSlice};});'use strict';tr.exportTo('tr.ui.e.chrome.gpu',function(){var StateSnapshotView=tr.ui.b.define('tr-ui-e-chrome-gpu-state-snapshot-view',tr.ui.analysis.ObjectSnapshotView);StateSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-chrome-gpu-state-snapshot-view');this.screenshotImage_=document.createElement('img');this.appendChild(this.screenshotImage_);},updateContents:function(){if(this.objectSnapshot_&&this.objectSnapshot_.screenshot){this.screenshotImage_.src='data:image/png;base64,'+
+this.objectSnapshot_.screenshot;}}};tr.ui.analysis.ObjectSnapshotView.register(StateSnapshotView,{typeName:'gpu::State'});return{StateSnapshotView:StateSnapshotView};});'use strict';tr.exportTo('tr.e.system_stats',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function SystemStatsSnapshot(objectInstance,ts,args){ObjectSnapshot.apply(this,arguments);this.objectInstance=objectInstance;this.ts=ts;this.args=args;this.stats=args;}
+SystemStatsSnapshot.prototype={__proto__:ObjectSnapshot.prototype,initialize:function(){if(this.args.length==0)
+throw new Error('No system stats snapshot data.');this.stats_=this.args;},getStats:function(){return this.stats_;},setStats:function(stats){this.stats_=stats;}};ObjectSnapshot.register(SystemStatsSnapshot,{typeName:'base::TraceEventSystemStatsMonitor::SystemStats'});return{SystemStatsSnapshot:SystemStatsSnapshot};});'use strict';tr.exportTo('tr.ui.e.system_stats',function(){var SystemStatsSnapshotView=tr.ui.b.define('tr-ui-e-system-stats-snapshot-view',tr.ui.analysis.ObjectSnapshotView);SystemStatsSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-system-stats-snapshot-view');},updateContents:function(){var snapshot=this.objectSnapshot_;if(!snapshot||!snapshot.getStats()){this.textContent='No system stats snapshot found.';return;}
+this.textContent='';var stats=snapshot.getStats();this.appendChild(this.buildList_(stats));},isFloat:function(n){return typeof n==='number'&&n%1!==0;},buildList_:function(stats){var statList=document.createElement('ul');for(var statName in stats){var statText=document.createElement('li');statText.textContent=''+statName+': ';statList.appendChild(statText);if(stats[statName]instanceof Object){statList.appendChild(this.buildList_(stats[statName]));}else{if(this.isFloat(stats[statName]))
+statText.textContent+=stats[statName].toFixed(2);else
+statText.textContent+=stats[statName];}}
+return statList;}};tr.ui.analysis.ObjectSnapshotView.register(SystemStatsSnapshotView,{typeName:'base::TraceEventSystemStatsMonitor::SystemStats'});return{SystemStatsSnapshotView:SystemStatsSnapshotView};});'use strict';tr.exportTo('tr.ui.tracks',function(){var StackedBarsTrack=tr.ui.b.define('stacked-bars-track',tr.ui.tracks.Track);StackedBarsTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('stacked-bars-track');this.objectInstance_=null;this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},addEventsToTrackMap:function(eventToTrackMap){var objectSnapshots=this.objectInstance_.snapshots;objectSnapshots.forEach(function(obj){eventToTrackMap.addEvent(obj,this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){function onSnapshot(snapshot){selection.push(snapshot);}
+var snapshots=this.objectInstance_.snapshots;var maxBounds=this.objectInstance_.parent.model.bounds.max;tr.b.iterateOverIntersectingIntervals(snapshots,function(x){return x.ts;},function(x,i){if(i==snapshots.length-1){if(snapshots.length==1)
+return maxBounds;return snapshots[i].ts-snapshots[i-1].ts;}
+return snapshots[i+1].ts-snapshots[i].ts;},loWX,hiWX,onSnapshot);},addEventNearToProvidedEventToSelection:function(event,offset,selection){if(!(event instanceof tr.model.ObjectSnapshot))
+throw new Error('Unrecognized event');var objectSnapshots=this.objectInstance_.snapshots;var index=objectSnapshots.indexOf(event);var newIndex=index+offset;if(newIndex>=0&&newIndex<objectSnapshots.length){selection.push(objectSnapshots[newIndex]);return true;}
+return false;},addAllEventsMatchingFilterToSelection:function(filter,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){var snapshot=tr.b.findClosestElementInSortedArray(this.objectInstance_.snapshots,function(x){return x.ts;},worldX,worldMaxDist);if(!snapshot)
+return;selection.push(snapshot);}};return{StackedBarsTrack:StackedBarsTrack};});'use strict';tr.exportTo('tr.ui.e.system_stats',function(){var EventPresenter=tr.ui.b.EventPresenter;var statCount;var excludedStats={'meminfo':{'pswpin':0,'pswpout':0,'pgmajfault':0},'diskinfo':{'io':0,'io_time':0,'read_time':0,'reads':0,'reads_merged':0,'sectors_read':0,'sectors_written':0,'weighted_io_time':0,'write_time':0,'writes':0,'writes_merged':0},'swapinfo':{}};var SystemStatsInstanceTrack=tr.ui.b.define('tr-ui-e-system-stats-instance-track',tr.ui.tracks.StackedBarsTrack);SystemStatsInstanceTrack.prototype={__proto__:tr.ui.tracks.StackedBarsTrack.prototype,decorate:function(viewport){tr.ui.tracks.StackedBarsTrack.prototype.decorate.call(this,viewport);this.classList.add('tr-ui-e-system-stats-instance-track');this.objectInstance_=null;},set objectInstances(objectInstances){if(!objectInstances){this.objectInstance_=[];return;}
+if(objectInstances.length!=1)
+throw new Error('Bad object instance count.');this.objectInstance_=objectInstances[0];if(this.objectInstance_!==null){this.computeRates_(this.objectInstance_.snapshots);this.maxStats_=this.computeMaxStats_(this.objectInstance_.snapshots);}},computeRates_:function(snapshots){for(var i=0;i<snapshots.length;i++){var snapshot=snapshots[i];var stats=snapshot.getStats();var prevSnapshot;var prevStats;if(i==0){prevSnapshot=snapshots[0];}else{prevSnapshot=snapshots[i-1];}
+prevStats=prevSnapshot.getStats();var timeIntervalSeconds=(snapshot.ts-prevSnapshot.ts)/1000;if(timeIntervalSeconds==0)
+timeIntervalSeconds=1;this.computeRatesRecursive_(prevStats,stats,timeIntervalSeconds);}},computeRatesRecursive_:function(prevStats,stats,timeIntervalSeconds){for(var statName in stats){if(stats[statName]instanceof Object){this.computeRatesRecursive_(prevStats[statName],stats[statName],timeIntervalSeconds);}else{if(statName=='sectors_read'){stats['bytes_read_per_sec']=(stats['sectors_read']-
+prevStats['sectors_read'])*512/timeIntervalSeconds;}
+if(statName=='sectors_written'){stats['bytes_written_per_sec']=(stats['sectors_written']-
+prevStats['sectors_written'])*512/timeIntervalSeconds;}
+if(statName=='pgmajfault'){stats['pgmajfault_per_sec']=(stats['pgmajfault']-
+prevStats['pgmajfault'])/timeIntervalSeconds;}
+if(statName=='pswpin'){stats['bytes_swpin_per_sec']=(stats['pswpin']-
+prevStats['pswpin'])*1000/timeIntervalSeconds;}
+if(statName=='pswpout'){stats['bytes_swpout_per_sec']=(stats['pswpout']-
+prevStats['pswpout'])*1000/timeIntervalSeconds;}}}},computeMaxStats_:function(snapshots){var maxStats=new Object();statCount=0;for(var i=0;i<snapshots.length;i++){var snapshot=snapshots[i];var stats=snapshot.getStats();this.computeMaxStatsRecursive_(stats,maxStats,excludedStats);}
+return maxStats;},computeMaxStatsRecursive_:function(stats,maxStats,excludedStats){for(var statName in stats){if(stats[statName]instanceof Object){if(!(statName in maxStats))
+maxStats[statName]=new Object();var excludedNested;if(excludedStats&&statName in excludedStats)
+excludedNested=excludedStats[statName];else
+excludedNested=null;this.computeMaxStatsRecursive_(stats[statName],maxStats[statName],excludedNested);}else{if(excludedStats&&statName in excludedStats)
+continue;if(!(statName in maxStats)){maxStats[statName]=0;statCount++;}
+if(stats[statName]>maxStats[statName])
+maxStats[statName]=stats[statName];}}},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawStatBars_(viewLWorld,viewRWorld);break;}},drawStatBars_:function(viewLWorld,viewRWorld){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var width=bounds.width*pixelRatio;var height=(bounds.height*pixelRatio)/statCount;var vp=this.viewport.currentDisplayTransform;var maxStats=this.maxStats_;var objectSnapshots=this.objectInstance_.snapshots;var lowIndex=tr.b.findLowIndexInSortedArray(objectSnapshots,function(snapshot){return snapshot.ts;},viewLWorld);if(lowIndex>0)
+lowIndex-=1;for(var i=lowIndex;i<objectSnapshots.length;++i){var snapshot=objectSnapshots[i];var trace=snapshot.getStats();var currentY=height;var left=snapshot.ts;if(left>viewRWorld)
+break;var leftView=vp.xWorldToView(left);if(leftView<0)
+leftView=0;var right;if(i!=objectSnapshots.length-1){right=objectSnapshots[i+1].ts;}else{if(objectSnapshots.length>1)
+right=objectSnapshots[i].ts+(objectSnapshots[i].ts-
+objectSnapshots[i-1].ts);else
+right=this.objectInstance_.parent.model.bounds.max;}
+var rightView=vp.xWorldToView(right);if(rightView>width)
+rightView=width;leftView=Math.floor(leftView);rightView=Math.floor(rightView);this.drawStatBarsRecursive_(snapshot,leftView,rightView,height,trace,maxStats,currentY);if(i==lowIndex)
+this.drawStatNames_(leftView,height,currentY,'',maxStats);}
+ctx.lineWidth=1;},drawStatBarsRecursive_:function(snapshot,leftView,rightView,height,stats,maxStats,currentY){var ctx=this.context();for(var statName in maxStats){if(stats[statName]instanceof Object){currentY=this.drawStatBarsRecursive_(snapshot,leftView,rightView,height,stats[statName],maxStats[statName],currentY);}else{var maxStat=maxStats[statName];ctx.fillStyle=EventPresenter.getBarSnapshotColor(snapshot,Math.round(currentY/height));var barHeight;if(maxStat>0){barHeight=height*Math.max(stats[statName],0)/maxStat;}else{barHeight=0;}
+ctx.fillRect(leftView,currentY-barHeight,Math.max(rightView-leftView,1),barHeight);currentY+=height;}}
+return currentY;},drawStatNames_:function(leftView,height,currentY,prefix,maxStats){var ctx=this.context();ctx.textAlign='end';ctx.font='12px Arial';ctx.fillStyle='#000000';for(var statName in maxStats){if(maxStats[statName]instanceof Object){currentY=this.drawStatNames_(leftView,height,currentY,statName,maxStats[statName]);}else{var fullname=statName;if(prefix!='')
+fullname=prefix+' :: '+statName;ctx.fillText(fullname,leftView-10,currentY-height/4);currentY+=height;}}
+return currentY;}};tr.ui.tracks.ObjectInstanceTrack.register(SystemStatsInstanceTrack,{typeName:'base::TraceEventSystemStatsMonitor::SystemStats'});return{SystemStatsInstanceTrack:SystemStatsInstanceTrack};});'use strict';tr.exportTo('tr.e.tcmalloc',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function HeapSnapshot(){ObjectSnapshot.apply(this,arguments);}
+HeapSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);},initialize:function(){if(this.args.length==0)
+throw new Error('No heap snapshot data.');this.total_=this.args[0];var allocs=this.args.slice(1);this.heap_={children:{},currentBytes:0,currentAllocs:0,totalBytes:0,totalAllocs:0};for(var i=0;i<allocs.length;i++){var alloc=allocs[i];var traceNames=alloc.trace.split(' ');if(traceNames.indexOf('trace-memory-ignore')!=-1)
+continue;var heapEntry=this.heap_;for(var j=0;j<traceNames.length;j++){var traceName=traceNames[j];if(traceName.length!=0){heapEntry.currentBytes+=alloc.currentBytes;heapEntry.currentAllocs+=alloc.currentAllocs;heapEntry.totalBytes+=alloc.totalBytes;heapEntry.totalAllocs+=alloc.totalAllocs;}
+if(!heapEntry.children[traceName]){heapEntry.children[traceName]={children:{},currentBytes:alloc.currentBytes,currentAllocs:alloc.currentAllocs,totalBytes:alloc.totalBytes,totalAllocs:alloc.totalAllocs};}
+heapEntry=heapEntry.children[traceName];}}}};ObjectSnapshot.register(HeapSnapshot,{typeName:'memory::Heap'});return{HeapSnapshot:HeapSnapshot};});'use strict';tr.exportTo('tr.ui.e.tcmalloc',function(){var TcmallocInstanceView=tr.ui.b.define('tr-ui-e-tcmalloc-instance-view',tr.ui.analysis.ObjectInstanceView);TcmallocInstanceView.prototype={__proto__:tr.ui.analysis.ObjectInstanceView.prototype,decorate:function(){tr.ui.analysis.ObjectInstanceView.prototype.decorate.apply(this);this.classList.add('tr-ui-e-tcmalloc-instance-view');},updateContents:function(){var instance=this.objectInstance_;if(!instance||!instance.snapshots||instance.snapshots.length==0){this.textContent='No data found.';return;}
+this.textContent='';var snapshot=instance.snapshots[0];var heapEntry=snapshot.heap_;var traceNames=Object.keys(heapEntry.children);traceNames.sort(function(a,b){return heapEntry.children[b].currentBytes-
+heapEntry.children[a].currentBytes;});traceNames=traceNames.slice(0,5);var table=document.createElement('table');var titles=['Total'];titles=titles.concat(traceNames);table.appendChild(this.buildRow_(null,titles));var chartArrays=[[],[],[],[],[]];for(var i=0;i<instance.snapshots.length;i++){var snapshot=instance.snapshots[i];var rowData=[snapshot.total_.currentBytes];for(var j=0;j<5;j++){var bytes=snapshot.heap_.children[traceNames[j]].currentBytes;rowData.push(bytes);chartArrays[j].push([Math.round(snapshot.ts/1000),bytes/1024/1024]);}
+var row=this.buildRow_(snapshot,rowData);table.appendChild(row);}
+this.appendChild(table);},buildRow_:function(snapshot,items){var row=document.createElement('tr');var td=document.createElement('td');if(snapshot){var snapshotLink=document.createElement('tr-ui-a-analysis-link');snapshotLink.selection=new tr.model.EventSet(snapshot);td.appendChild(snapshotLink);}
+row.appendChild(td);for(var i=0;i<items.length;i++){var data=document.createElement('td');data.textContent=items[i];row.appendChild(data);}
+return row;},getByteString_:function(bytes){var mb=bytes/1024/1024;return mb.toFixed(1)+' MB';}};tr.ui.analysis.ObjectInstanceView.register(TcmallocInstanceView,{typeName:'memory::Heap'});return{TcmallocInstanceView:TcmallocInstanceView};});'use strict';tr.exportTo('tr.ui.e.tcmalloc',function(){var TcmallocSnapshotView=tr.ui.b.define('tr-ui-e-tcmalloc-heap-snapshot-view',tr.ui.analysis.ObjectSnapshotView);TcmallocSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-tcmalloc-heap-snapshot-view');},updateContents:function(){var snapshot=this.objectSnapshot_;if(!snapshot||!snapshot.heap_){this.textContent='No heap found.';return;}
+this.textContent='';var subhead=document.createElement('div');subhead.textContent='Retaining '+
+this.getByteString_(snapshot.total_.currentBytes)+' in '+
+snapshot.total_.currentAllocs+' allocations. Showing > 0.1 MB.';subhead.className='subhead';this.appendChild(subhead);var myList=this.buildAllocList_(snapshot.heap_,false);this.appendChild(myList);},buildAllocList_:function(heapEntry,hide){var myList=document.createElement('ul');myList.hidden=hide;var keys=Object.keys(heapEntry.children);keys.sort(function(a,b){return heapEntry.children[b].currentBytes-
+heapEntry.children[a].currentBytes;});for(var i=0;i<keys.length;i++){var traceName=keys[i];var trace=heapEntry.children[traceName];if(trace.currentBytes<100*1024)
+continue;var childCount=Object.keys(trace.children).length;var isLeaf=childCount==0;var myItem=this.buildItem_(traceName,isLeaf,trace.currentBytes,trace.currentAllocs);myList.appendChild(myItem);if(childCount>0)
+myItem.appendChild(this.buildAllocList_(trace,true));}
+return myList;},buildItem_:function(traceName,isLeaf,bytes,allocs){var myItem=document.createElement('li');myItem.className='trace-item';myItem.id=traceName;var byteDiv=document.createElement('div');byteDiv.textContent=this.getByteString_(bytes);byteDiv.className='trace-bytes';myItem.appendChild(byteDiv);if(traceName.length==0){traceName='(here)';}else if(traceName.indexOf('..')==0){var lastSlash=traceName.lastIndexOf('/');if(lastSlash!=-1)
+traceName='Task from '+traceName.substr(lastSlash+1);}
+var traceDiv=document.createElement('div');traceDiv.textContent=traceName;traceDiv.className='trace-name';myItem.appendChild(traceDiv);if(isLeaf)
+return myItem;var self=this;myItem.addEventListener('click',function(event){if(this==event.target||this==event.target.parentElement){this.classList.toggle('expanded');var child=this.querySelector('ul');child.hidden=!child.hidden;self.onItemClicked_(this);}});myItem.classList.add('collapsed');return myItem;},onItemClicked_:function(traceItem){var traces=[];while(traceItem.classList.contains('trace-item')){var traceNameDiv=traceItem.firstElementChild.nextElementSibling;traces.unshift(traceNameDiv.textContent);var traceNameUl=traceItem.parentElement;traceItem=traceNameUl.parentElement;}
+var instance=this.objectSnapshot_.objectInstance;instance.selectedTraces=traces;var trackView=document.querySelector('.timeline-track-view');trackView.viewport_.dispatchChangeEvent();},getByteString_:function(bytes){var mb=bytes/1024/1024;return mb.toFixed(1)+' MB';}};tr.ui.analysis.ObjectSnapshotView.register(TcmallocSnapshotView,{typeName:'memory::Heap'});return{TcmallocSnapshotView:TcmallocSnapshotView};});'use strict';tr.exportTo('tr.ui.e.tcmalloc',function(){var EventPresenter=tr.ui.b.EventPresenter;var HeapInstanceTrack=tr.ui.b.define('tr-ui-e-tcmalloc-heap-instance-track',tr.ui.tracks.StackedBarsTrack);HeapInstanceTrack.prototype={__proto__:tr.ui.tracks.StackedBarsTrack.prototype,decorate:function(viewport){tr.ui.tracks.StackedBarsTrack.prototype.decorate.call(this,viewport);this.classList.add('tr-ui-e-tcmalloc-heap-instance-track');this.objectInstance_=null;},set objectInstances(objectInstances){if(!objectInstances){this.objectInstance_=[];return;}
+if(objectInstances.length!=1)
+throw new Error('Bad object instance count.');this.objectInstance_=objectInstances[0];this.maxBytes_=this.computeMaxBytes_(this.objectInstance_.snapshots);},computeMaxBytes_:function(snapshots){var maxBytes=0;for(var i=0;i<snapshots.length;i++){var snapshot=snapshots[i];var traceNames=Object.keys(snapshot.heap_.children);var sumBytes=0;for(var j=0;j<traceNames.length;j++){sumBytes+=snapshot.heap_.children[traceNames[j]].currentBytes;}
+if(sumBytes>maxBytes)
+maxBytes=sumBytes;}
+return maxBytes;},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawEvents_(viewLWorld,viewRWorld);break;}},drawEvents_:function(viewLWorld,viewRWorld){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var width=bounds.width*pixelRatio;var height=bounds.height*pixelRatio;var dt=this.viewport.currentDisplayTransform;var maxBytes=this.maxBytes_;var objectSnapshots=this.objectInstance_.snapshots;var lowIndex=tr.b.findLowIndexInSortedArray(objectSnapshots,function(snapshot){return snapshot.ts;},viewLWorld);if(lowIndex>0)
+lowIndex-=1;for(var i=lowIndex;i<objectSnapshots.length;++i){var snapshot=objectSnapshots[i];var left=snapshot.ts;if(left>viewRWorld)
+break;var leftView=dt.xWorldToView(left);if(leftView<0)
+leftView=0;var right;if(i!=objectSnapshots.length-1){right=objectSnapshots[i+1].ts;}else{if(objectSnapshots.length>1)
+right=objectSnapshots[i].ts+(objectSnapshots[i].ts-
+objectSnapshots[i-1].ts);else
+right=this.objectInstance_.parent.model.bounds.max;}
+var rightView=dt.xWorldToView(right);if(rightView>width)
+rightView=width;leftView=Math.floor(leftView);rightView=Math.floor(rightView);var currentY=height;var keys=Object.keys(snapshot.heap_.children);for(var k=keys.length-1;k>=0;k--){var trace=snapshot.heap_.children[keys[k]];if(this.objectInstance_.selectedTraces&&this.objectInstance_.selectedTraces.length>0&&this.objectInstance_.selectedTraces[0]==keys[k]){ctx.fillStyle='rgb(239, 248, 206)';}else
+ctx.fillStyle=EventPresenter.getBarSnapshotColor(snapshot,k);var barHeight=height*trace.currentBytes/maxBytes;ctx.fillRect(leftView,currentY-barHeight,Math.max(rightView-leftView,1),barHeight);currentY-=barHeight;}}
+ctx.lineWidth=1;}};tr.ui.tracks.ObjectInstanceTrack.register(HeapInstanceTrack,{typeName:'memory::Heap'});return{HeapInstanceTrack:HeapInstanceTrack};});'use strict';Polymer('tr-ui-e-s-category-summary-side-panel',{ready:function(){},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();},get listeningToKeys(){return false;},set selection(selection){},set rangeOfInterest(rangeOfInterest){},updateContents_:function(){this.$.table.tableColumns=[{title:'Category / Title',value:function(row){return row.title;}},{title:'Events',textAlign:'right',value:function(row){return row.count;}}];if(this.model_===undefined){this.$.table.tableRows=[];return;}
+var categories={};this.model_.iterateAllEvents(function handleEvent(event){if(!(event instanceof tr.model.Slice)&&!(event instanceof tr.model.AsyncSlice)&&!(event instanceof tr.model.InstantEvent)&&!(event instanceof tr.model.FlowEvent))
+return;tr.b.getCategoryParts(event.category).forEach(function(category){if(categories[category]===undefined){categories[category]={};}
+var titleCounts=categories[category];if(titleCounts[event.title]===undefined){titleCounts[event.title]=0;}
+titleCounts[event.title]+=1;});});function compareCounts(a,b){return b.count-a.count;}
+var rows=[];for(var category in categories){var categoryRow={title:category,subRows:[],count:0};rows.push(categoryRow);var titleCounts=categories[category];for(var title in titleCounts){var count=titleCounts[title];categoryRow.count+=count;categoryRow.subRows.push({title:title,count:count});}
+categoryRow.subRows.sort(compareCounts);}
+rows.sort(compareCounts);this.$.table.tableRows=rows;},supportsModel:function(m){if(m==undefined){return{supported:false,reason:'Unknown tracing model'};}
+return{supported:true};},get textLabel(){return'Categories';}});'use strict';Polymer('tr-ui-e-s-input-latency-side-panel',{ready:function(){this.rangeOfInterest_=new tr.b.Range();this.frametimeType_=tr.e.audits.IMPL_FRAMETIME_TYPE;this.latencyChart_=undefined;this.frametimeChart_=undefined;this.selectedProcessId_=undefined;this.mouseDownIndex_=undefined;this.curMouseIndex_=undefined;},get model(){return this.model_;},set model(model){this.model_=model;if(this.model_)
+this.modelHelper_=new tr.e.audits.ChromeModelHelper(model);else
+this.modelHelper_=undefined;this.updateToolbar_();this.updateContents_();},get frametimeType(){return this.frametimeType_;},set frametimeType(type){if(this.frametimeType_===type)
+return;this.frametimeType_=type;this.updateContents_();},get selectedProcessId(){return this.selectedProcessId_;},set selectedProcessId(process){if(this.selectedProcessId_===process)
+return;this.selectedProcessId_=process;this.updateContents_();},set selection(selection){if(this.latencyChart_===undefined)
+return;this.latencyChart_.brushedRange=selection.bounds;},setBrushedIndices:function(mouseDownIndex,curIndex){this.mouseDownIndex_=mouseDownIndex;this.curMouseIndex_=curIndex;this.updateBrushedRange_();},updateBrushedRange_:function(){if(this.latencyChart_===undefined)
+return;var r=new tr.b.Range();if(this.mouseDownIndex_===undefined){this.latencyChart_.brushedRange=r;return;}
+r=this.latencyChart_.computeBrushRangeFromIndices(this.mouseDownIndex_,this.curMouseIndex_);this.latencyChart_.brushedRange=r;var latencySlices=[];this.model_.getAllThreads().forEach(function(thread){thread.iterateAllEvents(function(event){if(event.title.indexOf('InputLatency:')===0)
+latencySlices.push(event);});});latencySlices=tr.e.audits.getSlicesIntersectingRange(r,latencySlices);var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(latencySlices);this.latencyChart_.dispatchEvent(event);},registerMouseEventForLatencyChart_:function(){this.latencyChart_.addEventListener('item-mousedown',function(e){this.mouseDownIndex_=e.index;this.curMouseIndex_=e.index;this.updateBrushedRange_();}.bind(this));this.latencyChart_.addEventListener('item-mousemove',function(e){if(e.button==undefined)
+return;this.curMouseIndex_=e.index;this.updateBrushedRange_();}.bind(this));this.latencyChart_.addEventListener('item-mouseup',function(e){this.curMouseIndex=e.index;this.updateBrushedRange_();}.bind(this));},updateToolbar_:function(){var browserProcess=this.modelHelper_.browserProcess;var labels=[];if(browserProcess!==undefined){var label_str='Browser: '+browserProcess.pid;labels.push({label:label_str,value:browserProcess.pid});}
+tr.b.iterItems(this.modelHelper_.rendererHelpers,function(pid,rendererHelper){var rendererProcess=rendererHelper.process;var label_str='Renderer: '+rendererProcess.userFriendlyName;labels.push({label:label_str,value:rendererProcess.userFriendlyName});},this);if(labels.length===0)
+return;this.selectedProcessId_=labels[0].value;var toolbarEl=this.$.toolbar;toolbarEl.appendChild(tr.ui.b.createSelector(this,'frametimeType','inputLatencySidePanel.frametimeType',this.frametimeType_,[{label:'Main Thread Frame Times',value:tr.e.audits.MAIN_FRAMETIME_TYPE},{label:'Impl Thread Frame Times',value:tr.e.audits.IMPL_FRAMETIME_TYPE}]));toolbarEl.appendChild(tr.ui.b.createSelector(this,'selectedProcessId','inputLatencySidePanel.selectedProcessId',this.selectedProcessId_,labels));},get currentRangeOfInterest(){if(this.rangeOfInterest_.isEmpty)
+return this.model_.bounds;else
+return this.rangeOfInterest_;},createLatencyLineChart:function(data,title){var chart=new tr.ui.b.LineChart();var width=600;if(document.body.clientWidth!=undefined)
+width=document.body.clientWidth*0.5;chart.setSize({width:width,height:chart.height});chart.chartTitle=title;chart.data=data;return chart;},updateContents_:function(){var resultArea=this.$.result_area;this.latencyChart_=undefined;this.frametimeChart_=undefined;resultArea.textContent='';if(this.modelHelper_===undefined)
+return;var rangeOfInterest=this.currentRangeOfInterest;var chromeProcess;if(this.modelHelper_.rendererHelpers[this.selectedProcessId_])
+chromeProcess=this.modelHelper_.rendererHelpers[this.selectedProcessId_];else
+chromeProcess=this.modelHelper_.browserHelper;var frameEvents=chromeProcess.getFrameEventsInRange(this.frametimeType,rangeOfInterest);var frametimeData=tr.e.audits.getFrametimeDataFromEvents(frameEvents);var averageFrametime=tr.b.Statistics.mean(frametimeData,function(d){return d.frametime;});var latencyEvents=this.modelHelper_.browserHelper.getLatencyEventsInRange(rangeOfInterest);var latencyData=[];latencyEvents.forEach(function(event){if(event.inputLatency===undefined)
+return;latencyData.push({x:event.start,latency:event.inputLatency/1000});});var averageLatency=tr.b.Statistics.mean(latencyData,function(d){return d.latency;});var latencySummaryText=document.createElement('div');latencySummaryText.appendChild(tr.ui.b.createSpan({textContent:'Average Latency '+averageLatency+' ms',bold:true}));resultArea.appendChild(latencySummaryText);var frametimeSummaryText=document.createElement('div');frametimeSummaryText.appendChild(tr.ui.b.createSpan({textContent:'Average Frame Time '+averageFrametime+' ms',bold:true}));resultArea.appendChild(frametimeSummaryText);if(latencyData.length!==0){this.latencyChart_=this.createLatencyLineChart(latencyData,'Latency Over Time');this.registerMouseEventForLatencyChart_();resultArea.appendChild(this.latencyChart_);}
+if(frametimeData.length!=0){this.frametimeChart_=this.createLatencyLineChart(frametimeData,'Frame Times');this.frametimeChart_.style.display='block';resultArea.appendChild(this.frametimeChart_);}},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(rangeOfInterest){this.rangeOfInterest_=rangeOfInterest;this.updateContents_();},supportsModel:function(m){if(m==undefined){return{supported:false,reason:'Unknown tracing model'};}
+if(!tr.e.audits.ChromeModelHelper.supportsModel(m)){return{supported:false,reason:'No Chrome browser or renderer process found'};}
+var modelHelper=new tr.e.audits.ChromeModelHelper(m);if(modelHelper.browserHelper&&modelHelper.browserHelper.hasLatencyEvents){return{supported:true};}
+return{supported:false,reason:'No InputLatency events trace. Consider enabling '+'benchmark" and "input" category when recording the trace'};},get textLabel(){return'Input Latency';}});'use strict';tr.exportTo('tr.ui.b',function(){var ChartBase=tr.ui.b.ChartBase;var getColorOfKey=tr.ui.b.getColorOfKey;var MIN_RADIUS=100;var PieChart=tr.ui.b.define('pie-chart',ChartBase);PieChart.prototype={__proto__:ChartBase.prototype,decorate:function(){ChartBase.prototype.decorate.call(this);this.classList.add('pie-chart');this.data_=undefined;this.seriesKeys_=undefined;var chartAreaSel=d3.select(this.chartAreaElement);var pieGroupSel=chartAreaSel.append('g').attr('class','pie-group');this.pieGroup_=pieGroupSel.node();this.pathsGroup_=pieGroupSel.append('g').attr('class','paths').node();this.labelsGroup_=pieGroupSel.append('g').attr('class','labels').node();this.linesGroup_=pieGroupSel.append('g').attr('class','lines').node();},get data(){return this.data_;},set data(data){if(data!==undefined){var seriesKeys=[];var seenSeriesKeys={};data.forEach(function(d){var k=d.label;if(seenSeriesKeys[k])
+throw new Error('Label '+k+' has been used already');seriesKeys.push(k);seenSeriesKeys[k]=true;},this);this.seriesKeys_=seriesKeys;}else{this.seriesKeys_=undefined;}
+this.data_=data;this.updateContents_();},get margin(){var margin={top:0,right:0,bottom:0,left:0};if(this.chartTitle_)
+margin.top+=40;return margin;},getMinSize:function(){this.updateContents_();var labelSel=d3.select(this.labelsGroup_).selectAll('.label');var maxLabelWidth=-Number.MAX_VALUE;var leftTextHeightSum=0;var rightTextHeightSum=0;labelSel.each(function(l){var r=this.getBoundingClientRect();maxLabelWidth=Math.max(maxLabelWidth,r.width+32);if(this.style.textAnchor=='end'){leftTextHeightSum+=r.height;}else{rightTextHeightSum+=r.height;}});var titleWidth=this.querySelector('#title').getBoundingClientRect().width;var margin=this.margin;var marginWidth=margin.left+margin.right;var marginHeight=margin.top+margin.bottom;return{width:Math.max(2*MIN_RADIUS+2*maxLabelWidth,titleWidth*1.1)+marginWidth,height:marginHeight+Math.max(2*MIN_RADIUS,leftTextHeightSum,rightTextHeightSum)*1.25};},getLegendKeys_:function(){return undefined;},updateScales_:function(width,height){if(this.data_===undefined)
+return;},updateContents_:function(){ChartBase.prototype.updateContents_.call(this);if(!this.data_)
+return;var width=this.chartAreaSize.width;var height=this.chartAreaSize.height;var radius=Math.max(MIN_RADIUS,Math.min(width,height*0.95)/2);d3.select(this.pieGroup_).attr('transform','translate('+width/2+','+height/2+')');var pieLayout=d3.layout.pie().value(function(d){return d.value;}).sort(null);var piePathsSel=d3.select(this.pathsGroup_).datum(this.data_).selectAll('path').data(pieLayout);function midAngle(d){return d.startAngle+(d.endAngle-d.startAngle)/2;}
+var pathsArc=d3.svg.arc().innerRadius(0).outerRadius(radius-30);var valueLabelArc=d3.svg.arc().innerRadius(radius-100).outerRadius(radius-30);var lineBeginArc=d3.svg.arc().innerRadius(radius-50).outerRadius(radius-50);var lineEndArc=d3.svg.arc().innerRadius(radius).outerRadius(radius);piePathsSel.enter().append('path').attr('class','arc').attr('fill',function(d,i){var origData=this.data_[i];var highlighted=(origData.label===this.currentHighlightedLegendKey);return getColorOfKey(origData.label,highlighted);}.bind(this)).attr('d',pathsArc).on('click',function(d,i){var origData=this.data_[i];var event=new tr.b.Event('item-click');event.data=origData;event.index=i;this.dispatchEvent(event);d3.event.stopPropagation();}.bind(this)).on('mouseenter',function(d,i){var origData=this.data_[i];this.pushTempHighlightedLegendKey(origData.label);}.bind(this)).on('mouseleave',function(d,i){var origData=this.data_[i];this.popTempHighlightedLegendKey(origData.label);}.bind(this));piePathsSel.enter().append('text').attr('class','arc-text').attr('transform',function(d){return'translate('+valueLabelArc.centroid(d)+')';}).attr('dy','.35em').style('text-anchor','middle').text(function(d,i){var origData=this.data_[i];if(origData.valueText===undefined)
+return'';if(d.endAngle-d.startAngle<0.4)
+return'';return origData.valueText;}.bind(this));piePathsSel.exit().remove();var labelSel=d3.select(this.labelsGroup_).selectAll('.label').data(pieLayout(this.data_));labelSel.enter().append('text').attr('class','label').attr('dy','.35em');labelSel.text(function(d){if(d.data.label.length>40)
+return d.data.label.substr(0,40)+'...';return d.data.label;});labelSel.attr('transform',function(d){var pos=lineEndArc.centroid(d);pos[0]=radius*(midAngle(d)<Math.PI?1:-1);return'translate('+pos+')';});labelSel.style('text-anchor',function(d){return midAngle(d)<Math.PI?'start':'end';});var lineSel=d3.select(this.linesGroup_).selectAll('.line').data(pieLayout(this.data_));lineSel.enter().append('polyline').attr('class','line').attr('dy','.35em');lineSel.attr('points',function(d){var pos=lineEndArc.centroid(d);pos[0]=radius*0.95*(midAngle(d)<Math.PI?1:-1);return[lineBeginArc.centroid(d),lineEndArc.centroid(d),pos];});},updateHighlight_:function(){ChartBase.prototype.updateHighlight_.call(this);var pathsGroupSel=d3.select(this.pathsGroup_);var that=this;pathsGroupSel.selectAll('.arc').each(function(d,i){var origData=that.data_[i];var highlighted=origData.label==that.currentHighlightedLegendKey;var color=getColorOfKey(origData.label,highlighted);this.style.fill=color;});}};return{PieChart:PieChart};});'use strict';(function(){var GROUP_BY_PROCESS_NAME='process';var GROUP_BY_THREAD_NAME='thread';var WALL_TIME_GROUPING_UNIT='Wall time';var CPU_TIME_GROUPING_UNIT='CPU time';function ResultsForGroup(model,name){this.model=model;this.name=name;this.topLevelSlices=[];this.allSlices=[];}
+ResultsForGroup.prototype={get wallTime(){var wallSum=tr.b.Statistics.sum(this.topLevelSlices,function(x){return x.duration;});return wallSum;},get cpuTime(){var cpuDuration=0;for(var i=0;i<this.topLevelSlices.length;i++){var x=this.topLevelSlices[i];if(x.cpuDuration===undefined){if(x.duration===undefined)
+continue;return 0;}
+cpuDuration+=x.cpuDuration;}
+return cpuDuration;},appendGroupContents:function(group){if(group.model!=this.model)
+throw new Error('Models must be the same');group.allSlices.forEach(function(slice){this.allSlices.push(slice);},this);group.topLevelSlices.forEach(function(slice){this.topLevelSlices.push(slice);},this);},appendThreadSlices:function(rangeOfInterest,thread){var tmp=this.getSlicesIntersectingRange(rangeOfInterest,thread.sliceGroup.slices);tmp.forEach(function(slice){this.allSlices.push(slice);},this);tmp=this.getSlicesIntersectingRange(rangeOfInterest,thread.sliceGroup.topLevelSlices);tmp.forEach(function(slice){this.topLevelSlices.push(slice);},this);},getSlicesIntersectingRange:function(rangeOfInterest,slices){var slicesInFilterRange=[];for(var i=0;i<slices.length;i++){var slice=slices[i];if(rangeOfInterest.intersectsExplicitRange(slice.start,slice.end))
+slicesInFilterRange.push(slice);}
+return slicesInFilterRange;}};Polymer('tr-ui-e-s-time-summary-side-panel',{ready:function(){this.rangeOfInterest_=new tr.b.Range();this.selection_=undefined;this.groupBy_=GROUP_BY_PROCESS_NAME;this.groupingUnit_=CPU_TIME_GROUPING_UNIT;this.showCpuIdleTime_=true;this.chart_=undefined;var toolbarEl=this.$.toolbar;this.groupBySelector_=tr.ui.b.createSelector(this,'groupBy','timeSummarySidePanel.groupBy',this.groupBy_,[{label:'Group by process',value:GROUP_BY_PROCESS_NAME},{label:'Group by thread',value:GROUP_BY_THREAD_NAME}]);toolbarEl.appendChild(this.groupBySelector_);this.groupingUnitSelector_=tr.ui.b.createSelector(this,'groupingUnit','timeSummarySidePanel.groupingUnit',this.groupingUnit_,[{label:'Wall time',value:WALL_TIME_GROUPING_UNIT},{label:'CPU time',value:CPU_TIME_GROUPING_UNIT}]);toolbarEl.appendChild(this.groupingUnitSelector_);this.showCpuIdleTimeCheckbox_=tr.ui.b.createCheckBox(this,'showCpuIdleTime','timeSummarySidePanel.showCpuIdleTime',this.showCpuIdleTime_,'Show CPU idle time');toolbarEl.appendChild(this.showCpuIdleTimeCheckbox_);this.updateShowCpuIdleTimeCheckboxVisibility_();},trimPieChartData:function(groups,otherGroup,getValue,opt_extraValue){groups=groups.filter(function(d){return getValue(d)!=0;});var sum=tr.b.Statistics.sum(groups,getValue);if(opt_extraValue!==undefined)
+sum+=opt_extraValue;function compareByValue(a,b){return getValue(a)-getValue(b);}
+groups.sort(compareByValue);var thresshold=0.1*sum;while(groups.length>1){var group=groups[0];if(getValue(group)>=thresshold)
+break;var v=getValue(group);if(v+getValue(otherGroup)>thresshold)
+break;groups.splice(0,1);otherGroup.appendGroupContents(group);}
+if(getValue(otherGroup)>0)
+groups.push(otherGroup);groups.sort(compareByValue);return groups;},generateResultsForGroup:function(model,name){return new ResultsForGroup(model,name);},createPieChartFromResultGroups:function(groups,title,getValue,opt_extraData){var chart=new tr.ui.b.PieChart();function pushDataForGroup(data,resultsForGroup,value){data.push({label:resultsForGroup.name,value:value,valueText:tr.b.u.TimeDuration.format(value),resultsForGroup:resultsForGroup});}
+chart.addEventListener('item-click',function(clickEvent){var resultsForGroup=clickEvent.data.resultsForGroup;if(resultsForGroup===undefined)
+return;var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(resultsForGroup.allSlices);event.selection.timeSummaryGroupName=resultsForGroup.name;chart.dispatchEvent(event);});var data=[];groups.forEach(function(resultsForGroup){var value=getValue(resultsForGroup);if(value===0)
+return;pushDataForGroup(data,resultsForGroup,value);});if(opt_extraData)
+data.push.apply(data,opt_extraData);chart.chartTitle=title;chart.data=data;return chart;},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();},get listeningToKeys(){return false;},get groupBy(){return groupBy_;},set groupBy(groupBy){this.groupBy_=groupBy;if(this.groupBySelector_)
+this.groupBySelector_.selectedValue=groupBy;this.updateContents_();},get groupingUnit(){return groupingUnit_;},set groupingUnit(groupingUnit){this.groupingUnit_=groupingUnit;if(this.groupingUnitSelector_)
+this.groupingUnitSelector_.selectedValue=groupingUnit;this.updateShowCpuIdleTimeCheckboxVisibility_();this.updateContents_();},get showCpuIdleTime(){return this.showCpuIdleTime_;},set showCpuIdleTime(showCpuIdleTime){this.showCpuIdleTime_=showCpuIdleTime;if(this.showCpuIdleTimeCheckbox_)
+this.showCpuIdleTimeCheckbox_.checked=showCpuIdleTime;this.updateContents_();},updateShowCpuIdleTimeCheckboxVisibility_:function(){if(!this.showCpuIdleTimeCheckbox_)
+return;var visible=this.groupingUnit_==CPU_TIME_GROUPING_UNIT;if(visible)
+this.showCpuIdleTimeCheckbox_.style.display='';else
+this.showCpuIdleTimeCheckbox_.style.display='none';},getGroupNameForThread_:function(thread){if(this.groupBy_==GROUP_BY_THREAD_NAME)
+return thread.name?thread.name:thread.userFriendlyName;if(this.groupBy_==GROUP_BY_PROCESS_NAME)
+return thread.parent.userFriendlyName;},updateContents_:function(){var resultArea=this.$.result_area;this.chart_=undefined;resultArea.textContent='';if(this.model_===undefined)
+return;var rangeOfInterest;if(this.rangeOfInterest_.isEmpty)
+rangeOfInterest=this.model_.bounds;else
+rangeOfInterest=this.rangeOfInterest_;var allGroup=this.generateResultsForGroup(this.model_,'all');var resultsByGroupName={};this.model_.getAllThreads().forEach(function(thread){var groupName=this.getGroupNameForThread_(thread);if(resultsByGroupName[groupName]===undefined){resultsByGroupName[groupName]=this.generateResultsForGroup(this.model_,groupName);}
+resultsByGroupName[groupName].appendThreadSlices(rangeOfInterest,thread);allGroup.appendThreadSlices(rangeOfInterest,thread);},this);var getValueFromGroup=function(group){if(this.groupingUnit_==WALL_TIME_GROUPING_UNIT)
+return group.wallTime;return group.cpuTime;}.bind(this);var summaryText=document.createElement('div');summaryText.appendChild(tr.ui.b.createSpan({textContent:'Total '+this.groupingUnit_+': ',bold:true}));summaryText.appendChild(tr.ui.units.createTimeDurationSpan(getValueFromGroup(allGroup),{ownerDocument:this.ownerDocument}));resultArea.appendChild(summaryText);var extraValue=0;var extraData=[];if(this.showCpuIdleTime_&&this.groupingUnit_===CPU_TIME_GROUPING_UNIT&&this.model.kernel.bestGuessAtCpuCount!==undefined){var maxCpuTime=rangeOfInterest.range*this.model.kernel.bestGuessAtCpuCount;var idleTime=Math.max(0,maxCpuTime-allGroup.cpuTime);extraData.push({label:'CPU Idle',value:idleTime,valueText:tr.b.u.TimeDuration.format(idleTime)});extraValue+=idleTime;}
+var otherGroup=this.generateResultsForGroup(this.model_,'Other');var groups=this.trimPieChartData(tr.b.dictionaryValues(resultsByGroupName),otherGroup,getValueFromGroup,extraValue);if(groups.length==0){resultArea.appendChild(tr.ui.b.createSpan({textContent:'No data'}));return undefined;}
+this.chart_=this.createPieChartFromResultGroups(groups,this.groupingUnit_+' breakdown by '+this.groupBy_,getValueFromGroup,extraData);resultArea.appendChild(this.chart_);this.chart_.addEventListener('click',function(){var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.c.EventSet([]);this.dispatchEvent(event);});this.chart_.setSize(this.chart_.getMinSize());},get selection(){return selection_;},set selection(selection){this.selection_=selection;if(this.chart_===undefined)
+return;if(selection.timeSummaryGroupName)
+this.chart_.highlightedLegendKey=selection.timeSummaryGroupName;else
+this.chart_.highlightedLegendKey=undefined;},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(rangeOfInterest){this.rangeOfInterest_=rangeOfInterest;this.updateContents_();},supportsModel:function(model){return{supported:false};},get textLabel(){return'Time Summary';}});}());'use strict';tr.exportTo('tr.e.rail',function(){function RAILScore(opt_irs){this.interactionRecords_=[];if(opt_irs)
+this.interactionRecords_.push.apply(this.interactionRecords_,opt_irs);};RAILScore.prototype={get interactionRecords(){return this.interactionRecords_;},get overallScore(){if(!this.interactionRecords.length)
+return undefined;var numerator=0;var denominator=0;this.interactionRecords.forEach(function(ir){var score=ir.railScore;var scale=ir.railScoreScale;if(scale===undefined)
+scale=3;var power=ir.railScorePower;if(power===undefined)
+power=0.3;var base=ir.railScoreBase;if(base===undefined)
+base=Math.exp(1);var weight=Math.pow(base,-scale*Math.pow(score,power));numerator+=score*weight;denominator+=weight;});return numerator/denominator;},asDict:function(){return{overallScore:this.overallScore};}};RAILScore.fromModel=function(model){var rirs=model.interactionRecords.filter(function(ir){return ir instanceof tr.e.rail.RAILInteractionRecord;});if(rirs.length===0)
+return undefined;return new RAILScore(rirs);};return{RAILScore:RAILScore};});'use strict';Polymer('tr-ui-e-rail-rail-score-span',{created:function(){this.railScore_=undefined;},ready:function(){this.updateContent_();},get railScore(){return this.railScore_;},set railScore(railScore){this.railScore_=railScore;this.updateContent_();},updateContent_:function(){if(this.railScore_===undefined){this.$.content.style.display='none';return;}
+this.$.content.style.display='';var overallScore=this.railScore_.overallScore;if(overallScore===undefined)
+return;this.$.score.textContent=overallScore.toLocaleString(undefined,{minimumFractionDigits:3});}});'use strict';(function(){function setCoverageLink(link,labelString,events,eventRatio,cpuMs,cpuRatio){link.setSelectionAndContent(events);labelString+=' '+events.length+' events';labelString+=' ('+parseInt(100*eventRatio)+'%)';if(cpuRatio!==undefined)
+labelString+=', ';link.appendChild(document.createTextNode(labelString));if(cpuRatio===undefined)
+return;var cpuMsSpan=document.createElement('tr-ui-u-time-duration-span');cpuMsSpan.style.display='inline';cpuMsSpan.duration=cpuMs;cpuMsSpan.contentTextDecoration='underline';link.appendChild(cpuMsSpan);var cpuString=' ('+parseInt(100*cpuRatio)+'%)';link.appendChild(document.createTextNode(cpuString));}
+Polymer('tr-ui-e-rail-rail-score-side-panel',{ready:function(){this.rangeOfInterest_=new tr.b.Range();this.model_=undefined;this.railScore_=undefined;this.selection_=new tr.model.EventSet();this.$.test.addEventListener('click',this.createTest_.bind(this));},createTest_:function(){var overlay=new tr.ui.b.Overlay();overlay.title='RAILIRFinder test';var textarea=document.createElement('textarea');textarea.textContent=tr.e.rail.createIRFinderTestCaseStringFromModel(this.model_);textarea.rows=textarea.textContent.split('\n').length;textarea.cols=80;overlay.appendChild(textarea);overlay.visible=true;textarea.select();textarea.focus();},get textLabel(){return'RAIL Info';},supportsModel:function(m){if(m===undefined){return{supported:false,reason:'Unknown tracing model'};}
+var railScore=tr.e.rail.RAILScore.fromModel(m);if(railScore===undefined){return{supported:false,reason:'RAIL interactions were not found on the model'};}
+return{supported:true};},get model(){return this.model_;},set model(model){this.model_=model;this.railScore_=tr.e.rail.RAILScore.fromModel(model);this.$.score.railScore=this.railScore_;var coverage=tr.model.getIRCoverageFromModel(model);if(coverage){var associatedEvents=tr.model.getAssociatedEvents(model.interactionRecords);setCoverageLink(this.shadowRoot.querySelector('#associated-events'),'Associated',associatedEvents,coverage.coveredEventsCountRatio,coverage.associatedEventsCpuTimeMs,coverage.coveredEventsCpuTimeRatio);setCoverageLink(this.shadowRoot.querySelector('#unassociated-events'),'Unassociated',tr.model.getUnassociatedEvents(model,associatedEvents),1.0-coverage.coveredEventsCountRatio,coverage.unassociatedEventsCpuTimeMs,1.0-coverage.coveredEventsCpuTimeRatio);}
+this.updateTable_();},get listeningToKeys(){return false;},set rangeOfInterest(rangeOfInterest){},updateTable_:function(){function toThreeDigitLocaleString(value){return value.toLocaleString(undefined,{minimumFractionDigits:3,maximumFractionDigits:3});}
+var columns=[{title:'Type',width:'150px',value:function(ir){var el=document.createElement('tr-ui-b-color-legend');var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(new tr.model.EventSet([ir]),ir.railTypeName);el.setLabelAndColorId(linkEl,ir.colorId);el.compoundEventSelectionState=ir.computeCompoundEvenSelectionState(this.selection_);return el;}.bind(this),cmp:function(a,b){return a.railTypeName.localeCompare(b.railTypeName);}},{title:'Efficiency',width:'33%',value:function(ir){return toThreeDigitLocaleString(ir.normalizedEfficiency);},textAlign:'right',cmp:function(a,b){return a.normalizedEfficiency-b.normalizedEfficiency;}},{title:'Comfort',width:'33%',value:function(ir){return toThreeDigitLocaleString(ir.normalizedUserComfort);},textAlign:'right',cmp:function(a,b){return a.normalizedUserComfort-b.normalizedUserComfort;}},{title:'Score',width:'33%',value:function(ir){var span=document.createElement('span');span.style.fontWeight='bold';span.textContent=toThreeDigitLocaleString(ir.railScore);return span;},textAlign:'right',cmp:function(a,b){return a.railScore-b.railScore;}}];this.$.table.tableColumns=columns;if(this.railScore_)
+this.$.table.tableRows=this.railScore_.interactionRecords;else
+this.$.table.tableRows=[];this.$.table.rebuild();},onTableSelectionChanged_:function(){var selectedIR=this.$.table.selectedTableRow;var event=new tr.c.RequestSelectionChangeEvent();event.selection=new tr.c.Selection([selectedIR]);this.dispatchEvent(event);},set selection(selection){if(selection===undefined)
+selection=new tr.model.EventSet();if(this.selection_.equals(selection))
+return;this.selection_=selection;this.updateTable_();}});})();'use strict';Polymer('tr-ui-e-s-alerts-side-panel',{ready:function(){this.rangeOfInterest_=new tr.b.Range();this.selection_=undefined;},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();},get listeningToKeys(){return false;},set selection(selection){},set rangeOfInterest(rangeOfInterest){},selectAlertsOfType:function(alertTypeString){var alertsOfType=this.model_.alerts.filter(function(alert){return alert.title===alertTypeString;});var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(alertsOfType);this.dispatchEvent(event);},alertsByType_:function(alerts){var alertsByType={};alerts.forEach(function(alert){if(!alertsByType[alert.title])
+alertsByType[alert.title]=[];alertsByType[alert.title].push(alert);});return alertsByType;},alertsTableRows_:function(alertsByType){return Object.keys(alertsByType).map(function(key){return{alertType:key,count:alertsByType[key].length};});},alertsTableColumns_:function(){return[{title:'Alert type',value:function(row){return row.alertType;},width:'180px'},{title:'Count',width:'100%',value:function(row){return row.count;}}];},createAlertsTable_:function(alerts){var alertsByType=this.alertsByType_(alerts);var table=document.createElement('tr-ui-b-table');table.tableColumns=this.alertsTableColumns_();table.tableRows=this.alertsTableRows_(alertsByType);table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;table.addEventListener('selection-changed',function(e){var row=table.selectedTableRow;if(row)
+this.selectAlertsOfType(row.alertType);}.bind(this));return table;},updateContents_:function(){this.$.result_area.textContent='';if(this.model_===undefined)
+return;var panel=this.createAlertsTable_(this.model_.alerts);this.$.result_area.appendChild(panel);},supportsModel:function(m){if(m==undefined){return{supported:false,reason:'Unknown tracing model'};}else if(m.alerts.length===0){return{supported:false,reason:'No alerts in tracing model'};}
+return{supported:true};},get textLabel(){return'Alerts';}});'use strict';tr.exportTo('tr.ui.e.highlighter',function(){var Highlighter=tr.ui.tracks.Highlighter;function VSyncHighlighter(viewport){Highlighter.call(this,viewport);this.times_=[];}
+VSyncHighlighter.VSYNC_HIGHLIGHT_COLOR=new tr.b.Color(0,0,255);VSyncHighlighter.VSYNC_HIGHLIGHT_ALPHA=0.1;VSyncHighlighter.VSYNC_DENSITY_TRANSPARENT=0.20;VSyncHighlighter.VSYNC_DENSITY_OPAQUE=0.10;VSyncHighlighter.VSYNC_DENSITY_RANGE=VSyncHighlighter.VSYNC_DENSITY_TRANSPARENT-
+VSyncHighlighter.VSYNC_DENSITY_OPAQUE;VSyncHighlighter.generateStripes=function(times,minTime,maxTime){if(times.length===0)
+return[];var stripes=[];var lowIndex=tr.b.findLowIndexInSortedArray(times,function(time){return time;},minTime);var highIndex=lowIndex-1;while(times[highIndex+1]<=maxTime){highIndex++;}
+for(var i=lowIndex-(lowIndex%2);i<=highIndex;i+=2){var left=i<lowIndex?minTime:times[i];var right=i+1>highIndex?maxTime:times[i+1];stripes.push([left,right]);}
+return stripes;}
+VSyncHighlighter.prototype={__proto__:Highlighter.prototype,processModel:function(model){this.times_=model.device.vSyncTimestamps;},drawHighlight:function(ctx,dt,viewLWorld,viewRWorld,viewHeight){if(!this.viewport_.highlightVSync){return;}
+var stripes=VSyncHighlighter.generateStripes(this.times_,viewLWorld,viewRWorld);if(stripes.length==0){return;}
+var stripeRange=stripes[stripes.length-1][1]-stripes[0][0];var stripeDensity=stripes.length/(dt.scaleX*stripeRange);var clampedStripeDensity=tr.b.clamp(stripeDensity,VSyncHighlighter.VSYNC_DENSITY_OPAQUE,VSyncHighlighter.VSYNC_DENSITY_TRANSPARENT);var opacity=(VSyncHighlighter.VSYNC_DENSITY_TRANSPARENT-clampedStripeDensity)/VSyncHighlighter.VSYNC_DENSITY_RANGE;if(opacity==0){return;}
+var pixelRatio=window.devicePixelRatio||1;var height=viewHeight*pixelRatio;var c=VSyncHighlighter.VSYNC_HIGHLIGHT_COLOR;ctx.fillStyle=c.toStringWithAlphaOverride(VSyncHighlighter.VSYNC_HIGHLIGHT_ALPHA*opacity);for(var i=0;i<stripes.length;i++){var xLeftView=dt.xWorldToView(stripes[i][0]);var xRightView=dt.xWorldToView(stripes[i][1]);ctx.fillRect(xLeftView,0,xRightView-xLeftView,height);}}};tr.ui.tracks.Highlighter.register(VSyncHighlighter);return{VSyncHighlighter:VSyncHighlighter};});
+</script>
+</head>
+  <body>
+  </body>
+</html>
diff --git a/runtime/observatory/web/timeline.html b/runtime/observatory/web/timeline.html
new file mode 100644
index 0000000..ebcc46e
--- /dev/null
+++ b/runtime/observatory/web/timeline.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html style="height: 100%; width: 100%">
+<head>
+  <meta charset="utf-8">
+  <title>Dart VM Observatory Timeline</title>
+  <script src="timeline.js"></script>
+  <link rel="import" href="third_party/trace_viewer_full.html">
+  <style>
+html, body {
+  box-sizing: border-box;
+  overflow: hidden;
+  margin: 0px;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+}
+#trace-viewer {
+  width: 100%;
+  height: 100%;
+}
+#trace-viewer:focus {
+  outline: none;
+}
+  </style>
+</head>
+<body>
+</body>
+</html>
diff --git a/runtime/observatory/web/timeline.js b/runtime/observatory/web/timeline.js
new file mode 100644
index 0000000..155d010
--- /dev/null
+++ b/runtime/observatory/web/timeline.js
@@ -0,0 +1,93 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+function onModelLoaded() {
+  viewer.globalMode = true;
+  viewer.model = model;
+}
+
+function clearTimeline() {
+  viewer.model = undefined;
+}
+
+function onImportFail() {
+  var overlay = new tr.ui.b.Overlay();
+  overlay.textContent = tr.b.normalizeException(err).message;
+  overlay.title = 'Import error';
+  overlay.visible = true;
+  console.log('import failed');
+}
+
+function updateTimeline(events) {
+  model = new tr.Model();
+  var importer = new tr.importer.Import(model);
+  var p = importer.importTracesWithProgressDialog([events]);
+  p.then(onModelLoaded, onImportFail);
+}
+
+function registerForMessages() {
+  window.addEventListener("message", onMessage, false);
+}
+
+function fetchUri(uri, onLoad, onError) {
+  var xhr = new XMLHttpRequest();
+  xhr.open('GET', uri, true);
+  xhr.responseType = 'text';
+  xhr.addEventListener("load", onLoad);
+  xhr.addEventListener("error", onError);
+  xhr.send();
+  console.log('GET ' + uri);
+}
+
+function fetchTimelineOnLoad(event) {
+  var xhr = event.target;
+  var response = JSON.parse(xhr.responseText);
+  var result = response['result'];
+  var traceEvents = result['traceEvents'];
+  updateTimeline(traceEvents);
+}
+
+function fetchTimelineOnError(event) {
+}
+
+function fetchTimeline(vmAddress) {
+  var parser = document.createElement('a');
+  parser.href = vmAddress;
+  var requestUri = 'http://' +
+                   parser.hostname +
+                   ':' +
+                   parser.port +
+                   '/_getVMTimeline';
+  fetchUri(requestUri, fetchTimelineOnLoad, fetchTimelineOnError);
+}
+
+function onMessage(event) {
+  var request = JSON.parse(event.data);
+  var method = request['method'];
+  var params = request['params'];
+  switch (method) {
+    case 'refresh':
+      fetchTimeline(params['vmAddress']);
+    break;
+    case 'clear':
+      clearTimeline();
+    break;
+    default:
+      console.log('Unknown method:' + method + '.');
+  }
+}
+
+document.addEventListener('DOMContentLoaded', function() {
+  var container = document.createElement('track-view-container');
+  container.id = 'track_view_container';
+  viewer = document.createElement('tr-ui-timeline-view');
+  viewer.track_view_container = container;
+  viewer.appendChild(container);
+  viewer.id = 'trace-viewer';
+  viewer.globalMode = true;
+  document.body.appendChild(viewer);
+  registerForMessages();
+});
+
+console.log('loaded');
\ No newline at end of file
diff --git a/runtime/platform/globals.h b/runtime/platform/globals.h
index cd7b058..8d3a155 100644
--- a/runtime/platform/globals.h
+++ b/runtime/platform/globals.h
@@ -94,7 +94,7 @@
 // TODO(iposva): Rename TARGET_OS_MACOS to TARGET_OS_MAC to inherit
 // the value defined in TargetConditionals.h
 #define TARGET_OS_MACOS 1
-#if TARGET_OS_IPHONE && !defined(TARGET_OS_IOS)
+#if TARGET_OS_IPHONE
 #define TARGET_OS_IOS 1
 #endif
 
@@ -233,6 +233,18 @@
 #define DART_UNUSED
 #endif
 
+// DART_NORETURN indicates to the compiler that a function doees not return.
+// It should be used on functions that unconditionally call functions like
+// exit(), which end the program. We use it to avoid compiler warnings in
+// callers of DART_NORETURN functions.
+#ifdef _MSC_VER
+#define DART_NORETURN __declspec(noreturn)
+#elif __GNUC__
+#define DART_NORETURN __attribute__((noreturn))
+#else
+#error Automatic compiler detection failed.
+#endif
+
 #if !defined(TARGET_ARCH_MIPS)
 #if !defined(TARGET_ARCH_ARM)
 #if !defined(TARGET_ARCH_X64)
@@ -279,17 +291,17 @@
 #elif defined(TARGET_ARCH_X64)
   // No simulator used.
 #elif defined(TARGET_ARCH_ARM)
-#if !defined(HOST_ARCH_ARM) || TARGET_OS_IOS
+#if !defined(HOST_ARCH_ARM)
 #define USING_SIMULATOR 1
 #endif
 
 #elif defined(TARGET_ARCH_ARM64)
-#if !defined(HOST_ARCH_ARM64) || TARGET_OS_IOS
+#if !defined(HOST_ARCH_ARM64)
 #define USING_SIMULATOR 1
 #endif
 
 #elif defined(TARGET_ARCH_MIPS)
-#if !defined(HOST_ARCH_MIPS) || TARGET_OS_IOS
+#if !defined(HOST_ARCH_MIPS)
 #define USING_SIMULATOR 1
 #endif
 
diff --git a/runtime/tests/vm/dart/spawn_shutdown_test.dart b/runtime/tests/vm/dart/spawn_shutdown_test.dart
index 794e737..238c325 100644
--- a/runtime/tests/vm/dart/spawn_shutdown_test.dart
+++ b/runtime/tests/vm/dart/spawn_shutdown_test.dart
@@ -3,30 +3,47 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:async';
+import 'dart:io';
 import 'dart:isolate';
 
-// Spawn an isolate |foo| that will continue trying to spawn isolates even after
-// the timer in |main| completes. This test ensures that the VM can shutdown
-// correctly even while an isolate is attempting to spawn more isolates.
+// This test attempts to check that the vm can shutdown cleanly when
+// isolates are starting and stopping.
+//
+// We spawn a set of workers.  Each worker will kill its parent
+// worker (if any) and then spawn a child worker.  We start these
+// workers in a staggered fashion in an attempt to see a variety of
+// isolate states at the time that this program terminates.
 
-isolate1(sendPort) {
-  var receivePort = new ReceivePort();
-  sendPort.send(receivePort.sendPort);
-  receivePort.listen((msg) {});
-}
+void worker(SendPort parentPort) {
+  var port = new RawReceivePort();
 
-void foo(_) {
-  while (true) {
-    var receivePort = new ReceivePort();
-    Isolate.spawn(isolate1, receivePort.sendPort);
-    receivePort.listen((sendPort) {
-      Isolate.spawn(isolate1,sendPort);
-      receivePort.close();
-    });
+  // This worker will exit when it receives any message.
+  port.handler = (_) { port.close(); };
+
+  // Send a message to terminate our parent isolate.
+  if (parentPort != null) {
+    parentPort.send(null);
   }
+
+  // Spawn a child worker.
+  Isolate.spawn(worker, port.sendPort);
 }
 
 void main() {
-  Isolate.spawn(foo, null);
-  new Timer(const Duration(seconds: 10), () {});
+  const numWorkers = 50;
+  const delay = const Duration(milliseconds:(1000 ~/ numWorkers));
+  const exitDelay = const Duration(seconds: 2);
+
+  // Take about a second to spin up our workers in a staggered
+  // fashion. We want to maximize the chance that they will be in a
+  // variety of states when the vm shuts down.
+  print('Starting ${numWorkers} workers...');
+  for (int i = 0; i < numWorkers; i++) {
+    Isolate.spawn(worker, null);
+    sleep(delay);
+  }
+
+  // Let them spin for a bit before terminating the program.
+  print('Waiting for ${exitDelay} before exit...');
+  sleep(exitDelay);
 }
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 3c0182f..07373d4 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -3,7 +3,7 @@
 # BSD-style license that can be found in the LICENSE file.
 
 # These tests are expected to crash on all platforms.
-cc/ArrayNew_Overflow_Crash: Crash
+cc/ArrayNew_Overflow_Crash: Crash, Timeout
 cc/AllocGeneric_Overflow: Crash, Timeout
 cc/CodeImmutability: Crash
 
@@ -25,29 +25,11 @@
 [ $system == windows ]
 cc/Dart2JSCompileAll: Skip
 cc/ExternalizeConstantStrings: Skip
-cc/ThreadInterrupterHigh: Skip
-cc/ThreadInterrupterMedium: Skip
-cc/ThreadInterrupterLow: Skip
 cc/Service_Profile: Skip
 cc/Dart2JSCompilerStats: Skip
 cc/CorelibCompilerStats: Skip
-cc/ThreadIterator_AddFindRemove: Skip  # Issue 23474
-
-
-[ $system == linux ]
-cc/ThreadInterrupterHigh: Skip
-cc/ThreadInterrupterMedium: Skip
-cc/ThreadInterrupterLow: Skip
-
-[ $system == macos ]
-cc/ThreadInterrupterHigh: Skip
-cc/ThreadInterrupterMedium: Skip
-cc/ThreadInterrupterLow: Skip
 
 [ $arch == simarm || $arch == simarmv5te || $arch == simarm64 || $arch == simmips ]
-cc/ThreadInterrupterHigh: Skip
-cc/ThreadInterrupterMedium: Skip
-cc/ThreadInterrupterLow: Skip
 cc/Service_Profile: Skip
 
 [ $arch == arm ]
@@ -97,3 +79,8 @@
 
 [ $runtime == vm && $mode == debug && $builder_tag == asan ]
 cc/Dart2JSCompileAll: Skip  # Timeout.
+
+[ $noopt ]
+dart/redirection_type_shuffling_test: CompileTimeError # Imports dart:mirrors
+dart/byte_array_test: Crash # Incompatible flag --disable_alloc_stubs_after_gc
+dart/inline_stack_frame_test: Fail  # Issue 24783 - inlined frames missing
diff --git a/runtime/tools/create_archive.py b/runtime/tools/create_archive.py
new file mode 100644
index 0000000..0a3d756
--- /dev/null
+++ b/runtime/tools/create_archive.py
@@ -0,0 +1,151 @@
+# Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+#
+# This python script creates a tar archive and a C++ source file which contains
+# the tar archive as an array of bytes.
+
+import os
+import sys
+from os.path import join, splitext
+import time
+from optparse import OptionParser
+from datetime import date
+import tarfile
+import tempfile
+
+def makeArchive(tar_path, client_root, files):
+  tar = tarfile.open(tar_path, mode='w')
+  for input_file_name in files:
+    # Chop off client_root.
+    archive_file_name = input_file_name[ len(client_root) : ]
+    # Open input file and add it to the archive.
+    with open(input_file_name, 'rb') as input_file:
+      tarInfo = tarfile.TarInfo(name=archive_file_name)
+      input_file.seek(0,2)
+      tarInfo.size = input_file.tell()
+      input_file.seek(0)
+      tar.addfile(tarInfo, fileobj=input_file)
+  tar.close()
+
+def writeCCFile(output_file,
+                outer_namespace,
+                inner_namespace,
+                name,
+                tar_archive,
+                ):
+  cc_text = '''
+// Copyright (c) %d, 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.
+
+''' % date.today().year
+  cc_text += '''
+
+#if defined(_WIN32)
+typedef unsigned __int8 uint8_t;
+#else
+#include <inttypes.h>
+#include <stdint.h>
+#endif
+#include <stddef.h>
+
+'''
+  cc_text += 'namespace %s {\n' % outer_namespace
+  if inner_namespace != None:
+    cc_text += 'namespace %s {\n' % inner_namespace
+  cc_text += '\n\n'
+  # Write the archive.
+  cc_text += 'static const uint8_t %s_[] = {\n   ' % name
+  lineCounter = 0
+  for byte in tar_archive:
+    cc_text += r" %d," % ord(byte)
+    lineCounter += 1
+    if lineCounter == 10:
+      cc_text += '\n   '
+      lineCounter = 0
+  if lineCounter != 0:
+    cc_text += '\n   '
+  cc_text += '\n};\n'
+  cc_text += '\nunsigned int %s_len = %d;\n' % (name, len(tar_archive))
+  cc_text += '\nconst uint8_t* %s = %s_;\n\n' % (name, name)
+  if inner_namespace != None:
+    cc_text += '}  // namespace %s\n' % inner_namespace
+  cc_text += '} // namespace %s\n' % outer_namespace
+
+  open(output_file, 'w').write(cc_text)
+
+def main(args):
+  try:
+    # Parse input.
+    parser = OptionParser()
+    parser.add_option("--output",
+                      action="store", type="string",
+                      help="output file name")
+    parser.add_option("--tar_output",
+                      action="store", type="string",
+                      help="tar output file name")
+    parser.add_option("--outer_namespace",
+                      action="store", type="string",
+                      help="outer C++ namespace",
+                      default="dart")
+    parser.add_option("--inner_namespace",
+                      action="store", type="string",
+                      help="inner C++ namespace",
+                      default="bin")
+    parser.add_option("--name",
+                      action="store", type="string",
+                      help="name of tar archive symbol")
+    parser.add_option("--client_root",
+                      action="store", type="string",
+                      help="root directory client resources")
+
+    (options, args) = parser.parse_args()
+    if not options.output:
+      sys.stderr.write('--output not specified\n')
+      return -1
+    if not options.tar_output:
+      sys.stderr.write('--tar_output not specified\n')
+      return -1
+    if not options.name:
+      sys.stderr.write('--name not specified\n')
+      return -1
+    if not options.client_root:
+      sys.stderr.write('--client_root not specified')
+      return -1
+
+    files = [ ]
+
+    for dirname, dirnames, filenames in os.walk(options.client_root):
+      # strip out all dot files.
+      filenames = [f for f in filenames if not f[0] == '.']
+      dirnames[:] = [d for d in dirnames if not d[0] == '.']
+      for f in filenames:
+        src_path = os.path.join(dirname, f)
+        if (os.path.isdir(src_path)):
+            continue
+        files.append(src_path)
+
+    # Write out archive.
+    makeArchive(options.tar_output, options.client_root, files)
+
+    # Read it back in.
+    with open(options.tar_output, 'rb') as tar_file:
+      tar_archive = tar_file.read()
+
+    # Write CC file.
+    writeCCFile(options.output,
+                options.outer_namespace,
+                options.inner_namespace,
+                options.name,
+                tar_archive)
+    return 0
+
+  except Exception, inst:
+    sys.stderr.write('create_resources.py exception\n')
+    sys.stderr.write(str(inst))
+    sys.stderr.write('\n')
+    return -1
+
+if __name__ == '__main__':
+  sys.exit(main(sys.argv))
diff --git a/runtime/tools/create_snapshot_bin.py b/runtime/tools/create_snapshot_bin.py
index b91de38..344c4e3 100755
--- a/runtime/tools/create_snapshot_bin.py
+++ b/runtime/tools/create_snapshot_bin.py
@@ -32,6 +32,13 @@
       action="store", type="string",
       help="output file name into which isolate snapshot in binary form " +
            "is generated")
+  result.add_option("--instructions_bin",
+      action="store", type="string",
+      help="output file name into which instructions snapshot in assembly " +
+           "form is generated")
+  result.add_option("--embedder_entry_points_manifest",
+      action="store", type="string",
+      help="input manifest with the vm entry points in a precompiled snapshot")
   result.add_option("--script",
       action="store", type="string",
       help="Dart script for which snapshot is to be generated")
@@ -108,6 +115,16 @@
                                options.vm_output_bin ]))
   script_args.append(''.join([ "--isolate_snapshot=", options.output_bin ]))
 
+  # Setup the instuctions snapshot output filename
+  if options.instructions_bin:
+    script_args.append(''.join([ "--instructions_snapshot=",
+                                 options.instructions_bin ]))
+
+  # Specify the embedder entry points snapshot
+  if options.embedder_entry_points_manifest:
+    script_args.append(''.join([ "--embedder_entry_points_manifest=",
+                                 options.embedder_entry_points_manifest ]))
+
   # Next setup all url mapping options specified.
   for url_arg in options.url_mapping:
     url_mapping_argument = ''.join(["--url_mapping=", url_arg ])
diff --git a/runtime/tools/gen_library_src_paths.py b/runtime/tools/gen_library_src_paths.py
index 2751215..8a55118 100644
--- a/runtime/tools/gen_library_src_paths.py
+++ b/runtime/tools/gen_library_src_paths.py
@@ -8,10 +8,30 @@
 
 import os
 import sys
+import utils
 
 from os.path import join
 from optparse import OptionParser
 
+HOST_OS = utils.GuessOS()
+
+
+def makeString(input_file):
+  # TODO(iposva): For now avoid creating overly long strings on Windows.
+  if HOST_OS == 'win32':
+    return 'NULL'
+  result = '"'
+  fileHandle = open(input_file, 'rb')
+  lineCounter = 0
+  for byte in fileHandle.read():
+    result += '\\x%02x' % ord(byte)
+    lineCounter += 1
+    if lineCounter == 19:
+      result += '"\n "'
+      lineCounter = 0
+  result += '"'
+  return result
+
 
 def makeFile(output_file, input_cc_file, include, var_name, lib_name, in_files):
   part_index = [ ]
@@ -29,15 +49,17 @@
             main_file_found = True
             bootstrap_cc_text = bootstrap_cc_text.replace(
                  "{{LIBRARY_SOURCE_MAP}}",
-                 ' "' + lib_name + '", "' +
-                 os.path.abspath(string_file).replace('\\', '\\\\') + '", \n')
+                 ' "' + lib_name + '",\n "' +
+                 os.path.abspath(string_file).replace('\\', '\\\\') + '",\n' +
+                 ' ' + makeString(string_file) + ',\n')
         inpt.close()
         if (main_file_found):
           continue
       part_index.append(' "' +
-          os.path.basename(string_file).replace('\\', '\\\\') + '", ')
-      part_index.append('"' +
-          os.path.abspath(string_file).replace('\\', '\\\\') + '", \n')
+          os.path.basename(string_file).replace('\\', '\\\\') + '",\n')
+      part_index.append(' "' +
+          os.path.abspath(string_file).replace('\\', '\\\\') + '",\n')
+      part_index.append(' ' + makeString(string_file) + ',\n\n')
   bootstrap_cc_text = bootstrap_cc_text.replace("{{LIBRARY_SOURCE_MAP}}", '')
   bootstrap_cc_text = bootstrap_cc_text.replace("{{PART_SOURCE_MAP}}",
                                                 ''.join(part_index))
diff --git a/runtime/vm/allocation.h b/runtime/vm/allocation.h
index 468c1ad..af9a74a 100644
--- a/runtime/vm/allocation.h
+++ b/runtime/vm/allocation.h
@@ -37,13 +37,6 @@
 // to a stack frame above the frame where these objects were allocated.
 class StackResource {
  public:
-  // DEPRECATED: Use Thread-based interface. During migration, this defaults
-  // to using the mutator thread (which must also be the current thread).
-  explicit StackResource(Isolate* isolate) : thread_(NULL), previous_(NULL) {
-    Init((isolate == NULL) ?
-        NULL : reinterpret_cast<BaseIsolate*>(isolate)->mutator_thread_);
-  }
-
   explicit StackResource(Thread* thread) : thread_(NULL), previous_(NULL) {
     Init(thread);
   }
diff --git a/runtime/vm/allocation_test.cc b/runtime/vm/allocation_test.cc
index f8fe5a0..63b91f6 100644
--- a/runtime/vm/allocation_test.cc
+++ b/runtime/vm/allocation_test.cc
@@ -32,7 +32,7 @@
 class TestStackResource : public StackResource {
  public:
   explicit TestStackResource(int* ptr)
-      : StackResource(Isolate::Current()), ptr_(ptr) {
+      : StackResource(Thread::Current()), ptr_(ptr) {
     EXPECT_EQ(1, *ptr_);
     *ptr_ = 2;
   }
@@ -53,7 +53,7 @@
 class TestStackedStackResource : public StackResource {
  public:
   explicit TestStackedStackResource(int* ptr)
-      : StackResource(Isolate::Current()), ptr_(ptr) {
+      : StackResource(Thread::Current()), ptr_(ptr) {
     EXPECT_EQ(3, *ptr_);
     *ptr_ = 4;
   }
diff --git a/runtime/vm/assembler_arm.cc b/runtime/vm/assembler_arm.cc
index 815b796..c32632d 100644
--- a/runtime/vm/assembler_arm.cc
+++ b/runtime/vm/assembler_arm.cc
@@ -14,7 +14,8 @@
 #include "vm/stub_code.h"
 
 // An extra check since we are assuming the existence of /proc/cpuinfo below.
-#if !defined(USING_SIMULATOR) && !defined(__linux__) && !defined(ANDROID)
+#if !defined(USING_SIMULATOR) && !defined(__linux__) && !defined(ANDROID) && \
+    !TARGET_OS_IOS
 #error ARM cross-compile only supported on Linux
 #endif
 
@@ -104,6 +105,8 @@
                           Address ad) {
   ASSERT(rd != kNoRegister);
   ASSERT(cond != kNoCondition);
+  ASSERT(!ad.has_writeback() || (ad.rn() != rd));  // Unpredictable.
+
   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
                      B26 | (ad.kind() == Address::Immediate ? 0 : B25) |
                      (load ? L : 0) |
@@ -493,10 +496,11 @@
 }
 
 
-void Assembler::ldrd(Register rd, Register rn, int32_t offset, Condition cond) {
+void Assembler::ldrd(Register rd, Register rd2, Register rn, int32_t offset,
+                     Condition cond) {
   ASSERT((rd % 2) == 0);
+  ASSERT(rd2 == rd + 1);
   if (TargetCPUFeatures::arm_version() == ARMv5TE) {
-    const Register rd2 = static_cast<Register>(static_cast<int32_t>(rd) + 1);
     ldr(rd, Address(rn, offset), cond);
     ldr(rd2, Address(rn, offset + kWordSize), cond);
   } else {
@@ -505,10 +509,11 @@
 }
 
 
-void Assembler::strd(Register rd, Register rn, int32_t offset, Condition cond) {
+void Assembler::strd(Register rd, Register rd2, Register rn, int32_t offset,
+                     Condition cond) {
   ASSERT((rd % 2) == 0);
+  ASSERT(rd2 == rd + 1);
   if (TargetCPUFeatures::arm_version() == ARMv5TE) {
-    const Register rd2 = static_cast<Register>(static_cast<int32_t>(rd) + 1);
     str(rd, Address(rn, offset), cond);
     str(rd2, Address(rn, offset + kWordSize), cond);
   } else {
@@ -1513,6 +1518,7 @@
 
 void Assembler::CheckCodePointer() {
 #ifdef DEBUG
+  Comment("CheckCodePointer");
   Label cid_ok, instructions_ok;
   Push(R0);
   Push(IP);
@@ -1707,20 +1713,23 @@
                                        Register value_odd,
                                        Condition cond) {
   ASSERT(value_odd == value_even + 1);
+  ASSERT(value_even % 2 == 0);
   if (VerifiedMemory::enabled()) {
     ASSERT(base != value_even);
     ASSERT(base != value_odd);
     Operand shadow(GetVerifiedMemoryShadow());
     add(base, base, shadow, cond);
-    strd(value_even, base, offset, cond);
+    strd(value_even, value_odd, base, offset, cond);
     sub(base, base, shadow, cond);
   }
-  strd(value_even, base, offset, cond);
+  strd(value_even, value_odd, base, offset, cond);
 }
 
 
 Register UseRegister(Register reg, RegList* used) {
+  ASSERT(reg != THR);
   ASSERT(reg != SP);
+  ASSERT(reg != FP);
   ASSERT(reg != PC);
   ASSERT((*used & (1 << reg)) == 0);
   *used |= (1 << reg);
@@ -1736,7 +1745,8 @@
 }
 
 
-void Assembler::VerifiedWrite(const Address& address,
+void Assembler::VerifiedWrite(Register object,
+                              const Address& address,
                               Register new_value,
                               FieldContent old_content) {
 #if defined(DEBUG)
@@ -1746,6 +1756,9 @@
   RegList used = 0;
   UseRegister(new_value, &used);
   Register base = UseRegister(address.rn(), &used);
+  if ((object != base) && (object != kNoRegister)) {
+    UseRegister(object, &used);
+  }
   if (address.rm() != kNoRegister) {
     UseRegister(address.rm(), &used);
   }
@@ -1814,7 +1827,7 @@
                                 Register value,
                                 bool can_value_be_smi) {
   ASSERT(object != value);
-  VerifiedWrite(dest, value, kHeapObjectOrSmi);
+  VerifiedWrite(object, dest, value, kHeapObjectOrSmi);
   Label done;
   if (can_value_be_smi) {
     StoreIntoObjectFilter(object, value, &done);
@@ -1857,7 +1870,7 @@
                                          const Address& dest,
                                          Register value,
                                          FieldContent old_content) {
-  VerifiedWrite(dest, value, old_content);
+  VerifiedWrite(object, dest, value, old_content);
 #if defined(DEBUG)
   Label done;
   StoreIntoObjectFilter(object, value, &done);
@@ -1891,7 +1904,7 @@
          (value.IsOld() && value.IsNotTemporaryScopedHandle()));
   // No store buffer update.
   LoadObject(IP, value);
-  VerifiedWrite(dest, IP, old_content);
+  VerifiedWrite(object, dest, IP, old_content);
 }
 
 
@@ -1904,8 +1917,11 @@
     StoreIntoObjectNoBarrier(object, FieldAddress(object, offset), value,
                              old_content);
   } else {
-    AddImmediate(IP, object, offset - kHeapObjectTag);
-    StoreIntoObjectNoBarrier(object, Address(IP), value, old_content);
+    Register base = object == R9 ? R8 : R9;
+    Push(base);
+    AddImmediate(base, object, offset - kHeapObjectTag);
+    StoreIntoObjectNoBarrier(object, Address(base), value, old_content);
+    Pop(base);
   }
 }
 
@@ -1969,7 +1985,7 @@
   Stop("New value must be Smi.");
   Bind(&done);
 #endif  // defined(DEBUG)
-  VerifiedWrite(dest, value, kOnlySmi);
+  VerifiedWrite(kNoRegister, dest, value, kOnlySmi);
 }
 
 
@@ -2831,6 +2847,7 @@
                                Register base,
                                int32_t offset,
                                Condition cond) {
+  ASSERT(size != kWordPair);
   int32_t offset_mask = 0;
   if (!Address::CanHoldLoadOffset(size, offset, &offset_mask)) {
     ASSERT(base != IP);
@@ -2854,9 +2871,6 @@
     case kWord:
       ldr(reg, Address(base, offset), cond);
       break;
-    case kWordPair:
-      ldrd(reg, base, offset, cond);
-      break;
     default:
       UNREACHABLE();
   }
@@ -2868,6 +2882,7 @@
                               Register base,
                               int32_t offset,
                               Condition cond) {
+  ASSERT(size != kWordPair);
   int32_t offset_mask = 0;
   if (!Address::CanHoldStoreOffset(size, offset, &offset_mask)) {
     ASSERT(reg != IP);
@@ -2886,9 +2901,6 @@
     case kWord:
       str(reg, Address(base, offset), cond);
       break;
-    case kWordPair:
-      strd(reg, base, offset, cond);
-      break;
     default:
       UNREACHABLE();
   }
@@ -3243,6 +3255,7 @@
 
 
 void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) {
+  Comment("EnterCallRuntimeFrame");
   // Preserve volatile CPU registers and PP.
   EnterFrame(kDartVolatileCpuRegs | (1 << PP) | (1 << FP), 0);
   COMPILE_ASSERT((kDartVolatileCpuRegs & (1 << PP)) == 0);
@@ -3309,7 +3322,10 @@
 void Assembler::EnterDartFrame(intptr_t frame_size) {
   ASSERT(!constant_pool_allowed());
 
-  // Registers are pushed in descending order: R9 | R10 | R11 | R14.
+  // Registers are pushed in descending order: R5 | R6 | R7/R11 | R14.
+  COMPILE_ASSERT(PP < CODE_REG);
+  COMPILE_ASSERT(CODE_REG < FP);
+  COMPILE_ASSERT(FP < LR);
   EnterFrame((1 << PP) | (1 << CODE_REG) | (1 << FP) | (1 << LR), 0);
 
   // Setup pool pointer for this dart function.
diff --git a/runtime/vm/assembler_arm.h b/runtime/vm/assembler_arm.h
index 9ba279c..80b888b 100644
--- a/runtime/vm/assembler_arm.h
+++ b/runtime/vm/assembler_arm.h
@@ -321,6 +321,11 @@
 
   Mode mode() const { return static_cast<Mode>(encoding() & kModeMask); }
 
+  bool has_writeback() const {
+    return (mode() == PreIndex) || (mode() == PostIndex) ||
+           (mode() == NegPreIndex) || (mode() == NegPostIndex);
+  }
+
   uint32_t encoding() const { return encoding_; }
 
   // Encoding for addressing mode 3.
@@ -513,8 +518,11 @@
   // ldrd and strd actually support the full range of addressing modes, but
   // we don't use them, and we need to split them up into two instructions for
   // ARMv5TE, so we only support the base + offset mode.
-  void ldrd(Register rd, Register rn, int32_t offset, Condition cond = AL);
-  void strd(Register rd, Register rn, int32_t offset, Condition cond = AL);
+  // rd must be an even register and rd2 must be rd + 1.
+  void ldrd(Register rd, Register rd2, Register rn, int32_t offset,
+            Condition cond = AL);
+  void strd(Register rd, Register rd2, Register rn, int32_t offset,
+            Condition cond = AL);
 
   void ldm(BlockAddressMode am, Register base,
            RegList regs, Condition cond = AL);
@@ -1197,7 +1205,8 @@
                               Condition cond = AL);
   // Writes new_value to address and its shadow location, if enabled, after
   // verifying that its old value matches its shadow.
-  void VerifiedWrite(const Address& address,
+  void VerifiedWrite(Register object,
+                     const Address& address,
                      Register new_value,
                      FieldContent old_content);
 
diff --git a/runtime/vm/assembler_arm64.cc b/runtime/vm/assembler_arm64.cc
index 06203d2..14a51cd 100644
--- a/runtime/vm/assembler_arm64.cc
+++ b/runtime/vm/assembler_arm64.cc
@@ -14,7 +14,8 @@
 #include "vm/stub_code.h"
 
 // An extra check since we are assuming the existence of /proc/cpuinfo below.
-#if !defined(USING_SIMULATOR) && !defined(__linux__) && !defined(ANDROID)
+#if !defined(USING_SIMULATOR) && !defined(__linux__) && !defined(ANDROID) && \
+    !TARGET_OS_IOS
 #error ARM64 cross-compile only supported on Linux
 #endif
 
@@ -1076,6 +1077,7 @@
 
 void Assembler::CheckCodePointer() {
 #ifdef DEBUG
+  Comment("CheckCodePointer");
   Label cid_ok, instructions_ok;
   Push(R0);
   CompareClassId(CODE_REG, kCodeCid);
@@ -1162,6 +1164,7 @@
 
 
 void Assembler::EnterCallRuntimeFrame(intptr_t frame_size) {
+  Comment("EnterCallRuntimeFrame");
   EnterStubFrame();
 
   // Store fpu registers with the lowest register number at the lowest
diff --git a/runtime/vm/assembler_arm_test.cc b/runtime/vm/assembler_arm_test.cc
index dd53235..12f470a 100644
--- a/runtime/vm/assembler_arm_test.cc
+++ b/runtime/vm/assembler_arm_test.cc
@@ -1150,10 +1150,10 @@
 ASSEMBLER_TEST_GENERATE(Ldrd, assembler) {
   __ mov(IP, Operand(SP));
   __ sub(SP, SP, Operand(kWordSize*30));
-  __ strd(R2, SP, 0);
-  __ strd(R0, IP, (-kWordSize*28));
-  __ ldrd(R2, IP, (-kWordSize*28));
-  __ ldrd(R0, SP, 0);
+  __ strd(R2, R3, SP, 0);
+  __ strd(R0, R1, IP, (-kWordSize*28));
+  __ ldrd(R2, R3, IP, (-kWordSize*28));
+  __ ldrd(R0, R1, SP, 0);
   __ add(SP, SP, Operand(kWordSize*30));
   __ sub(R0, R0, Operand(R2));
   __ add(R1, R1, Operand(R3));
@@ -1174,33 +1174,33 @@
   __ mov(R1, Operand(7));
   __ mov(R2, Operand(11));
   __ mov(R3, Operand(31));
-  __ Push(R5);  // We use R5 as accumulator.
-  __ Push(R5);
-  __ Push(R5);
-  __ Push(R5);
-  __ Push(R5);
+  __ Push(R9);  // We use R9 as accumulator.
+  __ Push(R9);
+  __ Push(R9);
+  __ Push(R9);
+  __ Push(R9);
   __ Push(R0);  // Make room, so we can decrement after.
   __ stm(DA_W, SP, (1 << R0 | 1 << R1 | 1 << R2 | 1 << R3));
   __ str(R2, Address(SP));                 // Should be a free slot.
-  __ ldr(R5, Address(SP, 1 * kWordSize));  // R0.  R5 = +1.
+  __ ldr(R9, Address(SP, 1 * kWordSize));  // R0.  R9 = +1.
   __ ldr(IP, Address(SP, 2 * kWordSize));  // R1.
-  __ sub(R5, R5, Operand(IP));      // -R1. R5 = -6.
+  __ sub(R9, R9, Operand(IP));      // -R1. R9 = -6.
   __ ldr(IP, Address(SP, 3 * kWordSize));  // R2.
-  __ add(R5, R5, Operand(IP));      // +R2. R5 = +5.
+  __ add(R9, R9, Operand(IP));      // +R2. R9 = +5.
   __ ldr(IP, Address(SP, 4 * kWordSize));  // R3.
-  __ sub(R5, R5, Operand(IP));      // -R3. R5 = -26.
+  __ sub(R9, R9, Operand(IP));      // -R3. R9 = -26.
   __ ldm(IB_W, SP, (1 << R0 | 1 << R1 | 1 << R2 | 1 << R3));
   // Same operations again. But this time from the restore registers.
-  __ add(R5, R5, Operand(R0));
-  __ sub(R5, R5, Operand(R1));
-  __ add(R5, R5, Operand(R2));
-  __ sub(R0, R5, Operand(R3));  // R0 = result = -52.
+  __ add(R9, R9, Operand(R0));
+  __ sub(R9, R9, Operand(R1));
+  __ add(R9, R9, Operand(R2));
+  __ sub(R0, R9, Operand(R3));  // R0 = result = -52.
   __ Pop(R1);  // Remove storage slot.
-  __ Pop(R5);  // Restore R5.
-  __ Pop(R5);  // Restore R5.
-  __ Pop(R5);  // Restore R5.
-  __ Pop(R5);  // Restore R5.
-  __ Pop(R5);  // Restore R5.
+  __ Pop(R9);  // Restore R9.
+  __ Pop(R9);  // Restore R9.
+  __ Pop(R9);  // Restore R9.
+  __ Pop(R9);  // Restore R9.
+  __ Pop(R9);  // Restore R9.
   __ bx(LR);
 }
 
diff --git a/runtime/vm/assembler_ia32.cc b/runtime/vm/assembler_ia32.cc
index 7fe4193..c4ee937 100644
--- a/runtime/vm/assembler_ia32.cc
+++ b/runtime/vm/assembler_ia32.cc
@@ -2570,6 +2570,7 @@
 
 
 void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) {
+  Comment("EnterCallRuntimeFrame");
   EnterFrame(0);
 
   // Preserve volatile CPU registers.
diff --git a/runtime/vm/assembler_mips.cc b/runtime/vm/assembler_mips.cc
index 90a010a..9f63660 100644
--- a/runtime/vm/assembler_mips.cc
+++ b/runtime/vm/assembler_mips.cc
@@ -461,6 +461,7 @@
 
 void Assembler::CheckCodePointer() {
 #ifdef DEBUG
+  Comment("CheckCodePointer");
   Label cid_ok, instructions_ok;
   Push(CMPRES1);
   Push(CMPRES2);
diff --git a/runtime/vm/assembler_mips.h b/runtime/vm/assembler_mips.h
index 5316110..e075dd3 100644
--- a/runtime/vm/assembler_mips.h
+++ b/runtime/vm/assembler_mips.h
@@ -762,6 +762,12 @@
     EmitRType(SPECIAL, rs, rt, R0, 0, MULTU);
   }
 
+  void negd(DRegister dd, DRegister ds) {
+    FRegister fd = static_cast<FRegister>(dd * 2);
+    FRegister fs = static_cast<FRegister>(ds * 2);
+    EmitFpuRType(COP1, FMT_D, F0, fs, fd, COP1_NEG);
+  }
+
   void nop() {
     Emit(Instr::kNopInstruction);
   }
diff --git a/runtime/vm/assembler_mips_test.cc b/runtime/vm/assembler_mips_test.cc
index 552aa60..f23fe93 100644
--- a/runtime/vm/assembler_mips_test.cc
+++ b/runtime/vm/assembler_mips_test.cc
@@ -1639,6 +1639,21 @@
 }
 
 
+ASSEMBLER_TEST_GENERATE(Negd, assembler) {
+  __ LoadImmediate(D1, 1.0);
+  __ negd(D0, D1);
+  __ Ret();
+}
+
+
+ASSEMBLER_TEST_RUN(Negd, test) {
+  typedef double (*SimpleCode)() DART_UNUSED;
+  EXPECT(test != NULL);
+  double res = EXECUTE_TEST_CODE_DOUBLE(SimpleCode, test->entry());
+  EXPECT_FLOAT_EQ(-1.0, res, 0.001);
+}
+
+
 ASSEMBLER_TEST_GENERATE(Sdc1Ldc1, assembler) {
   __ mov(T0, SP);
   __ AddImmediate(SP, -3 * kWordSize);
diff --git a/runtime/vm/assembler_x64.cc b/runtime/vm/assembler_x64.cc
index 04e82d8..9c4b45d 100644
--- a/runtime/vm/assembler_x64.cc
+++ b/runtime/vm/assembler_x64.cc
@@ -1343,13 +1343,6 @@
 }
 
 
-void Assembler::fildl(const Address& src) {
-  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
-  EmitUint8(0xDF);
-  EmitOperand(5, src);
-}
-
-
 void Assembler::fincstp() {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   EmitUint8(0xD9);
@@ -3331,6 +3324,7 @@
 
 
 void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) {
+  Comment("EnterCallRuntimeFrame");
   EnterStubFrame();
 
   // TODO(vegorov): avoid saving FpuTMP, it is used only as scratch.
@@ -3420,6 +3414,7 @@
 
 void Assembler::CheckCodePointer() {
 #ifdef DEBUG
+  Comment("CheckCodePointer");
   Label cid_ok, instructions_ok;
   pushq(RAX);
   LoadClassId(RAX, CODE_REG);
diff --git a/runtime/vm/assembler_x64.h b/runtime/vm/assembler_x64.h
index 0a6b694..30feb10 100644
--- a/runtime/vm/assembler_x64.h
+++ b/runtime/vm/assembler_x64.h
@@ -671,8 +671,6 @@
   void fldl(const Address& src);
   void fstpl(const Address& dst);
 
-  void fildl(const Address& src);
-
   void fincstp();
   void ffree(intptr_t value);
 
diff --git a/runtime/vm/assembler_x64_test.cc b/runtime/vm/assembler_x64_test.cc
index e404b89..a78f3ca 100644
--- a/runtime/vm/assembler_x64_test.cc
+++ b/runtime/vm/assembler_x64_test.cc
@@ -3393,22 +3393,6 @@
 }
 
 
-ASSEMBLER_TEST_GENERATE(IntToDoubleConversion2, assembler) {
-  __ pushq(CallingConventions::kArg1Reg);
-  __ fildl(Address(RSP, 0));
-  __ fstpl(Address(RSP, 0));
-  __ movsd(XMM0, Address(RSP, 0));
-  __ popq(RAX);
-  __ ret();
-}
-
-
-ASSEMBLER_TEST_RUN(IntToDoubleConversion2, test) {
-  typedef double (*IntToDoubleConversion2Code)(int i);
-  double res = reinterpret_cast<IntToDoubleConversion2Code>(test->entry())(3);
-  EXPECT_FLOAT_EQ(3.0, res, 0.001);
-}
-
 ASSEMBLER_TEST_GENERATE(DoubleToDoubleTrunc, assembler) {
   __ roundsd(XMM0, XMM0, Assembler::kRoundToZero);
   __ ret();
diff --git a/runtime/vm/ast.h b/runtime/vm/ast.h
index c3b6ac1..14934fd 100644
--- a/runtime/vm/ast.h
+++ b/runtime/vm/ast.h
@@ -1814,19 +1814,14 @@
   NativeBodyNode(intptr_t token_pos,
                  const Function& function,
                  const String& native_c_function_name,
-                 NativeFunction native_c_function,
                  LocalScope* scope,
-                 bool is_bootstrap_native,
                  bool link_lazily = false)
       : AstNode(token_pos),
         function_(function),
         native_c_function_name_(native_c_function_name),
-        native_c_function_(native_c_function),
         scope_(scope),
-        is_bootstrap_native_(is_bootstrap_native),
         link_lazily_(link_lazily) {
     ASSERT(function_.IsZoneHandle());
-    ASSERT(native_c_function_ != NULL);
     ASSERT(native_c_function_name_.IsZoneHandle());
     ASSERT(native_c_function_name_.IsSymbol());
   }
@@ -1835,9 +1830,7 @@
   const String& native_c_function_name() const {
     return native_c_function_name_;
   }
-  NativeFunction native_c_function() const { return native_c_function_; }
   LocalScope* scope() const { return scope_; }
-  bool is_bootstrap_native() const { return is_bootstrap_native_; }
 
   bool link_lazily() const { return link_lazily_; }
 
@@ -1848,9 +1841,7 @@
  private:
   const Function& function_;  // Native Dart function.
   const String& native_c_function_name_;
-  NativeFunction native_c_function_;  // Actual non-Dart implementation.
   LocalScope* scope_;
-  const bool is_bootstrap_native_;  // Is a bootstrap native method.
   const bool link_lazily_;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(NativeBodyNode);
diff --git a/runtime/vm/base_isolate.h b/runtime/vm/base_isolate.h
index 833f7e5..b2cc7fc 100644
--- a/runtime/vm/base_isolate.h
+++ b/runtime/vm/base_isolate.h
@@ -42,9 +42,6 @@
   Thread* mutator_thread_;
 
  private:
-  // During migration, some deprecated interfaces will default to using the
-  // mutator_thread_ (can't use accessor in Isolate due to circular deps).
-  friend class StackResource;
   DISALLOW_COPY_AND_ASSIGN(BaseIsolate);
 };
 
diff --git a/runtime/vm/benchmark_test.cc b/runtime/vm/benchmark_test.cc
index 9fcb4d00..1b22bc5 100644
--- a/runtime/vm/benchmark_test.cc
+++ b/runtime/vm/benchmark_test.cc
@@ -41,8 +41,7 @@
   bin::Builtin::SetNativeResolver(bin::Builtin::kIOLibrary);
   Timer timer(true, "Compile all of Core lib benchmark");
   timer.Start();
-  const Error& error = Error::Handle(benchmark->isolate()->current_zone(),
-                                     Library::CompileAll());
+  const Error& error = Error::Handle(Library::CompileAll());
   if (!error.IsNull()) {
     OS::PrintErr("Unexpected error in CorelibCompileAll benchmark:\n%s",
                  error.ToErrorCString());
@@ -61,8 +60,7 @@
   stats->EnableBenchmark();
   Timer timer(true, "Compiler stats compiling all of Core lib");
   timer.Start();
-  const Error& error = Error::Handle(benchmark->isolate()->current_zone(),
-                                     Library::CompileAll());
+  const Error& error = Error::Handle(Library::CompileAll());
   if (!error.IsNull()) {
     OS::PrintErr("Unexpected error in CorelibCompileAll benchmark:\n%s",
                  error.ToErrorCString());
diff --git a/runtime/vm/bootstrap.cc b/runtime/vm/bootstrap.cc
index 85fcf52..5d7bdc39 100644
--- a/runtime/vm/bootstrap.cc
+++ b/runtime/vm/bootstrap.cc
@@ -30,6 +30,14 @@
 } bootstrap_lib_props;
 
 
+enum {
+  kPathsUriOffset = 0,
+  kPathsFileOffset = 1,
+  kPathsSourceOffset = 2,
+  kPathsEntryLength = 3
+};
+
+
 static bootstrap_lib_props bootstrap_libraries[] = {
   INIT_LIBRARY(ObjectStore::kCore,
                core,
@@ -86,7 +94,7 @@
 static RawString* GetLibrarySource(const Library& lib,
                                    const String& uri,
                                    bool patch) {
-  // First check if this is a valid boot strap library and find it's index
+  // First check if this is a valid bootstrap library and find it's index
   // in the 'bootstrap_libraries' table above.
   intptr_t index;
   const String& lib_uri = String::Handle(lib.url());
@@ -98,7 +106,7 @@
     }
   }
   if (bootstrap_libraries[index].index_ == ObjectStore::kNone) {
-    return String::null();  // Library is not a boot strap library.
+    return String::null();  // Library is not a bootstrap library.
   }
 
   // Try to read the source using the path specified for the uri.
@@ -109,38 +117,42 @@
     return String::null();  // No path mapping information exists for library.
   }
   const char* source_path = NULL;
-  for (intptr_t i = 0; source_paths[i] != NULL; i += 2) {
-    if (uri.Equals(source_paths[i])) {
-      source_path = source_paths[i + 1];
+  const char* source_data = NULL;
+  for (intptr_t i = 0; source_paths[i] != NULL; i += kPathsEntryLength) {
+    if (uri.Equals(source_paths[i + kPathsUriOffset])) {
+      source_path = source_paths[i + kPathsFileOffset];
+      source_data = source_paths[i + kPathsSourceOffset];
       break;
     }
   }
-  if (source_path == NULL) {
+  if ((source_path == NULL) && (source_data == NULL)) {
     return String::null();  // Uri does not exist in path mapping information.
   }
 
-  Dart_FileOpenCallback file_open = Isolate::file_open_callback();
-  Dart_FileReadCallback file_read = Isolate::file_read_callback();
-  Dart_FileCloseCallback file_close = Isolate::file_close_callback();
-  if (file_open == NULL || file_read == NULL || file_close == NULL) {
-    return String::null();  // File operations are not supported.
-  }
-
-  void* stream = (*file_open)(source_path, false);
-  if (stream == NULL) {
-    return String::null();
-  }
-
   const uint8_t* utf8_array = NULL;
   intptr_t file_length = -1;
-  (*file_read)(&utf8_array, &file_length, stream);
+
+  Dart_FileOpenCallback file_open = Isolate::file_open_callback();
+  Dart_FileReadCallback file_read = Isolate::file_read_callback();
+  Dart_FileCloseCallback file_close = Isolate::file_close_callback();
+  if ((file_open != NULL) && (file_read != NULL) && (file_close != NULL)) {
+    // Try to open and read the file.
+    void* stream = (*file_open)(source_path, false);
+    if (stream != NULL) {
+      (*file_read)(&utf8_array, &file_length, stream);
+      (*file_close)(stream);
+    }
+  }
   if (file_length == -1) {
-    return String::null();
+    if (source_data != NULL) {
+      file_length = strlen(source_data);
+      utf8_array = reinterpret_cast<const uint8_t*>(source_data);
+    } else {
+      return String::null();
+    }
   }
   ASSERT(utf8_array != NULL);
-
-  (*file_close)(stream);
-
+  ASSERT(file_length >= 0);
   return String::FromUTF8(utf8_array, file_length);
 }
 
@@ -237,8 +249,8 @@
   const Array& strings = Array::Handle(zone, Array::New(3));
   strings.SetAt(0, patch_uri);
   strings.SetAt(1, Symbols::Slash());
-  for (intptr_t j = 0; patch_files[j] != NULL; j += 2) {
-    patch_file_uri = String::New(patch_files[j]);
+  for (intptr_t j = 0; patch_files[j] != NULL; j += kPathsEntryLength) {
+    patch_file_uri = String::New(patch_files[j + kPathsUriOffset]);
     source = GetLibrarySource(lib, patch_file_uri, true);
     if (source.IsNull()) {
       const String& message = String::Handle(
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index e416b7f..03393de 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -144,6 +144,7 @@
   V(Random_nextState, 1)                                                       \
   V(Random_setupSeed, 1)                                                       \
   V(Random_initialSeed, 0)                                                     \
+  V(SecureRandom_getBytes, 1)                                                  \
   V(DateNatives_currentTimeMillis, 0)                                          \
   V(DateNatives_timeZoneName, 1)                                               \
   V(DateNatives_timeZoneOffsetInSeconds, 1)                                    \
@@ -155,9 +156,11 @@
   V(AbstractClassInstantiationError_throwNew, 2)                               \
   V(Stopwatch_now, 0)                                                          \
   V(Stopwatch_frequency, 0)                                                    \
+  V(Timeline_getIsolateNum, 0)                                                 \
   V(Timeline_getNextAsyncId, 0)                                                \
   V(Timeline_getTraceClock, 0)                                                 \
   V(Timeline_reportCompleteEvent, 5)                                           \
+  V(Timeline_reportInstantEvent, 4)                                            \
   V(Timeline_reportTaskEvent, 6)                                               \
   V(TypedData_Int8Array_new, 1)                                                \
   V(TypedData_Uint8Array_new, 1)                                               \
@@ -402,6 +405,7 @@
   V(VMService_OnExit, 0)                                                       \
   V(VMService_ListenStream, 1)                                                 \
   V(VMService_CancelStream, 1)                                                 \
+  V(VMService_RequestAssets, 0)                                                \
 
 class BootstrapNatives : public AllStatic {
  public:
diff --git a/runtime/vm/cha.cc b/runtime/vm/cha.cc
index a2f50a3..667d598 100644
--- a/runtime/vm/cha.cc
+++ b/runtime/vm/cha.cc
@@ -62,14 +62,20 @@
 
 
 bool CHA::HasOverride(const Class& cls, const String& function_name) {
-  const GrowableObjectArray& cls_direct_subclasses =
-      GrowableObjectArray::Handle(thread_->zone(), cls.direct_subclasses());
+  // Can't track dependencies for classes on the VM heap since those are
+  // read-only.
+  // TODO(fschneider): Enable tracking of CHA dependent code for VM heap
+  // classes.
+  if (cls.InVMHeap()) return true;
+
   // Subclasses of Object are not tracked by CHA. Safely assume that overrides
   // exist.
   if (cls.IsObjectClass()) {
     return true;
   }
 
+  const GrowableObjectArray& cls_direct_subclasses =
+      GrowableObjectArray::Handle(thread_->zone(), cls.direct_subclasses());
   if (cls_direct_subclasses.IsNull()) {
     return false;
   }
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 4d8178b..d8434d9 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -1314,7 +1314,7 @@
     field ^= array.At(i);
     type = field.type();
     type = FinalizeType(cls, type, kCanonicalize);
-    field.set_type(type);
+    field.SetFieldType(type);
     name = field.name();
     if (field.is_static()) {
       getter_name = Field::GetterSymbol(name);
@@ -2072,7 +2072,6 @@
   const String& mixin_name = String::Handle(mixin_app.Name());
   const Class& super_class = Class::Handle(mixin_app.SuperClass());
   const String& super_name = String::Handle(super_class.Name());
-  const Type& dynamic_type = Type::Handle(Type::DynamicType());
   const Array& functions = Array::Handle(super_class.functions());
   const intptr_t num_functions = functions.Length();
   Function& func = Function::Handle();
@@ -2105,7 +2104,7 @@
       clone.set_num_fixed_parameters(func.num_fixed_parameters());
       clone.SetNumOptionalParameters(func.NumOptionalParameters(),
                                      func.HasOptionalPositionalParameters());
-      clone.set_result_type(dynamic_type);
+      clone.set_result_type(Object::dynamic_type());
       clone.set_is_debuggable(false);
 
       const intptr_t num_parameters = func.NumParameters();
@@ -2117,7 +2116,7 @@
       // The parameter types of the cloned constructor are 'dynamic'.
       clone.set_parameter_types(Array::Handle(Array::New(num_parameters)));
       for (intptr_t n = 0; n < num_parameters; n++) {
-        clone.SetParameterTypeAt(n, dynamic_type);
+        clone.SetParameterTypeAt(n, Object::dynamic_type());
       }
       cloned_funcs.Add(clone);
     }
@@ -2438,10 +2437,7 @@
     enum_value.SetField(index_field, ordinal_value);
     const char* error_msg = "";
     enum_value = enum_value.CheckAndCanonicalize(&error_msg);
-    if (enum_value.IsNull()) {
-      ReportError(enum_cls, enum_cls.token_pos(), "Failed finalizing values.");
-      UNREACHABLE();
-    }
+    ASSERT(!enum_value.IsNull());
     ASSERT(enum_value.IsCanonical());
     field.SetStaticValue(enum_value, true);
     field.RecordStore(enum_value);
@@ -2450,6 +2446,9 @@
     values_list.SetAt(ord, enum_value);
   }
   values_list.MakeImmutable();
+  const char* error_msg = NULL;
+  values_list ^= values_list.CheckAndCanonicalize(&error_msg);
+  ASSERT(!values_list.IsNull());
 }
 
 
diff --git a/runtime/vm/class_table.cc b/runtime/vm/class_table.cc
index ea37920..52786ee 100644
--- a/runtime/vm/class_table.cc
+++ b/runtime/vm/class_table.cc
@@ -95,6 +95,7 @@
 
 
 void ClassTable::Register(const Class& cls) {
+  ASSERT(Thread::Current()->IsMutatorThread());
   intptr_t index = cls.id();
   if (index != kIllegalCid) {
     ASSERT(index > 0);
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index 60a3ab3..2aba065 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -59,8 +59,10 @@
 DEFINE_FLAG(bool, trace_type_checks, false, "Trace runtime type checks.");
 
 DECLARE_FLAG(int, deoptimization_counter_threshold);
+DECLARE_FLAG(bool, enable_inlining_annotations);
 DECLARE_FLAG(bool, trace_compiler);
 DECLARE_FLAG(bool, warn_on_javascript_compatibility);
+DECLARE_FLAG(int, max_polymorphic_checks);
 
 DEFINE_FLAG(bool, use_osr, true, "Use on-stack replacement.");
 DEFINE_FLAG(bool, trace_osr, false, "Trace attempts at on-stack replacement.");
@@ -779,11 +781,9 @@
 // Handle other invocations (implicit closures, noSuchMethod).
 RawFunction* InlineCacheMissHelper(
     const Instance& receiver,
-    const ICData& ic_data) {
-  const Array& args_descriptor = Array::Handle(ic_data.arguments_descriptor());
-
+    const Array& args_descriptor,
+    const String& target_name) {
   const Class& receiver_class = Class::Handle(receiver.clazz());
-  const String& target_name = String::Handle(ic_data.target_name());
 
   Function& result = Function::Handle();
   if (!ResolveCallThroughGetter(receiver,
@@ -828,7 +828,12 @@
                    String::Handle(ic_data.target_name()).ToCString(),
                    receiver.ToCString());
     }
-    target_function = InlineCacheMissHelper(receiver, ic_data);
+    const Array& args_descriptor =
+        Array::Handle(ic_data.arguments_descriptor());
+    const String& target_name = String::Handle(ic_data.target_name());
+    target_function = InlineCacheMissHelper(receiver,
+                                            args_descriptor,
+                                            target_name);
   }
   if (target_function.IsNull()) {
     ASSERT(!FLAG_lazy_dispatchers);
@@ -1008,18 +1013,21 @@
 
 // Handle a miss of a megamorphic cache.
 //   Arg0: Receiver.
-//   Arg1: ICData object.
+//   Arg1: ICData or MegamorphicCache.
 //   Arg2: Arguments descriptor array.
-
 //   Returns: target function to call.
 DEFINE_RUNTIME_ENTRY(MegamorphicCacheMissHandler, 3) {
-  const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0));
-  const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1));
-  const Array& descriptor = Array::CheckedHandle(arguments.ArgAt(2));
-  const String& name = String::Handle(ic_data.target_name());
-  const MegamorphicCache& cache = MegamorphicCache::Handle(
-      MegamorphicCacheTable::Lookup(isolate, name, descriptor));
-  Class& cls = Class::Handle(receiver.clazz());
+  const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0));
+  const Object& ic_data_or_cache = Object::Handle(zone, arguments.ArgAt(1));
+  const Array& descriptor = Array::CheckedHandle(zone, arguments.ArgAt(2));
+  String& name = String::Handle(zone);
+  if (ic_data_or_cache.IsICData()) {
+    name = ICData::Cast(ic_data_or_cache).target_name();
+  } else {
+    ASSERT(ic_data_or_cache.IsMegamorphicCache());
+    name = MegamorphicCache::Cast(ic_data_or_cache).target_name();
+  }
+  Class& cls = Class::Handle(zone, receiver.clazz());
   ASSERT(!cls.IsNull());
   if (FLAG_trace_ic || FLAG_trace_ic_miss_in_optimized) {
     OS::PrintErr("Megamorphic IC miss, class=%s, function=%s\n",
@@ -1027,41 +1035,70 @@
   }
 
   ArgumentsDescriptor args_desc(descriptor);
-  Function& target_function = Function::Handle(
+  Function& target_function = Function::Handle(zone,
       Resolver::ResolveDynamicForReceiverClass(cls,
                                                name,
                                                args_desc));
   if (target_function.IsNull()) {
-    target_function = InlineCacheMissHelper(receiver, ic_data);
+    target_function = InlineCacheMissHelper(receiver, descriptor, name);
   }
   if (target_function.IsNull()) {
     ASSERT(!FLAG_lazy_dispatchers);
     arguments.SetReturn(target_function);
     return;
   }
-  // Insert function found into cache and return it.
-  cache.EnsureCapacity();
-  const Smi& class_id = Smi::Handle(Smi::New(cls.id()));
-  cache.Insert(class_id, target_function);
+
+  if (ic_data_or_cache.IsICData()) {
+    const ICData& ic_data = ICData::Cast(ic_data_or_cache);
+    ic_data.AddReceiverCheck(receiver.GetClassId(), target_function);
+    if (ic_data.NumberOfChecks() > FLAG_max_polymorphic_checks) {
+      // Switch to megamorphic call.
+      const MegamorphicCache& cache = MegamorphicCache::Handle(zone,
+          MegamorphicCacheTable::Lookup(isolate, name, descriptor));
+      DartFrameIterator iterator;
+      StackFrame* miss_function_frame = iterator.NextFrame();
+      ASSERT(miss_function_frame->IsDartFrame());
+      StackFrame* caller_frame = iterator.NextFrame();
+      ASSERT(caller_frame->IsDartFrame());
+      const Code& code = Code::Handle(zone, caller_frame->LookupDartCode());
+      const Code& stub =
+          Code::Handle(zone, StubCode::MegamorphicLookup_entry()->code());
+      CodePatcher::PatchSwitchableCallAt(caller_frame->pc(),
+                                         code, ic_data, cache, stub);
+    }
+  } else {
+    const MegamorphicCache& cache = MegamorphicCache::Cast(ic_data_or_cache);
+    // Insert function found into cache and return it.
+    cache.EnsureCapacity();
+    const Smi& class_id = Smi::Handle(zone, Smi::New(cls.id()));
+    cache.Insert(class_id, target_function);
+  }
   arguments.SetReturn(target_function);
 }
 
 
 // Invoke appropriate noSuchMethod or closure from getter.
 // Arg0: receiver
-// Arg1: IC data
+// Arg1: ICData or MegamorphicCache
 // Arg2: arguments descriptor array
 // Arg3: arguments array
 DEFINE_RUNTIME_ENTRY(InvokeNoSuchMethodDispatcher, 4) {
   ASSERT(!FLAG_lazy_dispatchers);
-  const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0));
-  const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1));
-  const Array& orig_arguments_desc = Array::CheckedHandle(arguments.ArgAt(2));
-  const Array& orig_arguments = Array::CheckedHandle(arguments.ArgAt(3));
-  const String& target_name = String::Handle(ic_data.target_name());
+  const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0));
+  const Object& ic_data_or_cache = Object::Handle(zone, arguments.ArgAt(1));
+  const Array& orig_arguments_desc =
+      Array::CheckedHandle(zone, arguments.ArgAt(2));
+  const Array& orig_arguments = Array::CheckedHandle(zone, arguments.ArgAt(3));
+  String& target_name = String::Handle(zone);
+  if (ic_data_or_cache.IsICData()) {
+    target_name = ICData::Cast(ic_data_or_cache).target_name();
+  } else {
+    ASSERT(ic_data_or_cache.IsMegamorphicCache());
+    target_name = MegamorphicCache::Cast(ic_data_or_cache).target_name();
+  }
 
-  Class& cls = Class::Handle(receiver.clazz());
-  Function& function = Function::Handle();
+  Class& cls = Class::Handle(zone, receiver.clazz());
+  Function& function = Function::Handle(zone);
 
   // Dart distinguishes getters and regular methods and allows their calls
   // to mix with conversions, and its selectors are independent of arity. So do
@@ -1069,7 +1106,7 @@
   // need for conversion, or there really is no such method.
 
 #define NO_SUCH_METHOD()                                                       \
-  const Object& result = Object::Handle(                                       \
+  const Object& result = Object::Handle(zone,                                  \
       DartEntry::InvokeNoSuchMethod(receiver,                                  \
                                     target_name,                               \
                                     orig_arguments,                            \
@@ -1079,9 +1116,9 @@
 
 #define CLOSURIZE(some_function)                                               \
   const Function& closure_function =                                           \
-      Function::Handle(some_function.ImplicitClosureFunction());               \
+      Function::Handle(zone, some_function.ImplicitClosureFunction());         \
   const Object& result =                                                       \
-      Object::Handle(closure_function.ImplicitInstanceClosure(receiver));      \
+      Object::Handle(zone, closure_function.ImplicitInstanceClosure(receiver));\
   arguments.SetReturn(result);                                                 \
 
   const bool is_getter = Field::IsGetterName(target_name);
@@ -1091,7 +1128,7 @@
     // encountered first on the inheritance chain. Or,
     // o#foo= (o.get:#set:foo) failed, closurize o.foo= if it exists.
     String& field_name =
-        String::Handle(Field::NameFromGetter(target_name));
+        String::Handle(zone, Field::NameFromGetter(target_name));
 
     const bool is_extractor = field_name.CharAt(0) == '#';
     if (is_extractor) {
@@ -1143,14 +1180,15 @@
       // call method and with lazy dispatchers the field-invocation-dispatcher
       // would perform the closure call.
       const Object& result =
-        Object::Handle(DartEntry::InvokeClosure(orig_arguments,
-                                                orig_arguments_desc));
+        Object::Handle(zone, DartEntry::InvokeClosure(orig_arguments,
+                                                      orig_arguments_desc));
       CheckResultError(result);
       arguments.SetReturn(result);
       return;
     }
 
-    const String& getter_name = String::Handle(Field::GetterName(target_name));
+    const String& getter_name =
+        String::Handle(zone, Field::GetterName(target_name));
     while (!cls.IsNull()) {
       function ^= cls.LookupDynamicFunction(target_name);
       if (!function.IsNull()) {
@@ -1163,15 +1201,15 @@
         const Array& getter_arguments = Array::Handle(Array::New(1));
         getter_arguments.SetAt(0, receiver);
         const Object& getter_result =
-          Object::Handle(DartEntry::InvokeFunction(function,
-                                                   getter_arguments));
+          Object::Handle(zone, DartEntry::InvokeFunction(function,
+                                                         getter_arguments));
         CheckResultError(getter_result);
         ASSERT(getter_result.IsNull() || getter_result.IsInstance());
 
         orig_arguments.SetAt(0, getter_result);
         const Object& call_result =
-          Object::Handle(DartEntry::InvokeClosure(orig_arguments,
-                                                  orig_arguments_desc));
+          Object::Handle(zone, DartEntry::InvokeClosure(orig_arguments,
+                                                        orig_arguments_desc));
         CheckResultError(call_result);
         arguments.SetReturn(call_result);
         return;
@@ -1214,10 +1252,11 @@
 }
 
 
-static bool CanOptimizeFunction(const Function& function, Isolate* isolate) {
+static bool CanOptimizeFunction(const Function& function, Thread* thread) {
   const intptr_t kLowInvocationCount = -100000000;
+  Isolate* isolate = thread->isolate();
   if (isolate->debugger()->IsStepping() ||
-      isolate->debugger()->HasBreakpoint(function)) {
+      isolate->debugger()->HasBreakpoint(function, thread->zone())) {
     // We cannot set breakpoints and single step in optimized code,
     // so do not optimize the function.
     function.set_usage_counter(0);
@@ -1378,7 +1417,7 @@
     ASSERT(function.HasCode());
     // Don't do OSR on intrinsified functions: The intrinsic code expects to be
     // called like a regular function and can't be entered via OSR.
-    if (!CanOptimizeFunction(function, isolate) || function.is_intrinsic()) {
+    if (!CanOptimizeFunction(function, thread) || function.is_intrinsic()) {
       return;
     }
 
@@ -1387,7 +1426,7 @@
     ASSERT(function.unoptimized_code() != Object::null());
     intptr_t osr_id =
         Code::Handle(function.unoptimized_code()).GetDeoptIdForOsr(frame->pc());
-    ASSERT(osr_id != Thread::kNoDeoptId);
+    ASSERT(osr_id != Compiler::kNoOSRDeoptId);
     if (FLAG_trace_osr) {
       OS::Print("Attempting OSR for %s at id=%" Pd ", count=%" Pd "\n",
                 function.ToFullyQualifiedCString(),
@@ -1447,18 +1486,27 @@
   ASSERT(!function.IsNull());
   ASSERT(function.HasCode());
 
-  if (CanOptimizeFunction(function, isolate)) {
-    // Reset usage counter for reoptimization before calling optimizer to
-    // prevent recursive triggering of function optimization.
-    function.set_usage_counter(0);
+  if (CanOptimizeFunction(function, thread)) {
     if (FLAG_background_compilation) {
-      BackgroundCompiler::EnsureInit(isolate);
+      if (FLAG_enable_inlining_annotations) {
+        FATAL("Cannot enable inlining annotations and background compilation");
+      }
+      // Reduce the chance of triggering optimization while the function is
+      // being optimized in the background. INT_MIN should ensure that it takes
+      // long time to trigger optimization.
+      // Note that the background compilation queue rejects duplicate entries.
+      function.set_usage_counter(INT_MIN);
+      BackgroundCompiler::EnsureInit(thread);
       ASSERT(isolate->background_compiler() != NULL);
       isolate->background_compiler()->CompileOptimized(function);
       // Continue in the same code.
       arguments.SetReturn(Code::Handle(zone, function.CurrentCode()));
       return;
     }
+
+    // Reset usage counter for reoptimization before calling optimizer to
+    // prevent recursive triggering of function optimization.
+    function.set_usage_counter(0);
     if (FLAG_trace_compiler) {
       if (function.HasOptimizedCode()) {
         THR_Print("ReCompiling function: '%s' \n",
diff --git a/runtime/vm/code_generator_test.cc b/runtime/vm/code_generator_test.cc
index aac9311..2cdc6fb 100644
--- a/runtime/vm/code_generator_test.cc
+++ b/runtime/vm/code_generator_test.cc
@@ -192,58 +192,6 @@
 CODEGEN_TEST_RUN(BinaryOpCodegen, Double::New(2.5));
 
 
-// Tested Dart code:
-//   int dec(int a, [int b = 1]) native: "TestSmiSub";
-// The native entry TestSmiSub implements dec natively.
-CODEGEN_TEST_GENERATE(NativeDecCodegen, test) {
-  // A NativeBodyNode, preceded by an EnterNode and followed by a ReturnNode,
-  // implements the body of a native Dart function. Let's take this native
-  // function as an example: int dec(int a, int b = 1) native;
-  // Since this function has an optional parameter, its prologue will copy
-  // incoming parameters to locals.
-  SequenceNode* node_seq = test->node_sequence();
-  const int num_fixed_params = 1;
-  const int num_opt_params = 1;
-  const int num_params = num_fixed_params + num_opt_params;
-  LocalScope* local_scope = node_seq->scope();
-  local_scope->InsertParameterAt(0, NewTestLocalVariable("a"));
-  local_scope->InsertParameterAt(1, NewTestLocalVariable("b"));
-  ASSERT(local_scope->num_variables() == num_params);
-  ZoneGrowableArray<const Instance*>* default_values =
-      new ZoneGrowableArray<const Instance*>(num_opt_params);
-  default_values->Add(&Smi::ZoneHandle(Smi::New(1)));  // b = 1.
-  test->set_default_parameter_values(default_values);
-  const Function& function = test->function();
-  function.set_is_native(true);
-  function.set_num_fixed_parameters(num_fixed_params);
-  function.SetNumOptionalParameters(num_opt_params, true);
-  const String& native_name =
-      String::ZoneHandle(Symbols::New("TestSmiSub"));
-  NativeFunction native_function =
-      reinterpret_cast<NativeFunction>(TestSmiSub);
-  node_seq->Add(
-      new ReturnNode(kPos,
-                     new NativeBodyNode(kPos,
-                                        function,
-                                        native_name,
-                                        native_function,
-                                        local_scope,
-                                        false /* not bootstrap native */)));
-}
-
-
-// Tested Dart code:
-//   return dec(5);
-CODEGEN_TEST2_GENERATE(StaticDecCallCodegen, function, test) {
-  SequenceNode* node_seq = test->node_sequence();
-  ArgumentListNode* arguments = new ArgumentListNode(kPos);
-  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(5))));
-  node_seq->Add(new ReturnNode(kPos,
-                               new StaticCallNode(kPos, function, arguments)));
-}
-CODEGEN_TEST2_RUN(StaticDecCallCodegen, NativeDecCodegen, Smi::New(4))
-
-
 CODEGEN_TEST_GENERATE(SmiUnaryOpCodegen, test) {
   SequenceNode* node_seq = test->node_sequence();
   LiteralNode* a = new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(12)));
@@ -368,159 +316,6 @@
 CODEGEN_TEST_RUN(InstanceCallCodegen, Smi::New(42))
 
 
-// Tested Dart code:
-//   int sum(int a, int b,
-//           [int c = 10, int d = 21, int e = -32]) native: "TestSmiSum";
-// The native entry TestSmiSum implements sum natively.
-CODEGEN_TEST_GENERATE(NativeSumCodegen, test) {
-  SequenceNode* node_seq = test->node_sequence();
-  const int num_fixed_params = 2;
-  const int num_opt_params = 3;
-  const int num_params = num_fixed_params + num_opt_params;
-  LocalScope* local_scope = node_seq->scope();
-  local_scope->InsertParameterAt(0, NewTestLocalVariable("a"));
-  local_scope->InsertParameterAt(1, NewTestLocalVariable("b"));
-  local_scope->InsertParameterAt(2, NewTestLocalVariable("c"));
-  local_scope->InsertParameterAt(3, NewTestLocalVariable("d"));
-  local_scope->InsertParameterAt(4, NewTestLocalVariable("e"));
-  ASSERT(local_scope->num_variables() == num_params);
-  ZoneGrowableArray<const Instance*>* default_values =
-      new ZoneGrowableArray<const Instance*>(num_opt_params);
-  default_values->Add(&Smi::ZoneHandle(Smi::New(10)));
-  default_values->Add(&Smi::ZoneHandle(Smi::New(21)));
-  default_values->Add(&Smi::ZoneHandle(Smi::New(-32)));
-  test->set_default_parameter_values(default_values);
-  const Function& function = test->function();
-  function.set_is_native(true);
-  function.set_num_fixed_parameters(num_fixed_params);
-  function.SetNumOptionalParameters(num_opt_params, true);
-  function.set_parameter_types(Array::Handle(Array::New(num_params)));
-  function.set_parameter_names(Array::Handle(Array::New(num_params)));
-  const Type& param_type = Type::Handle(Type::DynamicType());
-  for (int i = 0; i < num_params; i++) {
-    function.SetParameterTypeAt(i, param_type);
-  }
-  const String& native_name =
-      String::ZoneHandle(Symbols::New("TestSmiSum"));
-  NativeFunction native_function =
-      reinterpret_cast<NativeFunction>(TestSmiSum);
-  node_seq->Add(
-      new ReturnNode(kPos,
-                     new NativeBodyNode(kPos,
-                                        function,
-                                        native_name,
-                                        native_function,
-                                        local_scope,
-                                        false /* Not bootstrap native */)));
-}
-
-
-// Tested Dart code, calling function sum declared above:
-//   return sum(1, 3);
-// Optional arguments are not passed and hence are set to their default values.
-CODEGEN_TEST2_GENERATE(StaticSumCallNoOptCodegen, function, test) {
-  SequenceNode* node_seq = test->node_sequence();
-  ArgumentListNode* arguments = new ArgumentListNode(kPos);
-  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(1))));
-  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(3))));
-  node_seq->Add(new ReturnNode(kPos,
-                               new StaticCallNode(kPos, function, arguments)));
-}
-CODEGEN_TEST2_RUN(StaticSumCallNoOptCodegen,
-                  NativeSumCodegen,
-                  Smi::New(1 + 3 + 10 + 21 - 32))
-
-
-// Tested Dart code, calling function sum declared above:
-//   return sum(1, 3, 5);
-// Only one out of three optional arguments is passed in; the second and third
-// arguments are hence set to their default values.
-CODEGEN_TEST2_GENERATE(StaticSumCallOneOptCodegen, function, test) {
-  SequenceNode* node_seq = test->node_sequence();
-  ArgumentListNode* arguments = new ArgumentListNode(kPos);
-  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(1))));
-  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(3))));
-  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(5))));
-  node_seq->Add(new ReturnNode(kPos,
-                               new StaticCallNode(kPos, function, arguments)));
-}
-CODEGEN_TEST2_RUN(StaticSumCallOneOptCodegen,
-                  NativeSumCodegen,
-                  Smi::New(1 + 3 + 5 + 21 - 32))
-
-
-// Tested Dart code, calling function sum declared above:
-//   return sum(0, 1, 1, 2, 3);
-// Optional arguments are passed in.
-CODEGEN_TEST2_GENERATE(StaticSumCallTenFiboCodegen, function, test) {
-  SequenceNode* node_seq = test->node_sequence();
-  ArgumentListNode* arguments = new ArgumentListNode(kPos);
-  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(0))));
-  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(1))));
-  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(1))));
-  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(2))));
-  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(3))));
-  node_seq->Add(new ReturnNode(kPos,
-                               new StaticCallNode(kPos, function, arguments)));
-}
-CODEGEN_TEST2_RUN(
-    StaticSumCallTenFiboCodegen,
-    NativeSumCodegen,
-    Smi::New(0 + 1 + 1 + 2 + 3))
-
-
-// Tested Dart code:
-//   int sum(a, b, c) native: "TestNonNullSmiSum";
-// The native entry TestNonNullSmiSum implements sum natively.
-CODEGEN_TEST_GENERATE(NativeNonNullSumCodegen, test) {
-  SequenceNode* node_seq = test->node_sequence();
-  const int num_params = 3;
-  LocalScope* local_scope = node_seq->scope();
-  local_scope->InsertParameterAt(0, NewTestLocalVariable("a"));
-  local_scope->InsertParameterAt(1, NewTestLocalVariable("b"));
-  local_scope->InsertParameterAt(2, NewTestLocalVariable("c"));
-  ASSERT(local_scope->num_variables() == num_params);
-  const Function& function = test->function();
-  function.set_is_native(true);
-  function.set_num_fixed_parameters(num_params);
-  ASSERT(!function.HasOptionalParameters());
-  function.set_parameter_types(Array::Handle(Array::New(num_params)));
-  function.set_parameter_names(Array::Handle(Array::New(num_params)));
-  const Type& param_type = Type::Handle(Type::DynamicType());
-  for (int i = 0; i < num_params; i++) {
-    function.SetParameterTypeAt(i, param_type);
-  }
-  const String& native_name =
-      String::ZoneHandle(Symbols::New("TestNonNullSmiSum"));
-  NativeFunction native_function =
-      reinterpret_cast<NativeFunction>(TestNonNullSmiSum);
-  node_seq->Add(
-      new ReturnNode(kPos,
-                     new NativeBodyNode(kPos,
-                                        function,
-                                        native_name,
-                                        native_function,
-                                        local_scope,
-                                        false /* Not bootstrap native */)));
-}
-
-
-// Tested Dart code, calling function sum declared above:
-//   return sum(1, null, 3);
-CODEGEN_TEST2_GENERATE(StaticNonNullSumCallCodegen, function, test) {
-  SequenceNode* node_seq = test->node_sequence();
-  ArgumentListNode* arguments = new ArgumentListNode(kPos);
-  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(1))));
-  arguments->Add(new LiteralNode(kPos, Instance::ZoneHandle()));
-  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(3))));
-  node_seq->Add(new ReturnNode(kPos,
-                               new StaticCallNode(kPos, function, arguments)));
-}
-CODEGEN_TEST2_RUN(StaticNonNullSumCallCodegen,
-                  NativeNonNullSumCodegen,
-                  Smi::New(1 + 3))
-
-
 // Test allocation of dart objects.
 CODEGEN_TEST_GENERATE(AllocateNewObjectCodegen, test) {
   const char* kScriptChars =
diff --git a/runtime/vm/code_patcher.h b/runtime/vm/code_patcher.h
index dc27168..ebcdeaa 100644
--- a/runtime/vm/code_patcher.h
+++ b/runtime/vm/code_patcher.h
@@ -74,6 +74,12 @@
                                      const Code& code,
                                      const Code& new_target);
 
+  static void PatchSwitchableCallAt(uword return_address,
+                                    const Code& code,
+                                    const ICData& ic_data,
+                                    const MegamorphicCache& new_cache,
+                                    const Code& lookup_stub);
+
   static RawCode* GetNativeCallAt(uword return_address,
                                   const Code& code,
                                   NativeFunction* target);
diff --git a/runtime/vm/code_patcher_arm.cc b/runtime/vm/code_patcher_arm.cc
index a9d5a10..7e0e8ea 100644
--- a/runtime/vm/code_patcher_arm.cc
+++ b/runtime/vm/code_patcher_arm.cc
@@ -69,6 +69,19 @@
 }
 
 
+void CodePatcher::PatchSwitchableCallAt(uword return_address,
+                                        const Code& code,
+                                        const ICData& ic_data,
+                                        const MegamorphicCache& cache,
+                                        const Code& lookup_stub) {
+  ASSERT(code.ContainsInstructionAt(return_address));
+  SwitchableCallPattern call(return_address, code);
+  ASSERT(call.cache() == ic_data.raw());
+  call.SetLookupStub(lookup_stub);
+  call.SetCache(cache);
+}
+
+
 void CodePatcher::PatchNativeCallAt(uword return_address,
                                     const Code& code,
                                     NativeFunction target,
diff --git a/runtime/vm/code_patcher_arm64.cc b/runtime/vm/code_patcher_arm64.cc
index 4e0bbee..53f26ed 100644
--- a/runtime/vm/code_patcher_arm64.cc
+++ b/runtime/vm/code_patcher_arm64.cc
@@ -109,6 +109,19 @@
 }
 
 
+void CodePatcher::PatchSwitchableCallAt(uword return_address,
+                                        const Code& code,
+                                        const ICData& ic_data,
+                                        const MegamorphicCache& cache,
+                                        const Code& lookup_stub) {
+  ASSERT(code.ContainsInstructionAt(return_address));
+  SwitchableCallPattern call(return_address, code);
+  ASSERT(call.cache() == ic_data.raw());
+  call.SetLookupStub(lookup_stub);
+  call.SetCache(cache);
+}
+
+
 void CodePatcher::PatchNativeCallAt(uword return_address,
                                     const Code& code,
                                     NativeFunction target,
diff --git a/runtime/vm/code_patcher_arm_test.cc b/runtime/vm/code_patcher_arm_test.cc
index 525b3db..f9a3f42 100644
--- a/runtime/vm/code_patcher_arm_test.cc
+++ b/runtime/vm/code_patcher_arm_test.cc
@@ -42,7 +42,7 @@
   // Code accessing pp is generated, but not executed. Uninitialized pp is OK.
   __ set_constant_pool_allowed(true);
 
-  __ LoadObject(R5, ic_data);
+  __ LoadObject(R9, ic_data);
   __ BranchLinkPatchable(*StubCode::OneArgCheckInlineCache_entry());
   __ Ret();
 }
diff --git a/runtime/vm/code_patcher_ia32.cc b/runtime/vm/code_patcher_ia32.cc
index d0a4f07..90f1876 100644
--- a/runtime/vm/code_patcher_ia32.cc
+++ b/runtime/vm/code_patcher_ia32.cc
@@ -211,6 +211,16 @@
 }
 
 
+void CodePatcher::PatchSwitchableCallAt(uword return_address,
+                                        const Code& code,
+                                        const ICData& ic_data,
+                                        const MegamorphicCache& cache,
+                                        const Code& lookup_stub) {
+  // Switchable instance calls only generated for precompilation.
+  UNREACHABLE();
+}
+
+
 void CodePatcher::PatchNativeCallAt(uword return_address,
                                     const Code& code,
                                     NativeFunction target,
diff --git a/runtime/vm/code_patcher_mips.cc b/runtime/vm/code_patcher_mips.cc
index 09b06a2..4c8ab99 100644
--- a/runtime/vm/code_patcher_mips.cc
+++ b/runtime/vm/code_patcher_mips.cc
@@ -68,6 +68,19 @@
 }
 
 
+void CodePatcher::PatchSwitchableCallAt(uword return_address,
+                                        const Code& code,
+                                        const ICData& ic_data,
+                                        const MegamorphicCache& cache,
+                                        const Code& lookup_stub) {
+  ASSERT(code.ContainsInstructionAt(return_address));
+  SwitchableCallPattern call(return_address, code);
+  ASSERT(call.cache() == ic_data.raw());
+  call.SetLookupStub(lookup_stub);
+  call.SetCache(cache);
+}
+
+
 void CodePatcher::PatchNativeCallAt(uword return_address,
                                     const Code& code,
                                     NativeFunction target,
diff --git a/runtime/vm/code_patcher_x64.cc b/runtime/vm/code_patcher_x64.cc
index d0ac739..2e6ec02 100644
--- a/runtime/vm/code_patcher_x64.cc
+++ b/runtime/vm/code_patcher_x64.cc
@@ -184,6 +184,64 @@
 };
 
 
+// Instance call that can switch from an IC call to a megamorphic call
+//   load ICData             load MegamorphicCache
+//   call ICLookup stub  ->  call MegamorphicLookup stub
+//   call target             call target
+class SwitchableCall : public ValueObject {
+ public:
+  SwitchableCall(uword return_address, const Code& code)
+      : start_(return_address - kCallPatternSize),
+        object_pool_(ObjectPool::Handle(code.GetObjectPool())) {
+    ASSERT(IsValid());
+  }
+
+  static const int kCallPatternSize = 24;
+
+  bool IsValid() const {
+    static int16_t pattern[kCallPatternSize] = {
+      0x49, 0x8b, 0x9f, -1, -1, -1, -1,  // movq rbx, [PP + cache_offs]
+      0x4d, 0x8b, 0xa7, -1, -1, -1, -1,  // movq r12, [PP + code_offs]
+      0x4d, 0x8b, 0x5c, 0x24, 0x07,      // movq r11, [r12 + entrypoint_off]
+      0x41, 0xff, 0xd3,                  // call r11
+      0xff, 0xd1,                        // call rcx
+    };
+    return MatchesPattern(start_, pattern, kCallPatternSize);
+  }
+
+  intptr_t cache_index() const {
+    return IndexFromPPLoad(start_ + 3);
+  }
+  intptr_t lookup_stub_index() const {
+    return IndexFromPPLoad(start_ + 10);
+  }
+
+  RawObject* cache() const {
+    return object_pool_.ObjectAt(cache_index());
+  }
+
+  void SetCache(const MegamorphicCache& cache) const {
+    ASSERT(Object::Handle(object_pool_.ObjectAt(cache_index())).IsICData());
+    object_pool_.SetObjectAt(cache_index(), cache);
+    // No need to flush the instruction cache, since the code is not modified.
+  }
+
+  void SetLookupStub(const Code& lookup_stub) const {
+    ASSERT(Object::Handle(object_pool_.ObjectAt(lookup_stub_index())).IsCode());
+    object_pool_.SetObjectAt(lookup_stub_index(), lookup_stub);
+    // No need to flush the instruction cache, since the code is not modified.
+  }
+
+ protected:
+  uword start_;
+  const ObjectPool& object_pool_;
+
+ private:
+  DISALLOW_IMPLICIT_CONSTRUCTORS(SwitchableCall);
+};
+
+
+
 RawCode* CodePatcher::GetStaticCallTargetAt(uword return_address,
                                             const Code& code) {
   ASSERT(code.ContainsInstructionAt(return_address));
@@ -248,6 +306,19 @@
 }
 
 
+void CodePatcher::PatchSwitchableCallAt(uword return_address,
+                                        const Code& code,
+                                        const ICData& ic_data,
+                                        const MegamorphicCache& cache,
+                                        const Code& lookup_stub) {
+  ASSERT(code.ContainsInstructionAt(return_address));
+  SwitchableCall call(return_address, code);
+  ASSERT(call.cache() == ic_data.raw());
+  call.SetLookupStub(lookup_stub);
+  call.SetCache(cache);
+}
+
+
 void CodePatcher::PatchNativeCallAt(uword return_address,
                                     const Code& code,
                                     NativeFunction target,
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 5d683ce..3ce52e1 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -35,6 +35,7 @@
 #include "vm/scanner.h"
 #include "vm/symbols.h"
 #include "vm/tags.h"
+#include "vm/thread_registry.h"
 #include "vm/timer.h"
 
 namespace dart {
@@ -63,6 +64,8 @@
 DEFINE_FLAG(bool, use_inlining, true, "Enable call-site inlining");
 DEFINE_FLAG(bool, verify_compiler, false,
     "Enable compiler verification assertions");
+DEFINE_FLAG(int, max_speculative_inlining_attempts, 1,
+    "Max number of attempts with speculative inlining (precompilation only)");
 
 DECLARE_FLAG(bool, background_compilation);
 DECLARE_FLAG(bool, load_deferred_eagerly);
@@ -184,6 +187,12 @@
 }
 
 
+bool Compiler::IsBackgroundCompilation() {
+  // For now: compilation in non mutator thread is the background compoilation.
+  return !Thread::Current()->IsMutatorThread();
+}
+
+
 RawError* Compiler::Compile(const Library& library, const Script& script) {
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
@@ -249,7 +258,7 @@
   // Add patch classes if they exist to the parse list if they have not already
   // been parsed and patched. Mark the class as parsed so that we don't
   // recursively add it back into the list.
-  parse_class ^= cls.patch_class();
+  parse_class ^= cls.GetPatchClass();
   if (!parse_class.IsNull()) {
     if (!parse_class.is_finalized() && !parse_class.is_marked_for_parsing()) {
       patch_list->Add(parse_class);
@@ -260,6 +269,7 @@
 
 
 RawError* Compiler::CompileClass(const Class& cls) {
+  ASSERT(Thread::Current()->IsMutatorThread());
   // If class is a top level class it is already parsed.
   if (cls.IsTopLevel()) {
     return Error::null();
@@ -378,6 +388,8 @@
 
 
 // Return false if bailed out.
+// If optimized_result_code is not NULL then it is caller's responsibility
+// to install code.
 static bool CompileParsedFunctionHelper(CompilationPipeline* pipeline,
                                         ParsedFunction* parsed_function,
                                         bool optimized,
@@ -393,6 +405,13 @@
   CSTAT_TIMER_SCOPE(thread, codegen_timer);
   HANDLESCOPE(thread);
 
+  // Get current generation count so that we can check and ensure that the code
+  // was not invalidated while we were compiling in the background.
+  uint32_t cha_invalidation_gen_at_start = isolate->cha_invalidation_gen();
+  uint32_t field_invalidation_gen_at_start = isolate->field_invalidation_gen();
+  uint32_t prefix_invalidation_gen_at_start =
+      isolate->prefix_invalidation_gen();
+
   // We may reattempt compilation if the function needs to be assembled using
   // far branches on ARM and MIPS. In the else branch of the setjmp call,
   // done is set to false, and use_far_branches is set to true if there is a
@@ -402,11 +421,15 @@
   bool done = false;
   // volatile because the variable may be clobbered by a longjmp.
   volatile bool use_far_branches = false;
+  volatile bool use_speculative_inlining = true;
+  GrowableArray<intptr_t> inlining_black_list;
+
   while (!done) {
     const intptr_t prev_deopt_id = thread->deopt_id();
     thread->set_deopt_id(0);
     LongJumpScope jump;
-    if (setjmp(*jump.Set()) == 0) {
+    const intptr_t val = setjmp(*jump.Set());
+    if (val == 0) {
       FlowGraph* flow_graph = NULL;
 
       // Class hierarchy analysis is registered with the isolate in the
@@ -424,7 +447,12 @@
           // builder uses it to attach it to nodes.
           ASSERT(function.deoptimization_counter() <
                  FLAG_deoptimization_counter_threshold);
-          function.RestoreICDataMap(ic_data_array);
+
+          // 'Freeze' ICData in background compilation so that it does not
+          // change while compiling.
+          const bool clone_descriptors = Compiler::IsBackgroundCompilation();
+          function.RestoreICDataMap(ic_data_array, clone_descriptors);
+
           if (FLAG_print_ic_data_map) {
             for (intptr_t i = 0; i < ic_data_array->length(); i++) {
               if ((*ic_data_array)[i] != NULL) {
@@ -447,7 +475,7 @@
           FlowGraphPrinter::ShouldPrint(function);
 
       if (print_flow_graph) {
-        if (osr_id == Thread::kNoDeoptId) {
+        if (osr_id == Compiler::kNoOSRDeoptId) {
           FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph);
         } else {
           FlowGraphPrinter::PrintGraph("For OSR", flow_graph);
@@ -485,9 +513,17 @@
         caller_inline_id.Add(-1);
         CSTAT_TIMER_SCOPE(thread, graphoptimizer_timer);
 
-        FlowGraphOptimizer optimizer(flow_graph);
+        FlowGraphOptimizer optimizer(flow_graph,
+                                     use_speculative_inlining,
+                                     &inlining_black_list);
         if (Compiler::always_optimize()) {
           optimizer.PopulateWithICData();
+
+          optimizer.ApplyClassIds();
+          DEBUG_ASSERT(flow_graph->VerifyUseLists());
+
+          FlowGraphTypePropagator::Propagate(flow_graph);
+          DEBUG_ASSERT(flow_graph->VerifyUseLists());
         }
         optimizer.ApplyICData();
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
@@ -589,10 +625,13 @@
         if (FLAG_common_subexpression_elimination) {
           if (DominatorBasedCSE::Optimize(flow_graph)) {
             DEBUG_ASSERT(flow_graph->VerifyUseLists());
+            optimizer.Canonicalize();
             // Do another round of CSE to take secondary effects into account:
             // e.g. when eliminating dependent loads (a.x[0] + a.x[0])
             // TODO(fschneider): Change to a one-pass optimization pass.
-            DominatorBasedCSE::Optimize(flow_graph);
+            if (DominatorBasedCSE::Optimize(flow_graph)) {
+              optimizer.Canonicalize();
+            }
             DEBUG_ASSERT(flow_graph->VerifyUseLists());
           }
         }
@@ -720,6 +759,16 @@
         pipeline->FinalizeCompilation();
       }
       {
+        // This part of compilation must be at a safepoint.
+        if (!Thread::Current()->IsMutatorThread()) {
+          // Stop mutator thread before creating the instruction object and
+          // installing code.
+          // Mutator thread may not run code while we are creating the
+          // instruction object, since the creation of instruction object
+          // changes code page access permissions (makes them temporary not
+          // executable).
+          isolate->thread_registry()->SafepointThreads();
+        }
         CSTAT_TIMER_SCOPE(thread, codefinalizer_timer);
         // CreateDeoptInfo uses the object pool and needs to be done before
         // FinalizeCode.
@@ -727,9 +776,12 @@
             Array::Handle(zone, graph_compiler.CreateDeoptInfo(&assembler));
         INC_STAT(thread, total_code_size,
                  deopt_info_array.Length() * sizeof(uword));
+        // Allocates instruction object. Since this occurs only at safepoint,
+        // there can be no concurrent access to the instruction page.
         const Code& code = Code::Handle(
             Code::FinalizeCode(function, &assembler, optimized));
         code.set_is_optimized(optimized);
+        code.set_owner(function);
 
         const Array& intervals = graph_compiler.inlined_code_intervals();
         INC_STAT(thread, total_code_size,
@@ -757,24 +809,70 @@
         graph_compiler.FinalizeStaticCallTargetsTable(code);
 
         if (optimized) {
-          // We may not have previous code if 'always_optimize' is set.
-          if ((osr_id == Thread::kNoDeoptId) && function.HasCode()) {
-            Code::Handle(function.CurrentCode()).DisableDartCode();
-          }
-          function.AttachCode(code);
-
-          // Register code with the classes it depends on because of CHA.
-          for (intptr_t i = 0;
-               i < thread->cha()->leaf_classes().length();
-               ++i) {
-            thread->cha()->leaf_classes()[i]->RegisterCHACode(code);
+          // Installs code while at safepoint.
+          if (thread->IsMutatorThread()) {
+            const bool is_osr = osr_id != Compiler::kNoOSRDeoptId;
+            function.InstallOptimizedCode(code, is_osr);
+          } else {
+            // Background compilation.
+            // Before installing code check generation counts if the code may
+            // have become invalid.
+            bool code_is_valid = true;
+            if (!thread->cha()->leaf_classes().is_empty()) {
+              if (cha_invalidation_gen_at_start !=
+                  isolate->cha_invalidation_gen()) {
+                code_is_valid = false;
+              }
+            }
+            if (!flow_graph->guarded_fields()->is_empty()) {
+              if (field_invalidation_gen_at_start !=
+                  isolate->field_invalidation_gen()) {
+                code_is_valid = false;
+              }
+            }
+            if (parsed_function->HasDeferredPrefixes()) {
+              if (prefix_invalidation_gen_at_start !=
+                  isolate->prefix_invalidation_gen()) {
+                code_is_valid = false;
+              }
+            }
+            if (code_is_valid) {
+              const bool is_osr = osr_id != Compiler::kNoOSRDeoptId;
+              ASSERT(!is_osr);  // OSR is compiled in background.
+              function.InstallOptimizedCode(code, is_osr);
+            }
+            if (function.usage_counter() < 0) {
+              // Reset to 0 so that it can be recompiled if needed.
+              function.set_usage_counter(0);
+            }
           }
 
-          for (intptr_t i = 0;
-               i < flow_graph->guarded_fields()->length();
-               i++) {
-            const Field* field = (*flow_graph->guarded_fields())[i];
-            field->RegisterDependentCode(code);
+          // Register code with the classes it depends on because of CHA and
+          // fields it depends on because of store guards, unless we cannot
+          // deopt.
+          if (Compiler::allow_recompilation()) {
+            // Deoptimize field dependent code first, before registering
+            // this yet uninstalled code as dependent on a field.
+            // TODO(srdjan): Debugging dart2js crashes;
+            // FlowGraphOptimizer::VisitStoreInstanceField populates
+            // deoptimize_dependent_code() list, currently disabled.
+            for (intptr_t i = 0;
+                 i < flow_graph->deoptimize_dependent_code().length();
+                 i++) {
+              const Field* field = flow_graph->deoptimize_dependent_code()[i];
+              field->DeoptimizeDependentCode();
+            }
+            for (intptr_t i = 0;
+                 i < thread->cha()->leaf_classes().length();
+                 ++i) {
+              thread->cha()->leaf_classes()[i]->RegisterCHACode(code);
+            }
+            for (intptr_t i = 0;
+                 i < flow_graph->guarded_fields()->length();
+                 i++) {
+              const Field* field = (*flow_graph->guarded_fields())[i];
+              field->RegisterDependentCode(code);
+            }
           }
         } else {  // not optimized.
           if (!Compiler::always_optimize() &&
@@ -794,6 +892,10 @@
             (*prefixes)[i]->RegisterDependentCode(code);
           }
         }
+        if (!Thread::Current()->IsMutatorThread()) {
+          // Background compilation.
+          isolate->thread_registry()->ResumeAllThreads();
+        }
       }
       // Mark that this isolate now has compiled code.
       isolate->set_has_compiled_code(true);
@@ -811,6 +913,26 @@
         done = false;
         ASSERT(!use_far_branches);
         use_far_branches = true;
+      } else if (error.raw() == Object::speculative_inlining_error().raw()) {
+        // The return value of setjmp is the deopt id of the check instruction
+        // that caused the bailout.
+        done = false;
+#if defined(DEBUG)
+        ASSERT(Compiler::always_optimize());
+        ASSERT(use_speculative_inlining);
+        for (intptr_t i = 0; i < inlining_black_list.length(); ++i) {
+          ASSERT(inlining_black_list[i] != val);
+        }
+#endif
+        inlining_black_list.Add(val);
+        const intptr_t max_attempts = FLAG_max_speculative_inlining_attempts;
+        if (inlining_black_list.length() >= max_attempts) {
+          use_speculative_inlining = false;
+          if (FLAG_trace_compiler) {
+            THR_Print("Disabled speculative inlining after %" Pd " attempts.\n",
+                      inlining_black_list.length());
+          }
+        }
       } else {
         // If the error isn't due to an out of range branch offset, we don't
         // try again (done = true), and indicate that we did not finish
@@ -819,7 +941,6 @@
           THR_Print("%s\n", error.ToErrorCString());
         }
         done = true;
-        ASSERT(optimized);
       }
 
       // Clear the error if it was not a real error, but just a bailout.
@@ -1019,7 +1140,7 @@
         thread, Function::ZoneHandle(zone, function.raw()));
     if (FLAG_trace_compiler) {
       THR_Print("Compiling %s%sfunction: '%s' @ token %" Pd ", size %" Pd "\n",
-                (osr_id == Thread::kNoDeoptId ? "" : "osr "),
+                (osr_id == Compiler::kNoOSRDeoptId ? "" : "osr "),
                 (optimized ? "optimized " : ""),
                 function.ToFullyQualifiedCString(),
                 function.token_pos(),
@@ -1056,8 +1177,14 @@
         }
         function.SetIsOptimizable(false);
         return Error::null();
+      } else {
+        // Encountered error.
+        Error& error = Error::Handle();
+        // We got an error during compilation.
+        error = isolate->object_store()->sticky_error();
+        isolate->object_store()->clear_sticky_error();
+        return error.raw();
       }
-      UNREACHABLE();
     }
 
     per_compile_timer.Stop();
@@ -1094,6 +1221,11 @@
     // We got an error during compilation.
     error = isolate->object_store()->sticky_error();
     isolate->object_store()->clear_sticky_error();
+    // Unoptimized compilation or precompilation may encounter compile-time
+    // errors, but regular optimized compilation should not.
+    ASSERT(!optimized || Compiler::always_optimize());
+    // Do not attempt to optimize functions that can cause errors.
+    function.set_is_optimizable(false);
     return error.raw();
   }
   UNREACHABLE();
@@ -1120,8 +1252,10 @@
   const bool optimized =
       Compiler::always_optimize() && function.IsOptimizable();
 
-  return CompileFunctionHelper(pipeline, function, optimized,
-      Thread::kNoDeoptId);
+  return CompileFunctionHelper(pipeline,
+                               function,
+                               optimized,
+                               kNoOSRDeoptId);
 }
 
 
@@ -1137,7 +1271,10 @@
   CompilationPipeline* pipeline =
       CompilationPipeline::New(thread->zone(), function);
   const Error& error = Error::Handle(
-      CompileFunctionHelper(pipeline, function, false, Thread::kNoDeoptId));
+      CompileFunctionHelper(pipeline,
+                            function,
+                            false,  /* not optimized */
+                            kNoOSRDeoptId));
   if (!error.IsNull()) {
     return error.raw();
   }
@@ -1163,12 +1300,15 @@
                                          "OptimizedFunction", function);
 
   // Optimization must happen in non-mutator/Dart thread if background
-  // compilation is on.
-  ASSERT(!FLAG_background_compilation ||
-         !thread->isolate()->MutatorThreadIsCurrentThread());
+  // compilation is on. OSR compilation still occurs in the main thread.
+  ASSERT((osr_id != kNoOSRDeoptId) || !FLAG_background_compilation ||
+         !thread->IsMutatorThread());
   CompilationPipeline* pipeline =
       CompilationPipeline::New(thread->zone(), function);
-  return CompileFunctionHelper(pipeline, function, true, osr_id);
+  return CompileFunctionHelper(pipeline,
+                               function,
+                               true,  /* optimized */
+                               osr_id);
 }
 
 
@@ -1182,7 +1322,7 @@
     CompileParsedFunctionHelper(&pipeline,
                                 parsed_function,
                                 false,
-                                Thread::kNoDeoptId);
+                                kNoOSRDeoptId);
     if (FLAG_disassemble) {
       DisassembleCode(parsed_function->function(), false);
     }
@@ -1247,22 +1387,22 @@
       func.ClearCode();
     }
   }
+
   // Inner functions get added to the closures array. As part of compilation
   // more closures can be added to the end of the array. Compile all the
   // closures until we have reached the end of the "worklist".
-  GrowableObjectArray& closures =
-      GrowableObjectArray::Handle(zone, cls.closures());
-  if (!closures.IsNull()) {
-    for (int i = 0; i < closures.Length(); i++) {
-      func ^= closures.At(i);
-      if (!func.HasCode()) {
-        error = CompileFunction(thread, func);
-        if (!error.IsNull()) {
-          return error.raw();
-        }
-        func.ClearICDataArray();
-        func.ClearCode();
+  const GrowableObjectArray& closures =
+      GrowableObjectArray::Handle(zone,
+          Isolate::Current()->object_store()->closure_functions());
+  for (int i = 0; i < closures.Length(); i++) {
+    func ^= closures.At(i);
+    if ((func.Owner() == cls.raw()) && !func.HasCode()) {
+      error = CompileFunction(thread, func);
+      if (!error.IsNull()) {
+        return error.raw();
       }
+      func.ClearICDataArray();
+      func.ClearCode();
     }
   }
   return error.raw();
@@ -1288,7 +1428,7 @@
   CompileParsedFunctionHelper(&pipeline,
                               parsed_function,
                               false,  // optimized
-                              Thread::kNoDeoptId);
+                              kNoOSRDeoptId);
 
   const Function& initializer = parsed_function->function();
   field.SetPrecompiledInitializer(initializer);
@@ -1319,7 +1459,7 @@
       CompileParsedFunctionHelper(&pipeline,
                                   parsed_function,
                                   false,  // optimized
-                                  Thread::kNoDeoptId);
+                                  kNoOSRDeoptId);
       initializer = parsed_function->function().raw();
       Code::Handle(initializer.unoptimized_code()).set_var_descriptors(
           Object::empty_var_descriptors());
@@ -1389,7 +1529,7 @@
     CompileParsedFunctionHelper(&pipeline,
                                 parsed_function,
                                 false,
-                                Thread::kNoDeoptId);
+                                kNoOSRDeoptId);
     Code::Handle(func.unoptimized_code()).set_var_descriptors(
         Object::empty_var_descriptors());
 
@@ -1409,85 +1549,160 @@
 }
 
 
-// A simple work queue containing functions to be optimized. Use
-// PushFront and PopBack to add and read from queue.
-// TODO(srdjan): Write a more efficient implementation.
-class CompilationWorkQueue : public ValueObject {
+// C-heap allocated background compilation queue element.
+class QueueElement {
  public:
-  explicit CompilationWorkQueue(Isolate* isolate) :
-      data_(GrowableObjectArray::Handle()) {
-    data_ = isolate->background_compilation_queue();
+  explicit QueueElement(const Function& function)
+      : next_(NULL),
+        function_(function.raw()) {
+    ASSERT(Thread::Current()->IsMutatorThread());
   }
 
-  intptr_t IsEmpty() const { return data_.Length() == 0; }
-
-  // Adds to the queue only if 'function' is not already in there.
-  void PushFront(const Function& function) {
-    for (intptr_t i = 0; i < data_.Length(); i++) {
-      if (data_.At(i) == function.raw()) {
-        return;
-      }
-    }
-    // Insert new element in front.
-    Object& f = Object::Handle();
-    data_.Add(f);
-    for (intptr_t i = data_.Length() - 1; i > 0; i--) {
-      f = data_.At(i - 1);
-      data_.SetAt(i, f);
-    }
-    data_.SetAt(0, function);
+  ~QueueElement() {
+    function_ = Function::null();
   }
 
-  RawFunction* PopBack() {
-    ASSERT(!IsEmpty());
-    Object& result = Object::Handle();
-    result = data_.At(data_.Length() - 1);
-    data_.SetLength(data_.Length() - 1);
-    return Function::Cast(result).raw();
+  RawFunction* Function() const { return function_; }
+
+
+  void set_next(QueueElement* elem) { next_ = elem; }
+  QueueElement* next() const { return next_; }
+
+  RawObject* function() const { return function_; }
+  RawObject** function_ptr() {
+    return reinterpret_cast<RawObject**>(&function_);
   }
 
  private:
-  GrowableObjectArray& data_;
+  QueueElement* next_;
+  RawFunction* function_;
 
-  DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationWorkQueue);
+  DISALLOW_COPY_AND_ASSIGN(QueueElement);
+};
+
+
+// Allocated in C-heap. Handles both input and output of background compilation.
+// It implements a FIFO queue, using Peek, Add, Remove operations.
+class BackgroundCompilationQueue {
+ public:
+  BackgroundCompilationQueue() : first_(NULL), last_(NULL) {}
+  ~BackgroundCompilationQueue() {
+    while (!IsEmpty()) {
+      QueueElement* e = Remove();
+      delete e;
+    }
+    ASSERT((first_ == NULL) && (last_ == NULL));
+  }
+
+  void VisitObjectPointers(ObjectPointerVisitor* visitor) {
+    ASSERT(visitor != NULL);
+    QueueElement* p = first_;
+    while (p != NULL) {
+      visitor->VisitPointer(p->function_ptr());
+      p = p->next();
+    }
+  }
+
+  bool IsEmpty() const { return first_ == NULL; }
+
+  void Add(QueueElement* value) {
+    ASSERT(value != NULL);
+    if (first_ == NULL) {
+      first_ = value;
+    } else {
+      last_->set_next(value);
+    }
+    value->set_next(NULL);
+    last_ = value;
+  }
+
+  QueueElement* Peek() const {
+    return first_;
+  }
+
+  RawFunction* PeekFunction() const {
+    QueueElement* e = Peek();
+    if (e == NULL) {
+      return Function::null();
+    } else {
+      return e->Function();
+    }
+  }
+
+  QueueElement* Remove() {
+    ASSERT(first_ != NULL);
+    QueueElement* result = first_;
+    first_ = first_->next();
+    if (first_ == NULL) {
+      last_ = NULL;
+    }
+    return result;
+  }
+
+  bool ContainsObj(const Object& obj) const {
+    QueueElement* p = first_;
+    while (p != NULL) {
+      if (p->function() == obj.raw()) {
+        return true;
+      }
+      p = p->next();
+    }
+    return false;
+  }
+
+ private:
+  QueueElement* first_;
+  QueueElement* last_;
+
+  DISALLOW_COPY_AND_ASSIGN(BackgroundCompilationQueue);
 };
 
 
 BackgroundCompiler::BackgroundCompiler(Isolate* isolate)
     : isolate_(isolate), running_(true), done_(new bool()),
-      monitor_(new Monitor()), done_monitor_(new Monitor())  {
+      queue_monitor_(new Monitor()), done_monitor_(new Monitor()),
+      function_queue_(new BackgroundCompilationQueue()) {
   *done_ = false;
 }
 
 
 void BackgroundCompiler::Run() {
   while (running_) {
-    {
-      // Wait to be notified when the work queue is not empty.
-      MonitorLocker ml(monitor_);
-      ml.Wait();
-    }
-
+    // Maybe something is already in the queue, check first before waiting
+    // to be notified.
     Thread::EnterIsolateAsHelper(isolate_);
     {
       Thread* thread = Thread::Current();
       StackZone stack_zone(thread);
+      Zone* zone = stack_zone.GetZone();
       HANDLESCOPE(thread);
-      Function& function = Function::Handle();
-      function = RemoveOrNull();
-      while (!function.IsNull()) {
-        const Error& error = Error::Handle(
-            Compiler::CompileOptimizedFunction(thread, function));
+      Function& function = Function::Handle(zone);
+      function = function_queue()->PeekFunction();
+      while (running_ && !function.IsNull()) {
+        const Error& error = Error::Handle(zone,
+            Compiler::CompileOptimizedFunction(thread,
+                                               function,
+                                               Compiler::kNoOSRDeoptId));
         // TODO(srdjan): We do not expect errors while compiling optimized
         // code, any errors should have been caught when compiling
-        // unoptimized code.
-        // If it still happens mark function as not optimizable.
+        // unoptimized code. Any issues while optimizing are flagged by
+        // making the result invalid.
         ASSERT(error.IsNull());
-        function = RemoveOrNull();
+        QueueElement* qelem = function_queue()->Remove();
+        delete qelem;
+        function = function_queue()->PeekFunction();
       }
     }
     Thread::ExitIsolateAsHelper();
-  }
+    {
+      // Wait to be notified when the work queue is not empty.
+      MonitorLocker ml(queue_monitor_);
+      while (function_queue()->IsEmpty() && running_) {
+        ml.Wait();
+      }
+    }
+  }  // while running
+
   {
     // Notify that the thread is done.
     MonitorLocker ml_done(done_monitor_);
@@ -1498,62 +1713,77 @@
 
 
 void BackgroundCompiler::CompileOptimized(const Function& function) {
-  Add(function);
-}
-
-
-void BackgroundCompiler::Add(const Function& f) const {
-  MonitorLocker ml(monitor_);
-  CompilationWorkQueue queue(isolate_);
-  queue.PushFront(f);
+  ASSERT(Thread::Current()->IsMutatorThread());
+  MonitorLocker ml(queue_monitor_);
+  if (function_queue()->ContainsObj(function)) {
+    return;
+  }
+  QueueElement* elem = new QueueElement(function);
+  function_queue()->Add(elem);
   ml.Notify();
 }
 
 
-RawFunction* BackgroundCompiler::RemoveOrNull() const {
-  MonitorLocker ml(monitor_);
-  CompilationWorkQueue queue(isolate_);
-  return queue.IsEmpty() ? Function::null() : queue.PopBack();
+void BackgroundCompiler::VisitPointers(ObjectPointerVisitor* visitor) {
+  function_queue_->VisitObjectPointers(visitor);
 }
 
 
 void BackgroundCompiler::Stop(BackgroundCompiler* task) {
+  ASSERT(Isolate::Current()->background_compiler() == task);
   if (task == NULL) {
     return;
   }
-  Monitor* monitor = task->monitor_;
+  BackgroundCompilationQueue* function_queue = task->function_queue();
+
+  Monitor* queue_monitor = task->queue_monitor_;
   Monitor* done_monitor = task->done_monitor_;
   bool* task_done = task->done_;
   // Wake up compiler task and stop it.
   {
-    MonitorLocker ml(task->monitor_);
+    MonitorLocker ml(task->queue_monitor_);
     task->running_ = false;
     // 'task' will be deleted by thread pool.
     task = NULL;
-    ml.Notify();
+    ml.Notify();   // Stop waiting for the queue.
   }
 
   {
     MonitorLocker ml_done(done_monitor);
     while (!(*task_done)) {
-      ml_done.Wait();
+      // In case that the compiler is waiting for safepoint.
+      Isolate::Current()->thread_registry()->CheckSafepoint();
+      ml_done.Wait(1);
     }
   }
   delete task_done;
   delete done_monitor;
-  delete monitor;
+  delete queue_monitor;
+  delete function_queue;
+  Isolate::Current()->set_background_compiler(NULL);
 }
 
 
-void BackgroundCompiler::EnsureInit(Isolate* isolate) {
+void BackgroundCompiler::EnsureInit(Thread* thread) {
+  ASSERT(thread->IsMutatorThread());
+  // Finalize NoSuchMethodError, _Mint; occasionally needed in optimized
+  // compilation.
+  Class& cls = Class::Handle(thread->zone(),
+      Library::LookupCoreClass(Symbols::NoSuchMethodError()));
+  Error& error = Error::Handle(thread->zone(),
+      cls.EnsureIsFinalized(thread));
+  ASSERT(error.IsNull());
+  cls = Library::LookupCoreClass(Symbols::_Mint());
+  error = cls.EnsureIsFinalized(thread);
+  ASSERT(error.IsNull());
+
   bool start_task = false;
+  Isolate* isolate = thread->isolate();
   {
     MutexLocker ml(isolate->mutex());
     if (isolate->background_compiler() == NULL) {
       BackgroundCompiler* task = new BackgroundCompiler(isolate);
       isolate->set_background_compiler(task);
-      isolate->set_background_compilation_queue(GrowableObjectArray::Handle(
-          isolate->current_zone(), GrowableObjectArray::New()));
       start_task = true;
     }
   }
diff --git a/runtime/vm/compiler.h b/runtime/vm/compiler.h
index 9c3e73f..130567d 100644
--- a/runtime/vm/compiler.h
+++ b/runtime/vm/compiler.h
@@ -13,16 +13,25 @@
 namespace dart {
 
 // Forward declarations.
+class BackgroundCompilationQueue;
 class Class;
+class Code;
+class CompilationWorkQueue;
 class Function;
 class Library;
 class ParsedFunction;
+class QueueElement;
 class RawInstance;
 class Script;
 class SequenceNode;
 
+
 class Compiler : public AllStatic {
  public:
+  static const intptr_t kNoOSRDeoptId = Thread::kNoDeoptId;
+
+  static bool IsBackgroundCompilation();
+
   // Extracts top level entities from the script and populates
   // the class dictionary of the library.
   //
@@ -47,10 +56,12 @@
   // Generates optimized code for function.
   //
   // Returns Error::null() if there is no compilation error.
+  // If 'result_code' is not NULL, then the generated code is returned but
+  // not installed.
   static RawError* CompileOptimizedFunction(
       Thread* thread,
       const Function& function,
-      intptr_t osr_id = Thread::kNoDeoptId);
+      intptr_t osr_id = kNoOSRDeoptId);
 
   // Generates code for given parsed function (without parsing it again) and
   // sets its code field.
@@ -104,27 +115,33 @@
 // Class to run optimizing compilation in a background thread.
 // Current implementation: one task per isolate, it dies with the owning
 // isolate.
+// No OSR compilation in the background compiler.
 class BackgroundCompiler : public ThreadPool::Task {
  public:
-  static void EnsureInit(Isolate* isolate);
+  static void EnsureInit(Thread* thread);
 
   static void Stop(BackgroundCompiler* task);
 
+  // Call to optimize a function in the background, enters the function in the
+  // compilation queue.
   void CompileOptimized(const Function& function);
 
+  void VisitPointers(ObjectPointerVisitor* visitor);
+
+  BackgroundCompilationQueue* function_queue() const { return function_queue_; }
+
  private:
   explicit BackgroundCompiler(Isolate* isolate);
 
   virtual void Run();
 
-  void Add(const Function& f) const;
-  RawFunction* RemoveOrNull() const;
-
   Isolate* isolate_;
-  bool running_;
-  bool* done_;
-  Monitor* monitor_;
-  Monitor* done_monitor_;
+  bool running_;       // While true, will try to read queue and compile.
+  bool* done_;         // True if the thread is done.
+  Monitor* queue_monitor_;  // Controls access to the queue.
+  Monitor* done_monitor_;   // Notify/wait that the thread is done.
+
+  BackgroundCompilationQueue* function_queue_;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(BackgroundCompiler);
 };
diff --git a/runtime/vm/compiler_stats.cc b/runtime/vm/compiler_stats.cc
index d3e4b02..d5b20f4 100644
--- a/runtime/vm/compiler_stats.cc
+++ b/runtime/vm/compiler_stats.cc
@@ -7,6 +7,7 @@
 #include "vm/flags.h"
 #include "vm/log.h"
 #include "vm/object_graph.h"
+#include "vm/object_store.h"
 #include "vm/timer.h"
 
 
@@ -37,11 +38,6 @@
       Token::Kind kind = tkit.CurrentTokenKind();
       while (kind != Token::kEOS) {
         ++stats_->num_tokens_total;
-        if (kind == Token::kIDENT) {
-          ++stats_->num_ident_tokens_total;
-        } else if (Token::NeedsLiteralToken(kind)) {
-          ++stats_->num_literal_tokens_total;
-        }
         tkit.Advance();
         kind = tkit.CurrentTokenKind();
       }
@@ -71,8 +67,6 @@
       graphcompiler_timer(true, "flow graph compiler timer"),
       codefinalizer_timer(true, "code finalization timer"),
       num_tokens_total(0),
-      num_literal_tokens_total(0),
-      num_ident_tokens_total(0),
       num_tokens_scanned(0),
       num_tokens_consumed(0),
       num_cached_consts(0),
@@ -117,8 +111,6 @@
   // Traverse the heap and compute number of tokens in all
   // TokenStream objects.
   num_tokens_total = 0;
-  num_literal_tokens_total = 0;
-  num_ident_tokens_total = 0;
   TokenStreamVisitor visitor(isolate_, this);
   isolate_->heap()->IterateObjects(&visitor);
   Dart::vm_isolate()->heap()->IterateObjects(&visitor);
@@ -199,11 +191,12 @@
   log.Print("==== Compiler Stats for isolate '%s' ====\n",
             isolate_->debugger_name());
   log.Print("Number of tokens:        %" Pd64 "\n", num_tokens_total);
-  log.Print("  Literal tokens:        %" Pd64 "\n", num_literal_tokens_total);
-  log.Print("  Ident tokens:          %" Pd64 "\n", num_ident_tokens_total);
   log.Print("Source length:           %" Pd64 " characters\n", src_length);
   log.Print("Number of source tokens: %" Pd64 "\n", num_tokens_scanned);
 
+  int64_t num_local_functions = GrowableObjectArray::Handle(
+      isolate_->object_store()->closure_functions()).Length();
+
   log.Print("==== Parser stats:\n");
   log.Print("Total tokens consumed:   %" Pd64 "\n", num_tokens_consumed);
   log.Print("Classes parsed:          %" Pd64 "\n", num_classes_parsed);
@@ -212,6 +205,7 @@
   log.Print("  Tokens consumed:       %" Pd64 "\n", num_func_tokens_compiled);
   log.Print("Impl getter funcs:       %" Pd64 "\n", num_implicit_final_getters);
   log.Print("Impl method extractors:  %" Pd64 "\n", num_method_extractors);
+  log.Print("Local functions:         %" Pd64 "\n", num_local_functions);
   log.Print("Consts cached:           %" Pd64 "\n", num_cached_consts);
   log.Print("Consts cache hits:       %" Pd64 "\n", num_const_cache_hits);
 
diff --git a/runtime/vm/compiler_stats.h b/runtime/vm/compiler_stats.h
index 4487991..296b2a4 100644
--- a/runtime/vm/compiler_stats.h
+++ b/runtime/vm/compiler_stats.h
@@ -41,8 +41,6 @@
   Timer codefinalizer_timer;   // Included in codegen_timer.
 
   int64_t num_tokens_total;    // Isolate + VM isolate
-  int64_t num_literal_tokens_total;
-  int64_t num_ident_tokens_total;
   int64_t num_tokens_scanned;
   int64_t num_tokens_consumed;
   int64_t num_cached_consts;
@@ -73,10 +71,11 @@
   char* PrintToZone();
 };
 
-// TODO(hausner): make the increment thread-safe.
 #define INC_STAT(thread, counter, incr)                                        \
   if (FLAG_compiler_stats) {                                                   \
-      (thread)->isolate()->compiler_stats()->counter += (incr); }
+    MutexLocker ml((thread)->isolate()->mutex());                              \
+    (thread)->isolate()->compiler_stats()->counter += (incr);                  \
+  }
 
 #define STAT_VALUE(thread, counter)                                            \
   ((FLAG_compiler_stats != false) ?                                            \
diff --git a/runtime/vm/compiler_test.cc b/runtime/vm/compiler_test.cc
index 19e4953..cab1593 100644
--- a/runtime/vm/compiler_test.cc
+++ b/runtime/vm/compiler_test.cc
@@ -10,10 +10,13 @@
 #include "vm/object.h"
 #include "vm/symbols.h"
 #include "vm/thread_pool.h"
+#include "vm/thread_registry.h"
 #include "vm/unit_test.h"
 
 namespace dart {
 
+DECLARE_FLAG(bool, background_compilation);
+
 TEST_CASE(CompileScript) {
   const char* kScriptChars =
       "class A {\n"
@@ -70,59 +73,7 @@
 }
 
 
-class CompileFunctionTask : public ThreadPool::Task {
- public:
-  CompileFunctionTask(Isolate* isolate,
-                      const Function& func,
-                      Monitor* done_monitor,
-                      bool* done)
-      : isolate_(isolate),
-        func_(func),
-        done_monitor_(done_monitor),
-        done_(done) {
-  }
-
-  virtual void Run() {
-    Thread::EnterIsolateAsHelper(isolate_);
-    {
-      Thread* thread = Thread::Current();
-      StackZone stack_zone(thread);
-      HANDLESCOPE(thread);
-      EXPECT(func_.HasCode());
-      EXPECT(!func_.HasOptimizedCode());
-      const Error& err =
-          Error::Handle(Compiler::CompileOptimizedFunction(thread, func_));
-      EXPECT(err.IsNull());
-      EXPECT(func_.HasOptimizedCode());
-    }
-    Thread::ExitIsolateAsHelper();
-    // Tell main thread that we are done.
-    {
-      MonitorLocker ml(done_monitor_);
-      ASSERT(!*done_);
-      *done_ = true;
-      ml.Notify();
-    }
-  }
-
- private:
-  Isolate* isolate_;
-  const Function& func_;
-  Monitor* done_monitor_;
-  bool* done_;
-};
-
-
 TEST_CASE(CompileFunctionOnHelperThread) {
-  Monitor done_monitor;
-  bool done = false;
-  Isolate* isolate = Thread::Current()->isolate();
-  // Flush store buffers, etc.
-  // TODO(koda): Currently, the GC only does this for the current thread, (i.e,
-  // the helper, in this test), but it should be done for all *threads*
-  // after/at safepointing.
-  Thread::PrepareForGC();
-
   // Create a simple function and compile it without optimization.
   const char* kScriptChars =
             "class A {\n"
@@ -147,19 +98,18 @@
   CompilerTest::TestCompileFunction(func);
   EXPECT(func.HasCode());
   EXPECT(!func.HasOptimizedCode());
-
-  // Now optimize it on a helper thread.
-  Dart::thread_pool()->Run(
-      new CompileFunctionTask(isolate, func, &done_monitor, &done));
-  {
-    // Manually wait.
-    // TODO(koda): Replace with execution of Dart and/or VM code when GC
-    // actually safepoints everything.
-    MonitorLocker ml(&done_monitor);
-    while (!done) {
-      ml.Wait();
-    }
+  FLAG_background_compilation = true;
+  BackgroundCompiler::EnsureInit(thread);
+  Isolate* isolate = thread->isolate();
+  ASSERT(isolate->background_compiler() != NULL);
+  isolate->background_compiler()->CompileOptimized(func);
+  Monitor* m = new Monitor();
+  MonitorLocker ml(m);
+  while (!func.HasOptimizedCode()) {
+    Isolate::Current()->thread_registry()->CheckSafepoint();
+    ml.Wait(1);
   }
+  BackgroundCompiler::Stop(isolate->background_compiler());
 }
 
 
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h
index 9bd7640..24110b4 100644
--- a/runtime/vm/constants_arm.h
+++ b/runtime/vm/constants_arm.h
@@ -26,31 +26,37 @@
 
 
 enum Register {
-  kNoRegister = -1,
-  kFirstFreeCpuRegister = 0,
   R0  =  0,
   R1  =  1,
   R2  =  2,
   R3  =  3,
   R4  =  4,
-  R5  =  5,
-  R6  =  6,
-  R7  =  7,
+  R5  =  5,  // PP
+  R6  =  6,  // CTX
+  R7  =  7,  // iOS FP
   R8  =  8,
   R9  =  9,
-  R10 = 10,
-  R11 = 11,
-  R12 = 12,
-  R13 = 13,
-  R14 = 14,
-  kLastFreeCpuRegister = 14,
-  R15 = 15,
-  FP  = R11,
+  R10 = 10,  // THR
+  R11 = 11,  // Linux FP
+  R12 = 12,  // IP aka TMP
+  R13 = 13,  // SP
+  R14 = 14,  // LR
+  R15 = 15,  // PC
+  kNumberOfCpuRegisters = 16,
+  kNoRegister = -1,  // Signals an illegal register.
+
+  // Aliases.
+#if defined(TARGET_OS_MACOS)
+  FP   = R7,
+  NOTFP = R11,
+#else
+  FP   = R11,
+  NOTFP = R7,
+#endif
   IP  = R12,
   SP  = R13,
   LR  = R14,
   PC  = R15,
-  kNumberOfCpuRegisters = 16,
 };
 
 
@@ -231,15 +237,15 @@
 // Register aliases.
 const Register TMP = IP;  // Used as scratch register by assembler.
 const Register TMP2 = kNoRegister;  // There is no second assembler temporary.
-const Register CTX = R10;  // Location of current context at method entry.
-const Register PP = R9;  // Caches object pool pointer in generated code.
+const Register CTX = R6;  // Location of current context at method entry.
+const Register PP = R5;  // Caches object pool pointer in generated code.
 const Register SPREG = SP;  // Stack pointer register.
 const Register FPREG = FP;  // Frame pointer register.
 const Register LRREG = LR;  // Link register.
-const Register ICREG = R5;  // IC data register.
+const Register ICREG = R9;  // IC data register.
 const Register ARGS_DESC_REG = R4;
-const Register CODE_REG = R10;
-const Register THR = R8;  // Caches current thread in generated code.
+const Register CODE_REG = R6;
+const Register THR = R10;  // Caches current thread in generated code.
 
 // R15 encodes APSR in the vmrs instruction.
 const Register APSR = R15;
@@ -261,24 +267,39 @@
 // C++ ABI call registers.
 const RegList kAbiArgumentCpuRegs =
     (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3);
+#if defined(TARGET_OS_MACOS)
+const RegList kAbiPreservedCpuRegs =
+    (1 << R4)  | (1 << R5) | (1 << R6) | (1 << R8) |
+    (1 << R10) | (1 << R11);
+const int kAbiPreservedCpuRegCount = 6;
+#else
 const RegList kAbiPreservedCpuRegs =
     (1 << R4) | (1 << R5) | (1 << R6) | (1 << R7) |
     (1 << R8) | (1 << R9) | (1 << R10);
 const int kAbiPreservedCpuRegCount = 7;
+#endif
 const QRegister kAbiFirstPreservedFpuReg = Q4;
 const QRegister kAbiLastPreservedFpuReg = Q7;
 const int kAbiPreservedFpuRegCount = 4;
 
+const RegList kReservedCpuRegisters =
+    (1 << SPREG) |
+    (1 << FPREG) |
+    (1 << TMP)   |
+    (1 << PP)    |
+    (1 << THR)   |
+    (1 << PC);
 // CPU registers available to Dart allocator.
 const RegList kDartAvailableCpuRegs =
-    (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3) |
-    (1 << R4) | (1 << R5) | (1 << R6) | (1 << R7) |
-    (1 << R8) | (1 << R14);
-
+    kAllCpuRegistersList & ~kReservedCpuRegisters;
 // Registers available to Dart that are not preserved by runtime calls.
 const RegList kDartVolatileCpuRegs =
     kDartAvailableCpuRegs & ~kAbiPreservedCpuRegs;
+#if defined(TARGET_OS_MACOS)
+const int kDartVolatileCpuRegCount = 6;
+#else
 const int kDartVolatileCpuRegCount = 5;
+#endif
 const QRegister kDartFirstVolatileFpuReg = Q0;
 const QRegister kDartLastVolatileFpuReg = Q3;
 const int kDartVolatileFpuRegCount = 4;
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h
index ab76fd1..b14ce55 100644
--- a/runtime/vm/constants_arm64.h
+++ b/runtime/vm/constants_arm64.h
@@ -10,7 +10,6 @@
 namespace dart {
 
 enum Register {
-  kFirstFreeCpuRegister = 0,
   R0  =  0,
   R1  =  1,
   R2  =  2,
@@ -29,16 +28,15 @@
   R15 = 15,
   R16 = 16,  // IP0 aka TMP
   R17 = 17,  // IP1 aka TMP2
-  R18 = 18,  // SP in Dart code.
-  R19 = 19,
-  R20 = 20,
+  R18 = 18,  // "platform register" on iOS.
+  R19 = 19,  // SP in Dart code.
+  R20 = 20,  // THR
   R21 = 21,
   R22 = 22,
   R23 = 23,
   R24 = 24,
   R25 = 25,
   R26 = 26,
-  kLastFreeCpuRegister = 26,
   R27 = 27,  // PP
   R28 = 28,  // CTX
   R29 = 29,  // FP
@@ -55,11 +53,12 @@
   // Aliases.
   IP0 = R16,
   IP1 = R17,
-  SP = R18,
+  SP = R19,
   FP = R29,
   LR = R30,
 };
 
+
 enum VRegister {
   V0  =  0,
   V1  =  1,
@@ -113,12 +112,13 @@
 const Register PP = R27;  // Caches object pool pointer in generated code.
 const Register CODE_REG = R24;
 const Register FPREG = FP;  // Frame pointer register.
-const Register SPREG = R18;  // Stack pointer register.
+const Register SPREG = R19;  // Stack pointer register.
 const Register LRREG = LR;  // Link register.
 const Register ICREG = R5;  // IC data register.
 const Register ARGS_DESC_REG = R4;  // Arguments descriptor register.
 const Register THR = R20;  // Caches current thread in generated code.
 
+
 // Exception object is passed in this register to the catch handlers when an
 // exception is thrown.
 const Register kExceptionObjectReg = R0;
@@ -143,25 +143,31 @@
     (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3) |
     (1 << R4) | (1 << R5) | (1 << R6) | (1 << R7);
 const RegList kAbiPreservedCpuRegs =
-    (1 << R19) | (1 << R20) | (1 << R21) | (1 << R22) |
-    (1 << R23) | (1 << R24) | (1 << R25) | (1 << R26) |
-    (1 << R27) | (1 << R28);
-const Register kAbiFirstPreservedCpuReg = R19;
+    (1 << R20) | (1 << R21) | (1 << R22) | (1 << R23) |
+    (1 << R24) | (1 << R25) | (1 << R26) | (1 << R27) |
+    (1 << R28);
+const Register kAbiFirstPreservedCpuReg = R20;
 const Register kAbiLastPreservedCpuReg = R28;
-const int kAbiPreservedCpuRegCount = 10;
+const int kAbiPreservedCpuRegCount = 9;
 const VRegister kAbiFirstPreservedFpuReg = V8;
 const VRegister kAbiLastPreservedFpuReg = V15;
 const int kAbiPreservedFpuRegCount = 8;
 
+const intptr_t kReservedCpuRegisters =
+    (1 << SPREG) |  // Dart SP
+    (1 << FPREG) |
+    (1 << TMP)   |
+    (1 << TMP2)  |
+    (1 << PP)    |
+    (1 << THR)   |
+    (1 << LR)    |
+    (1 << R31)   |  // C++ SP
+    (1 << CTX)   |
+    (1 << R18);     // iOS platform register.
+                    // TODO(rmacnak): Only reserve on Mac & iOS.
 // CPU registers available to Dart allocator.
 const RegList kDartAvailableCpuRegs =
-    (1 << R0)  | (1 << R1)  | (1 << R2)  | (1 << R3)  |
-    (1 << R4)  | (1 << R5)  | (1 << R6)  | (1 << R7)  |
-    (1 << R8)  | (1 << R9)  | (1 << R10) | (1 << R11) |
-    (1 << R12) | (1 << R13) | (1 << R14) | (1 << R15) |
-    (1 << R19) | (1 << R20) | (1 << R21) | (1 << R22) |
-    (1 << R23) | (1 << R24) | (1 << R25) | (1 << R26);
-
+    kAllCpuRegistersList & ~kReservedCpuRegisters;
 // Registers available to Dart that are not preserved by runtime calls.
 const RegList kDartVolatileCpuRegs =
     kDartAvailableCpuRegs & ~kAbiPreservedCpuRegs;
diff --git a/runtime/vm/constants_ia32.h b/runtime/vm/constants_ia32.h
index 0950639..466dd42 100644
--- a/runtime/vm/constants_ia32.h
+++ b/runtime/vm/constants_ia32.h
@@ -10,7 +10,6 @@
 namespace dart {
 
 enum Register {
-  kFirstFreeCpuRegister = 0,
   EAX = 0,
   ECX = 1,
   EDX = 2,
@@ -19,9 +18,8 @@
   EBP = 5,
   ESI = 6,
   EDI = 7,
-  kLastFreeCpuRegister = 7,
   kNumberOfCpuRegisters = 8,
-  kNoRegister = -1  // Signals an illegal register.
+  kNoRegister = -1,  // Signals an illegal register.
 };
 
 
@@ -71,6 +69,7 @@
 const Register ARGS_DESC_REG = EDX;  // Arguments descriptor register.
 const Register THR = ESI;  // Caches current thread in generated code.
 
+
 // Exception object is passed in this register to the catch handlers when an
 // exception is thrown.
 const Register kExceptionObjectReg = EAX;
@@ -80,6 +79,18 @@
 const Register kStackTraceObjectReg = EDX;
 
 
+typedef uint32_t RegList;
+const RegList kAllCpuRegistersList = 0xFF;
+
+const intptr_t kReservedCpuRegisters =
+    (1 << SPREG) |
+    (1 << FPREG) |
+    (1 << THR);
+// CPU registers available to Dart allocator.
+const RegList kDartAvailableCpuRegs =
+    kAllCpuRegistersList & ~kReservedCpuRegisters;
+
+
 enum ScaleFactor {
   TIMES_1 = 0,
   TIMES_2 = 1,
diff --git a/runtime/vm/constants_mips.h b/runtime/vm/constants_mips.h
index fed178f..ccf437a 100644
--- a/runtime/vm/constants_mips.h
+++ b/runtime/vm/constants_mips.h
@@ -11,8 +11,7 @@
 
 enum Register {
   R0  =  0,
-  R1  =  1,
-  kFirstFreeCpuRegister = 2,
+  R1  =  1,  // AT aka TMP
   R2  =  2,
   R3  =  3,
   R4  =  4,
@@ -30,23 +29,23 @@
   R16 = 16,
   R17 = 17,
   R18 = 18,
-  R19 = 19,
+  R19 = 19,  // THR
   R20 = 20,
   R21 = 21,
-  kLastFreeCpuRegister = 21,
-  R22 = 22,
-  R23 = 23,
+  R22 = 22,  // CTX
+  R23 = 23,  // PP
   R24 = 24,
   R25 = 25,
   R26 = 26,
   R27 = 27,
   R28 = 28,
-  R29 = 29,
-  R30 = 30,
-  R31 = 31,
+  R29 = 29,  // SP
+  R30 = 30,  // FP
+  R31 = 31,  // RA
   kNumberOfCpuRegisters = 32,
   IMM = 32,  // Positive value is easier to encode than kNoRegister in bitfield.
-  kNoRegister = -1,
+  kNoRegister = -1,  // Signals an illegal register.
+
 
   // Register aliases.
   ZR = R0,
@@ -188,6 +187,7 @@
 const Register ARGS_DESC_REG = S4;
 const Register THR = S3;  // Caches current thread in generated code.
 
+
 // The code that generates a comparison can be far away from the code that
 // generates the branch that uses the result of that comparison. In this case,
 // CMPRES1 and CMPRES2 are used for the results of the comparison. We need two
@@ -207,7 +207,6 @@
 typedef uint32_t RegList;
 const RegList kAllCpuRegistersList = 0xFFFFFFFF;
 
-
 const RegList kAbiArgumentCpuRegs =
     (1 << A0) | (1 << A1) | (1 << A2) | (1 << A3);
 const RegList kAbiPreservedCpuRegs =
@@ -221,13 +220,24 @@
     static_cast<FRegister>(kNumberOfFRegisters - 1);
 const int kAbiPreservedFpuRegCount = 12;
 
+const RegList kReservedCpuRegisters =
+    (1 << SPREG)   |
+    (1 << FPREG)   |
+    (1 << TMP)     |
+    (1 << PP)      |
+    (1 << THR)     |
+    (1 << CTX)     |
+    (1 << ZR)      |
+    (1 << CMPRES1) |
+    (1 << CMPRES2) |
+    (1 << K0)      |
+    (1 << K1)      |
+    (1 << GP)      |
+    (1 << RA);
 // CPU registers available to Dart allocator.
 const RegList kDartAvailableCpuRegs =
-    (1 << R2) | (1 << R3) | (1 << R4) | (1 << R5) |
-    (1 << R6) | (1 << R7) | (1 << R8) | (1 << R9) |
-    (1 << R10) | (1 << R11) | (1 << R12) | (1 << R13) |
-    (1 << R14) | (1 << R15) | (1 << R16) | (1 << R17) |
-    (1 << R18) | (1 << R19) | (1 << R20) | (1 << R21);
+    kAllCpuRegistersList & ~kReservedCpuRegisters;
+// Registers available to Dart that are not preserved by runtime calls.
 const RegList kDartVolatileCpuRegs =
     kDartAvailableCpuRegs & ~kAbiPreservedCpuRegs;
 const int kDartVolatileCpuRegCount = 14;
@@ -429,6 +439,7 @@
   COP1_DIV = 0x03,
   COP1_SQRT = 0x04,
   COP1_MOV = 0x06,
+  COP1_NEG = 0x07,
   COP1_CVT_S = 0x20,
   COP1_CVT_D = 0x21,
   COP1_CVT_W = 0x24,
diff --git a/runtime/vm/constants_x64.h b/runtime/vm/constants_x64.h
index c2b48c5..9c92faa 100644
--- a/runtime/vm/constants_x64.h
+++ b/runtime/vm/constants_x64.h
@@ -8,7 +8,6 @@
 namespace dart {
 
 enum Register {
-  kFirstFreeCpuRegister = 0,
   RAX = 0,
   RCX = 1,
   RDX = 2,
@@ -25,9 +24,8 @@
   R13 = 13,
   R14 = 14,
   R15 = 15,
-  kLastFreeCpuRegister = 15,
   kNumberOfCpuRegisters = 16,
-  kNoRegister = -1  // Signals an illegal register.
+  kNoRegister = -1,  // Signals an illegal register.
 };
 
 
@@ -96,6 +94,7 @@
 const Register CODE_REG = R12;
 const Register THR = R14;  // Caches current thread in generated code.
 
+
 // Exception object is passed in this register to the catch handlers when an
 // exception is thrown.
 const Register kExceptionObjectReg = RAX;
@@ -105,6 +104,20 @@
 const Register kStackTraceObjectReg = RDX;
 
 
+typedef uint32_t RegList;
+const RegList kAllCpuRegistersList = 0xFFFF;
+
+const RegList kReservedCpuRegisters =
+    (1 << SPREG) |
+    (1 << FPREG) |
+    (1 << TMP)   |
+    (1 << PP)    |
+    (1 << THR);
+// CPU registers available to Dart allocator.
+const RegList kDartAvailableCpuRegs =
+    kAllCpuRegistersList & ~kReservedCpuRegisters;
+
+
 enum ScaleFactor {
   TIMES_1 = 0,
   TIMES_2 = 1,
diff --git a/runtime/vm/coverage.cc b/runtime/vm/coverage.cc
index 73fb5b6..8fede58 100644
--- a/runtime/vm/coverage.cc
+++ b/runtime/vm/coverage.cc
@@ -83,7 +83,7 @@
   // Print the hit counts for all IC datas.
   ZoneGrowableArray<const ICData*>* ic_data_array =
       new(zone) ZoneGrowableArray<const ICData*>();
-  function.RestoreICDataMap(ic_data_array);
+  function.RestoreICDataMap(ic_data_array, false /* clone descriptors */);
   const PcDescriptors& descriptors = PcDescriptors::Handle(
       zone, code.pc_descriptors());
 
@@ -191,41 +191,43 @@
     }
   }
 
-  GrowableObjectArray& closures =
-      GrowableObjectArray::Handle(cls.closures());
-  if (!closures.IsNull()) {
-    i = 0;
-    pos_to_line.Clear();
-    // We need to keep rechecking the length of the closures array, as handling
-    // a closure potentially adds new entries to the end.
+  const GrowableObjectArray& closures = GrowableObjectArray::Handle(
+      thread->isolate()->object_store()->closure_functions());
+  pos_to_line.Clear();
+  // We need to keep rechecking the length of the closures array, as handling
+  // a closure potentially adds new entries to the end.
+  i = 0;
+  while (i < closures.Length()) {
+    HANDLESCOPE(thread);
+    function ^= closures.At(i);
+    if (function.Owner() != cls.raw()) {
+      i++;
+      continue;
+    }
+    script = function.script();
+    saved_url = script.url();
+    if (!filter->ShouldOutputCoverageFor(lib, script, cls, function)) {
+      i++;
+      continue;
+    }
+    ComputeTokenPosToLineNumberMap(script, &pos_to_line);
+    JSONObject jsobj(&jsarr);
+    jsobj.AddProperty("source", saved_url.ToCString());
+    jsobj.AddProperty("script", script);
+    JSONArray hits_or_sites(&jsobj, as_call_sites ? "callSites" : "hits");
+
+    // We stay within this loop while we are seeing functions from the same
+    // source URI.
     while (i < closures.Length()) {
-      HANDLESCOPE(thread);
       function ^= closures.At(i);
       script = function.script();
-      saved_url = script.url();
-      if (!filter->ShouldOutputCoverageFor(lib, script, cls, function)) {
-        i++;
-        continue;
+      url = script.url();
+      if (!url.Equals(saved_url)) {
+        pos_to_line.Clear();
+        break;
       }
-      ComputeTokenPosToLineNumberMap(script, &pos_to_line);
-      JSONObject jsobj(&jsarr);
-      jsobj.AddProperty("source", saved_url.ToCString());
-      jsobj.AddProperty("script", script);
-      JSONArray hits_or_sites(&jsobj, as_call_sites ? "callSites" : "hits");
-
-      // We stay within this loop while we are seeing functions from the same
-      // source URI.
-      while (i < closures.Length()) {
-        function ^= closures.At(i);
-        script = function.script();
-        url = script.url();
-        if (!url.Equals(saved_url)) {
-          pos_to_line.Clear();
-          break;
-        }
-        CompileAndAdd(function, hits_or_sites, pos_to_line, as_call_sites);
-        i++;
-      }
+      CompileAndAdd(function, hits_or_sites, pos_to_line, as_call_sites);
+      i++;
     }
   }
 }
diff --git a/runtime/vm/cpu_arm.cc b/runtime/vm/cpu_arm.cc
index 44964d2..491468a 100644
--- a/runtime/vm/cpu_arm.cc
+++ b/runtime/vm/cpu_arm.cc
@@ -78,7 +78,12 @@
 #endif
 
 void CPU::FlushICache(uword start, uword size) {
-#if !defined(USING_SIMULATOR)
+#if TARGET_OS_IOS
+  // Precompilation never patches code so there should be no I cache flushes.
+  UNREACHABLE();
+#endif
+
+#if !defined(USING_SIMULATOR) && !TARGET_OS_IOS
   // Nothing to do. Flushing no instructions.
   if (size == 0) {
     return;
@@ -123,6 +128,25 @@
 
 
 #if !defined(USING_SIMULATOR)
+#if TARGET_OS_IOS
+void HostCPUFeatures::InitOnce() {
+  // TODO(24743): Actually check the CPU features and fail if we're missing
+  // something assumed in a precompiled snapshot.
+  hardware_ = "";
+  // When the VM is targetted to ARMv7, pretend that the CPU is ARMv7 even if
+  // the CPU is actually AArch64.
+  arm_version_ = ARMv7;
+  // Always assume we have floating point unit since we dont support ARMv6 in
+  // this path.
+  vfp_supported_ = FLAG_use_vfp;
+  integer_division_supported_ = FLAG_use_integer_division;
+  neon_supported_ = FLAG_use_neon;
+  hardfp_supported_ = true;
+#if defined(DEBUG)
+  initialized_ = true;
+#endif
+}
+#else  // TARGET_OS_IOS
 void HostCPUFeatures::InitOnce() {
   bool is_arm64 = false;
   CpuInfo::InitOnce();
@@ -197,7 +221,7 @@
   initialized_ = true;
 #endif
 }
-
+#endif  // TARGET_OS_IOS
 
 void HostCPUFeatures::Cleanup() {
   DEBUG_ASSERT(initialized_);
diff --git a/runtime/vm/cpu_arm64.cc b/runtime/vm/cpu_arm64.cc
index d9ec03b..881aebc 100644
--- a/runtime/vm/cpu_arm64.cc
+++ b/runtime/vm/cpu_arm64.cc
@@ -18,7 +18,12 @@
 namespace dart {
 
 void CPU::FlushICache(uword start, uword size) {
-#if !defined(USING_SIMULATOR)
+#if TARGET_OS_IOS
+  // Precompilation never patches code so there should be no I cache flushes.
+  UNREACHABLE();
+#endif
+
+#if !defined(USING_SIMULATOR) && !TARGET_OS_IOS
   // Nothing to do. Flushing no instructions.
   if (size == 0) {
     return;
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 8ed714a..14ff0e7 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -80,7 +80,8 @@
                            Dart_FileReadCallback file_read,
                            Dart_FileWriteCallback file_write,
                            Dart_FileCloseCallback file_close,
-                           Dart_EntropySource entropy_source) {
+                           Dart_EntropySource entropy_source,
+                           Dart_GetVMServiceAssetsArchive get_service_assets) {
   // TODO(iposva): Fix race condition here.
   if (vm_isolate_ != NULL || !Flags::Initialized()) {
     return "VM already initialized or flags not initialized.";
@@ -92,6 +93,8 @@
   Thread::InitOnceBeforeIsolate();
   Thread::EnsureInit();
   Timeline::InitOnce();
+  Thread* thread = Thread::Current();
+  thread->set_name("Dart_Initialize");
   TimelineDurationScope tds(Timeline::GetVMStream(),
                             "Dart::InitOnce");
   Isolate::InitOnce();
@@ -141,6 +144,7 @@
     TargetCPUFeatures::InitOnce();
     Object::InitOnce(vm_isolate_);
     ArgumentsDescriptor::InitOnce();
+    ICData::InitOnce();
     // When precompiled the stub code is initialized from the snapshot.
     if (!precompiled) {
       StubCode::InitOnce();
@@ -177,8 +181,6 @@
       Symbols::InitOnce(vm_isolate_);
     }
     Thread::InitOnceAfterObjectAndStubCode();
-    // Now that the needed stub has been generated, set the stack limit.
-    vm_isolate_->InitializeStackLimit();
     Scanner::InitOnce();
 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
     // Dart VM requires at least SSE2.
@@ -201,6 +203,7 @@
   Isolate::SetUnhandledExceptionCallback(unhandled);
   Isolate::SetShutdownCallback(shutdown);
 
+  Service::SetGetServiceAssetsCallback(get_service_assets);
   ServiceIsolate::Run();
 
   return NULL;
@@ -295,9 +298,6 @@
     ObjectStore::Init(I);
   }
 
-  // Setup for profiling.
-  Profiler::InitProfilingForIsolate(I);
-
   const Error& error = Error::Handle(Object::Init(I));
   if (!error.IsNull()) {
     return error.raw();
@@ -352,6 +352,10 @@
   if (!Dart::IsRunningPrecompiledCode()) {
     MegamorphicCacheTable::InitMissHandler(I);
   }
+  const Code& miss_code =
+      Code::Handle(I->object_store()->megamorphic_miss_code());
+  I->set_ic_miss_code(miss_code);
+
   if (snapshot_buffer == NULL) {
     if (!I->object_store()->PreallocateObjects()) {
       return I->object_store()->sticky_error();
@@ -395,6 +399,17 @@
 }
 
 
+void Dart::ShutdownIsolate(Isolate* isolate) {
+  ASSERT(Isolate::Current() == NULL);
+  // We need to enter the isolate in order to shut it down.
+  Thread::EnterIsolate(isolate);
+  ShutdownIsolate();
+  // Since the isolate is shutdown and deleted, there is no need to
+  // exit the isolate here.
+  ASSERT(Isolate::Current() == NULL);
+}
+
+
 void Dart::ShutdownIsolate() {
   Isolate* isolate = Isolate::Current();
   isolate->Shutdown();
diff --git a/runtime/vm/dart.h b/runtime/vm/dart.h
index 5ae0550..3eded72 100644
--- a/runtime/vm/dart.h
+++ b/runtime/vm/dart.h
@@ -31,13 +31,15 @@
       Dart_FileReadCallback file_read,
       Dart_FileWriteCallback file_write,
       Dart_FileCloseCallback file_close,
-      Dart_EntropySource entropy_source);
+      Dart_EntropySource entropy_source,
+      Dart_GetVMServiceAssetsArchive get_service_assets);
   static const char* Cleanup();
 
   static Isolate* CreateIsolate(const char* name_prefix,
                                 const Dart_IsolateFlags& api_flags);
   static RawError* InitializeIsolate(const uint8_t* snapshot, void* data);
   static void RunShutdownCallback();
+  static void ShutdownIsolate(Isolate* isolate);
   static void ShutdownIsolate();
 
   static Isolate* vm_isolate() { return vm_isolate_; }
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 55a352f..7f71986 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -52,6 +52,7 @@
 
 
 DECLARE_FLAG(bool, load_deferred_eagerly);
+DECLARE_FLAG(bool, precompilation);
 DECLARE_FLAG(bool, print_class_table);
 DECLARE_FLAG(bool, verify_handles);
 #if defined(DART_NO_SNAPSHOT)
@@ -381,6 +382,7 @@
 
 RawObject* Api::UnwrapHandle(Dart_Handle object) {
 #if defined(DEBUG)
+  ASSERT(Thread::Current()->IsMutatorThread());
   Isolate* isolate = Isolate::Current();
   ASSERT(isolate != NULL);
   ApiState* state = isolate->api_state();
@@ -853,7 +855,7 @@
           CURRENT_FUNC);
     }
   }
-  if (isolate->top_exit_frame_info() == 0) {
+  if (thread->top_exit_frame_info() == 0) {
     // There are no dart frames on the stack so it would be illegal to
     // propagate an error here.
     return Api::NewError("No Dart frames on stack, cannot propagate error.");
@@ -870,7 +872,7 @@
     // handle for it in the surviving zone.
     NoSafepointScope no_safepoint;
     RawError* raw_error = Api::UnwrapErrorHandle(thread->zone(), handle).raw();
-    state->UnwindScopes(isolate->top_exit_frame_info());
+    state->UnwindScopes(thread->top_exit_frame_info());
     // Note that thread's zone is different here than at the beginning of this
     // function.
     error = &Error::Handle(thread->zone(), raw_error);
@@ -1279,12 +1281,17 @@
     Dart_FileReadCallback file_read,
     Dart_FileWriteCallback file_write,
     Dart_FileCloseCallback file_close,
-    Dart_EntropySource entropy_source) {
+    Dart_EntropySource entropy_source,
+    Dart_GetVMServiceAssetsArchive get_service_assets) {
+  if ((instructions_snapshot != NULL) && !FLAG_precompilation) {
+    return strdup("Flag --precompilation was not specified.");
+  }
   const char* err_msg = Dart::InitOnce(vm_isolate_snapshot,
                                        instructions_snapshot,
                                        create, interrupt, unhandled, shutdown,
                                        file_open, file_read, file_write,
-                                       file_close, entropy_source);
+                                       file_close, entropy_source,
+                                       get_service_assets);
   if (err_msg != NULL) {
     return strdup(err_msg);
   }
@@ -1457,25 +1464,21 @@
 }
 
 
-DART_EXPORT void Dart_IsolateBlocked() {
-  Isolate* isolate = Isolate::Current();
-  CHECK_ISOLATE(isolate);
-  IsolateProfilerData* profiler_data = isolate->profiler_data();
-  if (profiler_data == NULL) {
+DART_EXPORT void Dart_ThreadDisableProfiling() {
+  Thread* T = Thread::Current();
+  if (T == NULL) {
     return;
   }
-  profiler_data->Block();
+  T->DisableThreadInterrupts();
 }
 
 
-DART_EXPORT void Dart_IsolateUnblocked() {
-  Isolate* isolate = Isolate::Current();
-  CHECK_ISOLATE(isolate);
-  IsolateProfilerData* profiler_data = isolate->profiler_data();
-  if (profiler_data == NULL) {
+DART_EXPORT void Dart_ThreadEnableProfiling() {
+  Thread* T = Thread::Current();
+  if (T == NULL) {
     return;
   }
-  profiler_data->Unblock();
+  T->EnableThreadInterrupts();
 }
 
 
@@ -1658,8 +1661,9 @@
   Monitor monitor;
   MonitorLocker ml(&monitor);
   {
-    SwitchIsolateScope switch_scope(NULL);
-
+    // The message handler run loop does not expect to have a current isolate
+    // so we exit the isolate here and enter it again after the runloop is done.
+    Thread::ExitIsolate();
     RunLoopData data;
     data.monitor = &monitor;
     data.done = false;
@@ -1669,6 +1673,7 @@
     while (!data.done) {
       ml.Wait();
     }
+    Thread::EnterIsolate(I);
   }
   if (I->object_store()->sticky_error() != Object::null()) {
     Dart_Handle error = Api::NewHandle(I, I->object_store()->sticky_error());
@@ -2884,7 +2889,7 @@
   if (result.IsError()) return result.raw();
   ASSERT(result.IsNull());
 
-  if (isolate->top_exit_frame_info() == 0) {
+  if (thread->top_exit_frame_info() == 0) {
     // There are no dart frames on the stack so it would be illegal to
     // throw an exception here.
     const String& message = String::Handle(
@@ -2899,7 +2904,7 @@
   {
     NoSafepointScope no_safepoint;
     RawInstance* raw_exception = exception.raw();
-    state->UnwindScopes(isolate->top_exit_frame_info());
+    state->UnwindScopes(thread->top_exit_frame_info());
     saved_exception = &Instance::Handle(raw_exception);
   }
   Exceptions::Throw(thread, *saved_exception);
@@ -3780,6 +3785,11 @@
         CURRENT_FUNC);
   }
   Class& cls = Class::Handle(Z, type_obj.type_class());
+#if defined(DEBUG)
+  if (!cls.is_allocated() && Dart::IsRunningPrecompiledCode()) {
+    return Api::NewError("Precompilation dropped '%s'", cls.ToCString());
+  }
+#endif
   TypeArguments& type_arguments =
       TypeArguments::Handle(Z, type_obj.arguments());
 
@@ -3930,6 +3940,11 @@
     RETURN_TYPE_ERROR(Z, type, Type);
   }
   const Class& cls = Class::Handle(Z, type_obj.type_class());
+#if defined(DEBUG)
+  if (!cls.is_allocated() && Dart::IsRunningPrecompiledCode()) {
+    return Api::NewError("Precompilation dropped '%s'", cls.ToCString());
+  }
+#endif
   const Error& error = Error::Handle(Z, cls.EnsureIsFinalized(T));
   if (!error.IsNull()) {
     // An error occurred, return error object.
@@ -3955,6 +3970,11 @@
     RETURN_NULL_ERROR(native_fields);
   }
   const Class& cls = Class::Handle(Z, type_obj.type_class());
+#if defined(DEBUG)
+  if (!cls.is_allocated() && Dart::IsRunningPrecompiledCode()) {
+    return Api::NewError("Precompilation dropped '%s'", cls.ToCString());
+  }
+#endif
   const Error& error = Error::Handle(Z, cls.EnsureIsFinalized(T));
   if (!error.IsNull()) {
     // An error occurred, return error object.
@@ -4011,10 +4031,6 @@
         "%s expects argument 'number_of_arguments' to be non-negative.",
         CURRENT_FUNC);
   }
-  const String& constructor_name = Api::UnwrapStringHandle(Z, name);
-  if (constructor_name.IsNull()) {
-    RETURN_TYPE_ERROR(Z, name, String);
-  }
   const Instance& instance = Api::UnwrapInstanceHandle(Z, object);
   if (instance.IsNull()) {
     RETURN_TYPE_ERROR(Z, object, Instance);
@@ -4026,13 +4042,18 @@
   // once for the same object.
 
   // Construct name of the constructor to invoke.
+  const String& constructor_name = Api::UnwrapStringHandle(Z, name);
   const Type& type_obj = Type::Handle(Z, instance.GetType());
   const Class& cls = Class::Handle(Z, type_obj.type_class());
   const String& class_name = String::Handle(Z, cls.Name());
   const Array& strings = Array::Handle(Z, Array::New(3));
   strings.SetAt(0, class_name);
   strings.SetAt(1, Symbols::Dot());
-  strings.SetAt(2, constructor_name);
+  if (constructor_name.IsNull()) {
+    strings.SetAt(2, Symbols::Empty());
+  } else {
+    strings.SetAt(2, constructor_name);
+  }
   const String& dot_name = String::Handle(Z, String::ConcatAll(strings));
   const TypeArguments& type_arguments =
       TypeArguments::Handle(Z, type_obj.arguments());
@@ -4519,7 +4540,7 @@
       RETURN_TYPE_ERROR(zone, exception, Instance);
     }
   }
-  if (isolate->top_exit_frame_info() == 0) {
+  if (thread->top_exit_frame_info() == 0) {
     // There are no dart frames on the stack so it would be illegal to
     // throw an exception here.
     return Api::NewError("No Dart frames on stack, cannot throw exception");
@@ -4534,7 +4555,7 @@
     NoSafepointScope no_safepoint;
     RawInstance* raw_exception =
         Api::UnwrapInstanceHandle(zone, exception).raw();
-    state->UnwindScopes(isolate->top_exit_frame_info());
+    state->UnwindScopes(thread->top_exit_frame_info());
     saved_exception = &Instance::Handle(raw_exception);
   }
   Exceptions::Throw(thread, *saved_exception);
@@ -4559,7 +4580,7 @@
       RETURN_TYPE_ERROR(zone, stacktrace, Instance);
     }
   }
-  if (isolate->top_exit_frame_info() == 0) {
+  if (thread->top_exit_frame_info() == 0) {
     // There are no dart frames on the stack so it would be illegal to
     // throw an exception here.
     return Api::NewError("No Dart frames on stack, cannot throw exception");
@@ -4577,7 +4598,7 @@
         Api::UnwrapInstanceHandle(zone, exception).raw();
     RawStacktrace* raw_stacktrace =
         Api::UnwrapStacktraceHandle(zone, stacktrace).raw();
-    state->UnwindScopes(isolate->top_exit_frame_info());
+    state->UnwindScopes(thread->top_exit_frame_info());
     saved_exception = &Instance::Handle(raw_exception);
     saved_stacktrace = &Stacktrace::Handle(raw_stacktrace);
   }
@@ -4965,17 +4986,18 @@
 
 
 // --- Environment ---
-RawString* Api::CallEnvironmentCallback(Isolate* isolate, const String& name) {
-  Scope api_scope(isolate);
+RawString* Api::CallEnvironmentCallback(Thread* thread, const String& name) {
+  Isolate* isolate = thread->isolate();
+  Scope api_scope(thread);
   Dart_EnvironmentCallback callback = isolate->environment_callback();
-  String& result = String::Handle(isolate->current_zone());
+  String& result = String::Handle(thread->zone());
   if (callback != NULL) {
     Dart_Handle response = callback(Api::NewHandle(isolate, name.raw()));
     if (::Dart_IsString(response)) {
       result ^= Api::UnwrapHandle(response);
     } else if (::Dart_IsError(response)) {
-      const Object& error =
-          Object::Handle(isolate->current_zone(), Api::UnwrapHandle(response));
+      const Object& error = Object::Handle(
+          thread->zone(), Api::UnwrapHandle(response));
       Exceptions::ThrowArgumentError(
           String::Handle(String::New(Error::Cast(error).ToErrorCString())));
     } else if (!::Dart_IsNull(response)) {
@@ -5051,7 +5073,7 @@
 // NOTE: Need to pass 'result' as a parameter here in order to avoid
 // warning: variable 'result' might be clobbered by 'longjmp' or 'vfork'
 // which shows up because of the use of setjmp.
-static void CompileSource(Isolate* isolate,
+static void CompileSource(Thread* thread,
                           const Library& lib,
                           const Script& script,
                           Dart_Handle* result) {
@@ -5060,13 +5082,13 @@
   if (update_lib_status) {
     lib.SetLoadInProgress();
   }
-  ASSERT(isolate != NULL);
+  ASSERT(thread != NULL);
   const Error& error =
-      Error::Handle(isolate->current_zone(), Compiler::Compile(lib, script));
+      Error::Handle(thread->zone(), Compiler::Compile(lib, script));
   if (error.IsNull()) {
-    *result = Api::NewHandle(isolate, lib.raw());
+    *result = Api::NewHandle(thread->isolate(), lib.raw());
   } else {
-    *result = Api::NewHandle(isolate, error.raw());
+    *result = Api::NewHandle(thread->isolate(), error.raw());
     // Compilation errors are not Dart instances, so just mark the library
     // as having failed to load without providing an error instance.
     lib.SetLoadError(Object::null_instance());
@@ -5115,7 +5137,7 @@
       Script::New(url_str, source_str, RawScript::kScriptTag));
   script.SetLocationOffset(line_offset, column_offset);
   Dart_Handle result;
-  CompileSource(I, library, script, &result);
+  CompileSource(T, library, script, &result);
   return result;
 }
 
@@ -5168,6 +5190,18 @@
 }
 
 
+DART_EXPORT Dart_Handle Dart_SetRootLibrary(Dart_Handle library) {
+  DARTSCOPE(Thread::Current());
+  const Library& lib = Api::UnwrapLibraryHandle(Z, library);
+  if (lib.IsNull()) {
+    RETURN_TYPE_ERROR(Z, library, Library);
+  }
+  Isolate* isolate = Isolate::Current();
+  isolate->object_store()->set_root_library(lib);
+  return library;
+}
+
+
 DART_EXPORT Dart_Handle Dart_GetClass(Dart_Handle library,
                                       Dart_Handle class_name) {
   DARTSCOPE(Thread::Current());
@@ -5360,7 +5394,7 @@
       Script::New(url_str, source_str, RawScript::kLibraryTag));
   script.SetLocationOffset(line_offset, column_offset);
   Dart_Handle result;
-  CompileSource(I, library, script, &result);
+  CompileSource(T, library, script, &result);
   // Propagate the error out right now.
   if (::Dart_IsError(result)) {
     return result;
@@ -5455,7 +5489,7 @@
       Script::New(url_str, source_str, RawScript::kSourceTag));
   script.SetLocationOffset(line_offset, column_offset);
   Dart_Handle result;
-  CompileSource(I, lib, script, &result);
+  CompileSource(T, lib, script, &result);
   return result;
 }
 
@@ -5484,7 +5518,7 @@
   const Script& script = Script::Handle(Z,
       Script::New(url_str, source_str, RawScript::kPatchTag));
   Dart_Handle result;
-  CompileSource(I, lib, script, &result);
+  CompileSource(T, lib, script, &result);
   return result;
 }
 
@@ -5703,6 +5737,8 @@
       (stream_mask & DART_TIMELINE_STREAM_COMPILER) != 0);
   isolate->GetDartStream()->set_enabled(
       (stream_mask & DART_TIMELINE_STREAM_DART) != 0);
+  isolate->GetDebuggerStream()->set_enabled(
+      (stream_mask & DART_TIMELINE_STREAM_DEBUGGER) != 0);
   isolate->GetEmbedderStream()->set_enabled(
       (stream_mask & DART_TIMELINE_STREAM_EMBEDDER) != 0);
   isolate->GetGCStream()->set_enabled(
@@ -5719,6 +5755,8 @@
       (stream_mask & DART_TIMELINE_STREAM_COMPILER) != 0;
   const bool dart_enabled =
       (stream_mask & DART_TIMELINE_STREAM_DART) != 0;
+  const bool debugger_enabled =
+      (stream_mask & DART_TIMELINE_STREAM_DEBUGGER) != 0;
   const bool embedder_enabled =
       (stream_mask & DART_TIMELINE_STREAM_EMBEDDER) != 0;
   const bool gc_enabled = (stream_mask & DART_TIMELINE_STREAM_GC) != 0;
@@ -5727,6 +5765,7 @@
   Timeline::SetStreamAPIEnabled(api_enabled);
   Timeline::SetStreamCompilerEnabled(compiler_enabled);
   Timeline::SetStreamDartEnabled(dart_enabled);
+  Timeline::SetStreamDebuggerEnabled(debugger_enabled);
   Timeline::SetStreamEmbedderEnabled(embedder_enabled);
   Timeline::SetStreamGCEnabled(gc_enabled);
   Timeline::SetStreamIsolateEnabled(isolate_enabled);
@@ -5737,35 +5776,6 @@
 }
 
 
-// '[' + ']' + '\0'.
-#define MINIMUM_OUTPUT_LENGTH 3
-
-// Trims the '[' and ']' characters and, depending on whether or not more events
-// will follow, adjusts the last character of the string to either a '\0' or
-// ','.
-static char* TrimOutput(char* output,
-                        intptr_t* output_length,
-                        bool events_will_follow) {
-  ASSERT(output != NULL);
-  ASSERT(output_length != NULL);
-  ASSERT(*output_length > MINIMUM_OUTPUT_LENGTH);
-  // We expect the first character to be the opening of an array.
-  ASSERT(output[0] == '[');
-  // We expect the last character to be the closing of an array.
-  ASSERT(output[*output_length - 2] == ']');
-  if (events_will_follow) {
-    // Replace array closing character (']') with ','.
-    output[*output_length - 2] = ',';
-  } else {
-    // Replace array closing character (']') with '\0'.
-    output[*output_length - 2] = '\0';
-  }
-  // Skip the array opening character ('[').
-  *output_length -= 2;
-  return &output[1];
-}
-
-
 static void StartStreamToConsumer(Dart_StreamConsumer consumer,
                                   void* user_data,
                                   const char* stream_name) {
@@ -5827,45 +5837,38 @@
 
 static bool StreamTraceEvents(Dart_StreamConsumer consumer,
                               void* user_data,
-                              JSONStream* js,
-                              const char* dart_events) {
+                              JSONStream* js) {
   ASSERT(js != NULL);
   // Steal output from JSONStream.
   char* output = NULL;
   intptr_t output_length = 0;
   js->Steal(const_cast<const char**>(&output), &output_length);
-
-  const bool output_vm = output_length > MINIMUM_OUTPUT_LENGTH;
-  const bool output_dart = dart_events != NULL;
-
-  if (!output_vm && !output_dart) {
-    // We stole the JSONStream's output buffer, free it.
+  if (output_length < 3) {
+    // Empty JSON array.
     free(output);
-    // Nothing will be emitted.
     return false;
   }
+  // We want to send the JSON array without the leading '[' or trailing ']'
+  // characters.
+  ASSERT(output[0] == '[');
+  ASSERT(output[output_length - 1] == ']');
+  // Replace the ']' with the null character.
+  output[output_length - 1] = '\0';
+  // We are skipping the '['.
+  output_length -= 1;
 
   // Start the stream.
   StartStreamToConsumer(consumer, user_data, "timeline");
 
-  // Send events from the VM.
-  if (output_vm) {
-    // Add one for the '\0' character.
-    output_length++;
-    char* trimmed_output = TrimOutput(output, &output_length, output_dart);
-    DataStreamToConsumer(consumer, user_data,
-                         trimmed_output, output_length, "timeline");
-  }
+  DataStreamToConsumer(consumer,
+                       user_data,
+                       &output[1],
+                       output_length,
+                       "timeline");
+
   // We stole the JSONStream's output buffer, free it.
   free(output);
 
-  // Send events from dart.
-  if (output_dart) {
-    const intptr_t dart_events_len = strlen(dart_events) + 1;  // +1 for '\0'.
-    DataStreamToConsumer(consumer, user_data,
-                         dart_events, dart_events_len, "timeline");
-  }
-
   // Finish the stream.
   FinishStreamToConsumer(consumer, user_data, "timeline");
   return true;
@@ -5886,16 +5889,11 @@
   }
   Thread* T = Thread::Current();
   StackZone zone(T);
-  // Reclaim all blocks cached by isolate.
-  Timeline::ReclaimIsolateBlocks();
+  Timeline::ReclaimCachedBlocksFromThreads();
   JSONStream js;
-  IsolateTimelineEventFilter filter(isolate);
+  IsolateTimelineEventFilter filter(isolate->main_port());
   timeline_recorder->PrintTraceEvent(&js, &filter);
-  const char* dart_events =
-      DartTimelineEventIterator::PrintTraceEvents(timeline_recorder,
-                                                  zone.GetZone(),
-                                                  isolate);
-  return StreamTraceEvents(consumer, user_data, &js, dart_events);
+  return StreamTraceEvents(consumer, user_data, &js);
 }
 
 
@@ -5911,16 +5909,11 @@
   }
   Thread* T = Thread::Current();
   StackZone zone(T);
-  // Reclaim all blocks cached in the system.
-  Timeline::ReclaimAllBlocks();
+  Timeline::ReclaimCachedBlocksFromThreads();
   JSONStream js;
   TimelineEventFilter filter;
   timeline_recorder->PrintTraceEvent(&js, &filter);
-  const char* dart_events =
-      DartTimelineEventIterator::PrintTraceEvents(timeline_recorder,
-                                                  zone.GetZone(),
-                                                  NULL);
-  return StreamTraceEvents(consumer, user_data, &js, dart_events);
+  return StreamTraceEvents(consumer, user_data, &js);
 }
 
 
@@ -6035,6 +6028,9 @@
     Dart_QualifiedFunctionName entry_points[],
     bool reset_fields) {
   DARTSCOPE(Thread::Current());
+  if (!FLAG_precompilation) {
+    return Dart_NewApiError("Flag --precompilation was not specified.");
+  }
   Dart_Handle result = Api::CheckAndFinalizePendingClasses(I);
   if (::Dart_IsError(result)) {
     return result;
@@ -6058,6 +6054,10 @@
     intptr_t* instructions_snapshot_size) {
   ASSERT(FLAG_load_deferred_eagerly);
   DARTSCOPE(Thread::Current());
+  if (I->compilation_allowed()) {
+    return Dart_NewApiError("Isolate is not precompiled. "
+                            "Did you forget to call Dart_Precompile?");
+  }
   if (vm_isolate_snapshot_buffer == NULL) {
     RETURN_NULL_ERROR(vm_isolate_snapshot_buffer);
   }
diff --git a/runtime/vm/dart_api_impl.h b/runtime/vm/dart_api_impl.h
index 613778a..76b3aba 100644
--- a/runtime/vm/dart_api_impl.h
+++ b/runtime/vm/dart_api_impl.h
@@ -112,7 +112,7 @@
   // Create on the stack to provide a new throw-safe api scope.
   class Scope : public StackResource {
    public:
-    explicit Scope(Isolate* isolate) : StackResource(isolate) {
+    explicit Scope(Thread* thread) : StackResource(thread) {
       Dart_EnterScope();
     }
     ~Scope() {
@@ -269,7 +269,7 @@
   static void SetWeakHandleReturnValue(NativeArguments* args,
                                        Dart_WeakPersistentHandle retval);
 
-  static RawString* CallEnvironmentCallback(Isolate* isolate,
+  static RawString* CallEnvironmentCallback(Thread* thread,
                                             const String& name);
 
  private:
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 6a53ff7..3f5056f 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -4253,7 +4253,7 @@
   Dart_Handle url = NewString("library_url");
   Dart_Handle source = NewString(kImportedScriptChars);
   Dart_Handle imported_lib = Dart_LoadLibrary(url, source, 0, 0);
-  Dart_Handle prefix = NewString("");
+  Dart_Handle prefix = Dart_EmptyString();
   EXPECT_VALID(imported_lib);
   Dart_Handle result = Dart_LibraryImportLibrary(lib, imported_lib, prefix);
   EXPECT_VALID(result);
@@ -5126,7 +5126,7 @@
   Dart_Handle bad_args[1];
   bad_args[0] = Dart_NewApiError("myerror");
 
-  // Invoke the unnamed constructor.
+  // Allocate and Invoke the unnamed constructor passing in Dart_Null.
   Dart_Handle result = Dart_New(type, Dart_Null(), 0, NULL);
   EXPECT_VALID(result);
   bool instanceof = false;
@@ -5146,8 +5146,8 @@
   foo = Dart_GetField(obj, NewString("foo"));
   EXPECT(Dart_IsNull(foo));
 
-  // Invoke the unnamed constructor with an empty string.
-  result = Dart_New(type, NewString(""), 0, NULL);
+  // Allocate and Invoke the unnamed constructor passing in an empty string.
+  result = Dart_New(type, Dart_EmptyString(), 0, NULL);
   EXPECT_VALID(result);
   instanceof = false;
   EXPECT_VALID(Dart_ObjectIsType(result, type, &instanceof));
@@ -5163,7 +5163,15 @@
   instanceof = false;
   EXPECT_VALID(Dart_ObjectIsType(obj, type, &instanceof));
   EXPECT(instanceof);
-  result = Dart_InvokeConstructor(obj, NewString(""), 0, NULL);
+  // Use the empty string to invoke the unnamed constructor.
+  result = Dart_InvokeConstructor(obj, Dart_EmptyString(), 0, NULL);
+  EXPECT_VALID(result);
+  int_value = 0;
+  foo = Dart_GetField(result, NewString("foo"));
+  EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value));
+  EXPECT_EQ(7, int_value);
+  // use Dart_Null to invoke the unnamed constructor.
+  result = Dart_InvokeConstructor(obj, Dart_Null(), 0, NULL);
   EXPECT_VALID(result);
   int_value = 0;
   foo = Dart_GetField(result, NewString("foo"));
@@ -6240,6 +6248,26 @@
   const char* uri_cstr = "";
   EXPECT_VALID(Dart_StringToCString(lib_uri, &uri_cstr));
   EXPECT_STREQ(TestCase::url(), uri_cstr);
+
+
+  Dart_Handle core_uri = Dart_NewStringFromCString("dart:core");
+  Dart_Handle core_lib = Dart_LookupLibrary(core_uri);
+  EXPECT_VALID(core_lib);
+  EXPECT(Dart_IsLibrary(core_lib));
+
+  Dart_Handle result = Dart_SetRootLibrary(core_uri);  // Not a library.
+  EXPECT(Dart_IsError(result));
+  root_lib = Dart_RootLibrary();
+  lib_uri = Dart_LibraryUrl(root_lib);
+  EXPECT_VALID(Dart_StringToCString(lib_uri, &uri_cstr));
+  EXPECT_STREQ(TestCase::url(), uri_cstr);  // Root library didn't change.
+
+  result = Dart_SetRootLibrary(core_lib);
+  EXPECT_VALID(result);
+  root_lib = Dart_RootLibrary();
+  lib_uri = Dart_LibraryUrl(root_lib);
+  EXPECT_VALID(Dart_StringToCString(lib_uri, &uri_cstr));
+  EXPECT_STREQ("dart:core", uri_cstr);  // Root library did change.
 }
 
 
@@ -9418,9 +9446,9 @@
   Dart_TimelineDuration("testDurationEvent", 0, 1);
   // Check that it is in the output.
   TimelineEventRecorder* recorder = Timeline::recorder();
-  Timeline::ReclaimIsolateBlocks();
+  Timeline::ReclaimCachedBlocksFromThreads();
   JSONStream js;
-  IsolateTimelineEventFilter filter(isolate);
+  IsolateTimelineEventFilter filter(isolate->main_port());
   recorder->PrintJSON(&js, &filter);
   EXPECT_SUBSTRING("testDurationEvent", js.ToCString());
 }
@@ -9435,9 +9463,9 @@
   Dart_TimelineInstant("testInstantEvent");
   // Check that it is in the output.
   TimelineEventRecorder* recorder = Timeline::recorder();
-  Timeline::ReclaimIsolateBlocks();
+  Timeline::ReclaimCachedBlocksFromThreads();
   JSONStream js;
-  IsolateTimelineEventFilter filter(isolate);
+  IsolateTimelineEventFilter filter(isolate->main_port());
   recorder->PrintJSON(&js, &filter);
   EXPECT_SUBSTRING("testInstantEvent", js.ToCString());
 }
@@ -9457,7 +9485,7 @@
   Dart_TimelineAsyncEnd("testAsyncEvent", async_id);
   // Check that testAsync is not in the output.
   TimelineEventRecorder* recorder = Timeline::recorder();
-  Timeline::ReclaimIsolateBlocks();
+  Timeline::ReclaimCachedBlocksFromThreads();
   JSONStream js;
   TimelineEventFilter filter;
   recorder->PrintJSON(&js, &filter);
@@ -9480,9 +9508,9 @@
 
   // Check that it is in the output.
   TimelineEventRecorder* recorder = Timeline::recorder();
-  Timeline::ReclaimIsolateBlocks();
+  Timeline::ReclaimCachedBlocksFromThreads();
   JSONStream js;
-  IsolateTimelineEventFilter filter(isolate);
+  IsolateTimelineEventFilter filter(isolate->main_port());
   recorder->PrintJSON(&js, &filter);
   EXPECT_SUBSTRING("testAsyncEvent", js.ToCString());
 }
@@ -9554,6 +9582,12 @@
   EXPECT(buffer_length > 0);
   EXPECT(buffer != NULL);
 
+  // Response starts with a '{' character and not a '['.
+  EXPECT(buffer[0] == '{');
+  // Response ends with a '}' character and not a ']'.
+  EXPECT(buffer[buffer_length - 1] == '\0');
+  EXPECT(buffer[buffer_length - 2] == '}');
+
   // Heartbeat test.
   EXPECT_SUBSTRING("\"cat\":\"Compiler\"", buffer);
   EXPECT_SUBSTRING("\"name\":\"CompileFunction\"", buffer);
@@ -9601,6 +9635,12 @@
   EXPECT(buffer_length > 0);
   EXPECT(buffer != NULL);
 
+  // Response starts with a '{' character and not a '['.
+  EXPECT(buffer[0] == '{');
+  // Response ends with a '}' character and not a ']'.
+  EXPECT(buffer[buffer_length - 1] == '\0');
+  EXPECT(buffer[buffer_length - 2] == '}');
+
   // Heartbeat test.
   EXPECT_SUBSTRING("\"cat\":\"Dart\"", buffer);
   EXPECT_SUBSTRING("\"name\":\"DART_NAME\"", buffer);
@@ -9646,6 +9686,12 @@
   EXPECT(buffer_length > 0);
   EXPECT(buffer != NULL);
 
+  // Response starts with a '{' character and not a '['.
+  EXPECT(buffer[0] == '{');
+  // Response ends with a '}' character and not a ']'.
+  EXPECT(buffer[buffer_length - 1] == '\0');
+  EXPECT(buffer[buffer_length - 2] == '}');
+
   // Heartbeat test.
   EXPECT_SUBSTRING("\"cat\":\"Compiler\"", buffer);
   EXPECT_SUBSTRING("\"name\":\"CompileFunction\"", buffer);
@@ -9689,6 +9735,12 @@
   EXPECT(buffer_length > 0);
   EXPECT(buffer != NULL);
 
+  // Response starts with a '{' character and not a '['.
+  EXPECT(buffer[0] == '{');
+  // Response ends with a '}' character and not a ']'.
+  EXPECT(buffer[buffer_length - 1] == '\0');
+  EXPECT(buffer[buffer_length - 2] == '}');
+
   // Heartbeat test.
   EXPECT_SUBSTRING("\"cat\":\"Compiler\"", buffer);
   EXPECT_SUBSTRING("\"name\":\"CompileFunction\"", buffer);
@@ -9737,6 +9789,12 @@
   EXPECT(buffer_length > 0);
   EXPECT(buffer != NULL);
 
+  // Response starts with a '{' character and not a '['.
+  EXPECT(buffer[0] == '{');
+  // Response ends with a '}' character and not a ']'.
+  EXPECT(buffer[buffer_length - 1] == '\0');
+  EXPECT(buffer[buffer_length - 2] == '}');
+
   // Heartbeat test.
   EXPECT_SUBSTRING("\"name\":\"TestVMDuration\"", buffer);
   EXPECT_SUBSTRING("\"cat\":\"Compiler\"", buffer);
@@ -9771,6 +9829,11 @@
   buffer_length = data.buffer_length;
   EXPECT(buffer_length > 0);
   EXPECT(buffer != NULL);
+  // Response starts with a '{' character and not a '['.
+  EXPECT(buffer[0] == '{');
+  // Response ends with a '}' character and not a ']'.
+  EXPECT(buffer[buffer_length - 1] == '\0');
+  EXPECT(buffer[buffer_length - 2] == '}');
 
   // Heartbeat test for old events.
   EXPECT_SUBSTRING("\"name\":\"TestVMDuration\"", buffer);
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index 2f5a79e..63e2689 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -24,6 +24,7 @@
 
 RawObject* DartEntry::InvokeFunction(const Function& function,
                                      const Array& arguments) {
+  ASSERT(Thread::Current()->IsMutatorThread());
   const Array& arguments_descriptor =
       Array::Handle(ArgumentsDescriptor::New(arguments.Length()));
   return InvokeFunction(function, arguments, arguments_descriptor);
@@ -84,7 +85,7 @@
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   Isolate* isolate = thread->isolate();
-  ASSERT(isolate->MutatorThreadIsCurrentThread());
+  ASSERT(thread->IsMutatorThread());
   if (!function.HasCode()) {
     const Error& error = Error::Handle(
         zone, Compiler::CompileFunction(thread, function));
@@ -251,12 +252,12 @@
 
 
 intptr_t ArgumentsDescriptor::Count() const {
-  return Smi::CheckedHandle(array_.At(kCountIndex)).Value();
+  return Smi::Cast(Object::Handle(array_.At(kCountIndex))).Value();
 }
 
 
 intptr_t ArgumentsDescriptor::PositionalCount() const {
-  return Smi::CheckedHandle(array_.At(kPositionalCountIndex)).Value();
+  return Smi::Cast(Object::Handle(array_.At(kPositionalCountIndex))).Value();
 }
 
 
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 3434e01..0be47b7 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -310,8 +310,8 @@
 
   if (ServiceNeedsDebuggerEvent(event->type()) && event->IsPauseEvent()) {
     // If we were paused, notify the service that we have resumed.
-    const Error& error = Error::Handle(zone(),
-        isolate_->object_store()->sticky_error());
+    const Error& error =
+        Error::Handle(isolate_->object_store()->sticky_error());
     ASSERT(error.IsNull() || error.IsUnwindError());
 
     // Only send a resume event when the isolate is not unwinding.
@@ -365,7 +365,7 @@
 
   // If any error occurred while in the debug message loop, return it here.
   const Error& error =
-      Error::Handle(zone(), isolate_->object_store()->sticky_error());
+      Error::Handle(isolate_->object_store()->sticky_error());
   ASSERT(error.IsNull() || error.IsUnwindError());
   isolate_->object_store()->clear_sticky_error();
   return error.raw();
@@ -468,13 +468,13 @@
 }
 
 
-bool Debugger::HasBreakpoint(const Function& func) {
+bool Debugger::HasBreakpoint(const Function& func, Zone* zone) {
   if (!func.HasCode()) {
     // If the function is not compiled yet, just check whether there
     // is a user-defined breakpoint that falls into the token
     // range of the function. This may be a false positive: the breakpoint
     // might be inside a local closure.
-    Script& script = Script::Handle(zone());
+    Script& script = Script::Handle(zone);
     BreakpointLocation* sbpt = breakpoint_locations_;
     while (sbpt != NULL) {
       script = sbpt->script();
@@ -1251,6 +1251,7 @@
     : isolate_(NULL),
       isolate_id_(ILLEGAL_ISOLATE_ID),
       initialized_(false),
+      creation_message_sent_(false),
       next_id_(1),
       latent_locations_(NULL),
       breakpoint_locations_(NULL),
@@ -1277,6 +1278,12 @@
 
 
 void Debugger::Shutdown() {
+  // TODO(johnmccutchan): Do not create a debugger for isolates that don't need
+  // them. Then, assert here that isolate_ is not one of those isolates.
+  if ((isolate_ == Dart::vm_isolate()) ||
+      ServiceIsolate::IsServiceIsolateDescendant(isolate_)) {
+    return;
+  }
   while (breakpoint_locations_ != NULL) {
     BreakpointLocation* bpt = breakpoint_locations_;
     breakpoint_locations_ = breakpoint_locations_->next();
@@ -1293,8 +1300,9 @@
     bpt->Disable();
     delete bpt;
   }
-  // Signal isolate shutdown event.
-  if (!ServiceIsolate::IsServiceIsolateDescendant(isolate_)) {
+  // Signal isolate shutdown event, but only if we previously sent the creation
+  // event.
+  if (creation_message_sent_) {
     SignalIsolateEvent(DebuggerEvent::kIsolateShutdown);
   }
 }
@@ -1385,19 +1393,17 @@
           }
         }
       }
+    }
+  }
 
-      // Disable other optimized closure functions.
-      closures = cls.closures();
-      if (!closures.IsNull()) {
-        intptr_t num_closures = closures.Length();
-        for (intptr_t pos = 0; pos < num_closures; pos++) {
-          function ^= closures.At(pos);
-          ASSERT(!function.IsNull());
-          if (function.HasOptimizedCode()) {
-            function.SwitchToUnoptimizedCode();
-          }
-        }
-      }
+  // Disable optimized closure functions.
+  closures = isolate_->object_store()->closure_functions();
+  const intptr_t num_closures = closures.Length();
+  for (intptr_t pos = 0; pos < num_closures; pos++) {
+    function ^= closures.At(pos);
+    ASSERT(!function.IsNull());
+    if (function.HasOptimizedCode()) {
+      function.SwitchToUnoptimizedCode();
     }
   }
 }
@@ -1520,7 +1526,7 @@
   while ((frame != NULL) && !frame->IsDartFrame()) {
     frame = iterator.NextFrame();
   }
-  Code& code = Code::Handle(zone(), frame->LookupDartCode());
+  Code& code = Code::Handle(frame->LookupDartCode());
   ActivationFrame* activation =
       new ActivationFrame(frame->pc(), frame->fp(), frame->sp(), code,
                           Object::null_array(), 0);
@@ -1867,11 +1873,31 @@
                                      intptr_t start_pos,
                                      intptr_t end_pos,
                                      GrowableObjectArray* function_list) {
-  Zone* zn = zone();
-  Class& cls = Class::Handle(zn);
-  Array& functions = Array::Handle(zn);
-  GrowableObjectArray& closures = GrowableObjectArray::Handle(zn);
-  Function& function = Function::Handle(zn);
+  Zone* zone = Thread::Current()->zone();
+  Class& cls = Class::Handle(zone);
+  Array& functions = Array::Handle(zone);
+  GrowableObjectArray& closures = GrowableObjectArray::Handle(zone);
+  Function& function = Function::Handle(zone);
+
+  closures = isolate_->object_store()->closure_functions();
+  const intptr_t num_closures = closures.Length();
+  for (intptr_t pos = 0; pos < num_closures; pos++) {
+    function ^= closures.At(pos);
+    ASSERT(!function.IsNull());
+    if ((function.token_pos() == start_pos)
+        && (function.end_token_pos() == end_pos)
+        && (function.script() == script.raw())) {
+      if (function.HasCode() && function.is_debuggable()) {
+        function_list->Add(function);
+      }
+      if (function.HasImplicitClosureFunction()) {
+        function = function.ImplicitClosureFunction();
+        if (function.HasCode() && function.is_debuggable()) {
+          function_list->Add(function);
+        }
+      }
+    }
+  }
 
   const ClassTable& class_table = *isolate_->class_table();
   const intptr_t num_classes = class_table.NumCids();
@@ -1911,27 +1937,6 @@
           }
         }
       }
-      closures = cls.closures();
-      if (!closures.IsNull()) {
-        const intptr_t num_closures = closures.Length();
-        for (intptr_t pos = 0; pos < num_closures; pos++) {
-          function ^= closures.At(pos);
-          ASSERT(!function.IsNull());
-          if ((function.token_pos() == start_pos)
-              && (function.end_token_pos() == end_pos)
-              && (function.script() == script.raw())) {
-            if (function.HasCode() && function.is_debuggable()) {
-              function_list->Add(function);
-            }
-            if (function.HasImplicitClosureFunction()) {
-              function = function.ImplicitClosureFunction();
-              if (function.HasCode() && function.is_debuggable()) {
-                function_list->Add(function);
-              }
-            }
-          }
-        }
-      }
     }
   }
 }
@@ -1951,13 +1956,22 @@
 
 RawFunction* Debugger::FindBestFit(const Script& script,
                                    intptr_t token_pos) {
-  Zone* zn = zone();
-  Class& cls = Class::Handle(zn);
-  Array& functions = Array::Handle(zn);
-  GrowableObjectArray& closures = GrowableObjectArray::Handle(zn);
-  Function& function = Function::Handle(zn);
-  Function& best_fit = Function::Handle(zn);
-  Error& error = Error::Handle(zn);
+  Zone* zone = Thread::Current()->zone();
+  Class& cls = Class::Handle(zone);
+  Array& functions = Array::Handle(zone);
+  GrowableObjectArray& closures = GrowableObjectArray::Handle(zone);
+  Function& function = Function::Handle(zone);
+  Function& best_fit = Function::Handle(zone);
+  Error& error = Error::Handle(zone);
+
+  closures = isolate_->object_store()->closure_functions();
+  const intptr_t num_closures = closures.Length();
+  for (intptr_t i = 0; i < num_closures; i++) {
+    function ^= closures.At(i);
+    if (FunctionContains(function, script, token_pos)) {
+      SelectBestFit(&best_fit, &function);
+    }
+  }
 
   const ClassTable& class_table = *isolate_->class_table();
   const intptr_t num_classes = class_table.NumCids();
@@ -1993,18 +2007,6 @@
           }
         }
       }
-
-      closures = cls.closures();
-      if (!closures.IsNull()) {
-        const intptr_t num_closures = closures.Length();
-        for (intptr_t pos = 0; pos < num_closures; pos++) {
-          function ^= closures.At(pos);
-          ASSERT(!function.IsNull());
-          if (FunctionContains(function, script, token_pos)) {
-            SelectBestFit(&best_fit, &function);
-          }
-        }
-      }
     }
   }
   return best_fit.raw();
@@ -2016,7 +2018,7 @@
                                             intptr_t last_token_pos,
                                             intptr_t requested_line,
                                             intptr_t requested_column) {
-  Function& func = Function::Handle(zone());
+  Function& func = Function::Handle();
   func = FindBestFit(script, token_pos);
   if (func.IsNull()) {
     return NULL;
@@ -2208,12 +2210,13 @@
     const String& script_url,
     intptr_t line_number,
     intptr_t column_number) {
-  Library& lib = Library::Handle(zone());
-  Script& script = Script::Handle(zone());
+  Zone* zone = Thread::Current()->zone();
+  Library& lib = Library::Handle(zone);
+  Script& script = Script::Handle(zone);
   const GrowableObjectArray& libs =
       GrowableObjectArray::Handle(isolate_->object_store()->libraries());
   const GrowableObjectArray& scripts =
-    GrowableObjectArray::Handle(zone(), GrowableObjectArray::New());
+    GrowableObjectArray::Handle(zone, GrowableObjectArray::New());
   for (intptr_t i = 0; i < libs.Length(); i++) {
     lib ^= libs.At(i);
     script = lib.LookupScript(script_url);
@@ -2403,10 +2406,11 @@
                                     const String& prefix,
                                     bool include_private_fields) {
   DictionaryIterator it(lib);
-  Object& entry = Object::Handle(isolate_->current_zone());
-  Field& field = Field::Handle(zone());
-  String& field_name = String::Handle(zone());
-  PassiveObject& field_value = PassiveObject::Handle(isolate_->current_zone());
+  Zone* zone = Thread::Current()->zone();
+  Object& entry = Object::Handle(zone);
+  Field& field = Field::Handle(zone);
+  String& field_name = String::Handle(zone);
+  PassiveObject& field_value = PassiveObject::Handle(zone);
   while (it.HasNext()) {
     entry = it.GetNext();
     if (entry.IsField()) {
@@ -2437,26 +2441,28 @@
 
 
 RawArray* Debugger::GetLibraryFields(const Library& lib) {
+  Zone* zone = Thread::Current()->zone();
   const GrowableObjectArray& field_list =
       GrowableObjectArray::Handle(GrowableObjectArray::New(8));
-  CollectLibraryFields(field_list, lib, String::Handle(zone()), true);
+  CollectLibraryFields(field_list, lib, String::Handle(zone), true);
   return Array::MakeArray(field_list);
 }
 
 
 RawArray* Debugger::GetGlobalFields(const Library& lib) {
+  Zone* zone = Thread::Current()->zone();
   const GrowableObjectArray& field_list =
-      GrowableObjectArray::Handle(GrowableObjectArray::New(8));
-  String& prefix_name = String::Handle(zone());
+      GrowableObjectArray::Handle(zone, GrowableObjectArray::New(8));
+  String& prefix_name = String::Handle(zone);
   CollectLibraryFields(field_list, lib, prefix_name, true);
-  Library& imported = Library::Handle(zone());
+  Library& imported = Library::Handle(zone);
   intptr_t num_imports = lib.num_imports();
   for (intptr_t i = 0; i < num_imports; i++) {
     imported = lib.ImportLibraryAt(i);
     ASSERT(!imported.IsNull());
     CollectLibraryFields(field_list, imported, prefix_name, false);
   }
-  LibraryPrefix& prefix = LibraryPrefix::Handle(zone());
+  LibraryPrefix& prefix = LibraryPrefix::Handle(zone);
   LibraryPrefixIterator it(lib);
   while (it.HasNext()) {
     prefix = it.GetNext();
@@ -2507,7 +2513,16 @@
   pause_event_->UpdateTimestamp();
   obj_cache_ = new RemoteObjectCache(64);
 
-  InvokeEventHandler(event);
+  // We are about to invoke the debuggers event handler. Disable interrupts
+  // for this thread while waiting for debug commands over the service protocol.
+  {
+    Thread* thread = Thread::Current();
+    DisableThreadInterruptsScope dtis(thread);
+    TimelineDurationScope tds(thread,
+                              isolate_->GetDebuggerStream(),
+                              "Debugger Pause");
+    InvokeEventHandler(event);
+  }
 
   pause_event_ = NULL;
   obj_cache_ = NULL;    // Zone allocated
@@ -2548,11 +2563,6 @@
       }
     }
   }
-  if (!isolate_->single_step()) {
-    // We are no longer single stepping, make sure that the ThreadInterrupter
-    // is awake.
-    ThreadInterrupter::WakeUp();
-  }
 }
 
 
@@ -2665,7 +2675,7 @@
 
   // If any error occurred while in the debug message loop, return it here.
   const Error& error =
-      Error::Handle(zone(), isolate_->object_store()->sticky_error());
+      Error::Handle(isolate_->object_store()->sticky_error());
   isolate_->object_store()->clear_sticky_error();
   return error.raw();
 }
@@ -2754,7 +2764,7 @@
 
   // If any error occurred while in the debug message loop, return it here.
   const Error& error =
-      Error::Handle(zone(), isolate_->object_store()->sticky_error());
+      Error::Handle(isolate_->object_store()->sticky_error());
   isolate_->object_store()->clear_sticky_error();
   return error.raw();
 }
@@ -2801,8 +2811,10 @@
 
 void Debugger::NotifyIsolateCreated() {
   // Signal isolate creation event.
-  if (!ServiceIsolate::IsServiceIsolateDescendant(isolate_)) {
+  if ((isolate_ != Dart::vm_isolate()) &&
+      !ServiceIsolate::IsServiceIsolateDescendant(isolate_)) {
     SignalIsolateEvent(DebuggerEvent::kIsolateCreated);
+    creation_message_sent_ = true;
   }
 }
 
@@ -2811,20 +2823,14 @@
 // the given token position.
 RawFunction* Debugger::FindInnermostClosure(const Function& function,
                                             intptr_t token_pos) {
-  const Class& owner = Class::Handle(zone(), function.Owner());
-  if (owner.closures() == GrowableObjectArray::null()) {
-    return Function::null();
-  }
-  // Note that we need to check that the closure is in the same
-  // script as the outer function. We could have closures originating
-  // in mixin classes whose source code is contained in a different
-  // script.
-  const Script& outer_origin = Script::Handle(zone(), function.script());
+  Zone* zone = Thread::Current()->zone();
+  const Script& outer_origin = Script::Handle(zone, function.script());
   const GrowableObjectArray& closures =
-     GrowableObjectArray::Handle(zone(), owner.closures());
+     GrowableObjectArray::Handle(zone,
+         Isolate::Current()->object_store()->closure_functions());
   const intptr_t num_closures = closures.Length();
-  Function& closure = Function::Handle(zone());
-  Function& best_fit = Function::Handle(zone());
+  Function& closure = Function::Handle(zone);
+  Function& best_fit = Function::Handle(zone);
   for (intptr_t i = 0; i < num_closures; i++) {
     closure ^= closures.At(i);
     if ((function.token_pos() < closure.token_pos()) &&
@@ -2852,13 +2858,14 @@
   }
   // Iterate over all source breakpoints to check whether breakpoints
   // need to be set in the newly compiled function.
-  Script& script = Script::Handle(zone());
+  Zone* zone = Thread::Current()->zone();
+  Script& script = Script::Handle(zone);
   for (BreakpointLocation* loc = breakpoint_locations_;
       loc != NULL;
       loc = loc->next()) {
     script = loc->script();
     if (FunctionContains(func, script, loc->token_pos())) {
-      Function& inner_function = Function::Handle(zone());
+      Function& inner_function = Function::Handle(zone);
       inner_function = FindInnermostClosure(func, loc->token_pos());
       if (!inner_function.IsNull()) {
         // The local function of a function we just compiled cannot
@@ -2939,10 +2946,10 @@
     // Common, fast path.
     return;
   }
-  Zone* zn = zone();
-  Library& lib = Library::Handle(zn);
-  Script& script = Script::Handle(zn);
-  String& url = String::Handle(zn);
+  Zone* zone = Thread::Current()->zone();
+  Library& lib = Library::Handle(zone);
+  Script& script = Script::Handle(zone);
+  String& url = String::Handle(zone);
   BreakpointLocation* loc = latent_locations_;
   BreakpointLocation* prev_loc = NULL;
   const GrowableObjectArray& libs =
@@ -3215,7 +3222,7 @@
                                                   intptr_t line,
                                                   intptr_t column) {
   BreakpointLocation* bpt = latent_locations_;
-  String& bpt_url = String::Handle(zone());
+  String& bpt_url = String::Handle();
   while (bpt != NULL) {
     bpt_url = bpt->url();
     if (bpt_url.Equals(url) &&
diff --git a/runtime/vm/debugger.h b/runtime/vm/debugger.h
index a9d0547..aaa2b84 100644
--- a/runtime/vm/debugger.h
+++ b/runtime/vm/debugger.h
@@ -515,7 +515,9 @@
 
   // Returns true if there is at least one breakpoint set in func or code.
   // Checks for both user-defined and internal temporary breakpoints.
-  bool HasBreakpoint(const Function& func);
+  // This may be called from different threads, therefore do not use the,
+  // debugger's zone.
+  bool HasBreakpoint(const Function& func, Zone* zone);
   bool HasBreakpoint(const Code& code);
 
   // Returns true if the call at address pc is patched to point to
@@ -650,11 +652,10 @@
 
   void HandleSteppingRequest(DebuggerStackTrace* stack_trace);
 
-  Zone* zone() const { return isolate_->current_zone(); }
-
   Isolate* isolate_;
   Dart_Port isolate_id_;  // A unique ID for the isolate in the debugger.
   bool initialized_;
+  bool creation_message_sent_;  // The creation message has been sent.
 
   // ID number generator.
   intptr_t next_id_;
diff --git a/runtime/vm/debugger_api_impl_test.cc b/runtime/vm/debugger_api_impl_test.cc
index ca260f2..1bfc4ce 100644
--- a/runtime/vm/debugger_api_impl_test.cc
+++ b/runtime/vm/debugger_api_impl_test.cc
@@ -11,6 +11,7 @@
 
 namespace dart {
 
+DECLARE_FLAG(bool, background_compilation);
 DECLARE_FLAG(int, optimization_counter_threshold);
 DECLARE_FLAG(bool, use_osr);
 
@@ -493,6 +494,8 @@
 
 
 TEST_CASE(Debug_InspectStack_Optimized) {
+  // Ensure code gets optimized.
+  FLAG_background_compilation = false;
   InspectStackTest(true);
 }
 
@@ -589,6 +592,8 @@
 
 
 TEST_CASE(Debug_InspectStackWithClosure_Optimized) {
+  // Ensure code gets optimized.
+  FLAG_background_compilation = false;
   InspectStackWithClosureTest(true);
 }
 
@@ -2138,8 +2143,8 @@
       "int main() {\n"
       "}\n";
 
-  Isolate* isolate = Isolate::Current();
-  Zone* zone = isolate->current_zone();
+
+  Zone* zone = thread->zone();
   LoadScript(kScriptChars);
   ASSERT(script_lib != NULL);
   ASSERT(Dart_IsLibrary(script_lib));
diff --git a/runtime/vm/disassembler.cc b/runtime/vm/disassembler.cc
index 986b9b2..99b13ce 100644
--- a/runtime/vm/disassembler.cc
+++ b/runtime/vm/disassembler.cc
@@ -7,14 +7,17 @@
 #include "vm/assembler.h"
 #include "vm/globals.h"
 #include "vm/il_printer.h"
+#include "vm/instructions.h"
 #include "vm/json_stream.h"
 #include "vm/log.h"
 #include "vm/os.h"
+#include "vm/code_patcher.h"
 
 
 namespace dart {
 
-void DisassembleToStdout::ConsumeInstruction(char* hex_buffer,
+void DisassembleToStdout::ConsumeInstruction(const Code& code,
+                                             char* hex_buffer,
                                              intptr_t hex_size,
                                              char* human_buffer,
                                              intptr_t human_size,
@@ -41,18 +44,26 @@
 }
 
 
-void DisassembleToJSONStream::ConsumeInstruction(char* hex_buffer,
+void DisassembleToJSONStream::ConsumeInstruction(const Code& code,
+                                                 char* hex_buffer,
                                                  intptr_t hex_size,
                                                  char* human_buffer,
                                                  intptr_t human_size,
                                                  uword pc) {
-  // Instructions are represented as three consecutive values in a JSON array.
-  // All three are strings. The first is the address of the instruction,
-  // the second is the hex string of the code, and the final is a human
-  // readable string.
+  // Instructions are represented as four consecutive values in a JSON array.
+  // The first is the address of the instruction, the second is the hex string,
+  // of the code, and the third is a human readable string, and the fourth is
+  // the object loaded by the instruction.
   jsarr_.AddValueF("%" Pp "", pc);
   jsarr_.AddValue(hex_buffer);
   jsarr_.AddValue(human_buffer);
+
+  Object& object = Object::Handle();
+  if (DecodeLoadObjectFromPoolOrThread(pc, code, &object)) {
+    jsarr_.AddValue(object);
+  } else {
+    jsarr_.AddValueNull();  // Not a reference to null.
+  }
 }
 
 
@@ -71,12 +82,12 @@
       p[i] = ' ';
     }
   }
-  // Instructions are represented as three consecutive values in a JSON array.
-  // All three are strings. Comments only use the third slot. See above comment
-  // for more information.
-  jsarr_.AddValue("");
-  jsarr_.AddValue("");
+  // Instructions are represented as four consecutive values in a JSON array.
+  // Comments only use the third slot. See above comment for more information.
+  jsarr_.AddValueNull();
+  jsarr_.AddValueNull();
   jsarr_.AddValue(p);
+  jsarr_.AddValueNull();
   free(p);
 }
 
@@ -158,7 +169,8 @@
                       human_buffer,
                       sizeof(human_buffer),
                       &instruction_length, pc);
-    formatter->ConsumeInstruction(hex_buffer,
+    formatter->ConsumeInstruction(code,
+                                  hex_buffer,
                                   sizeof(hex_buffer),
                                   human_buffer,
                                   sizeof(human_buffer),
diff --git a/runtime/vm/disassembler.h b/runtime/vm/disassembler.h
index 1becc4d..e89ab21 100644
--- a/runtime/vm/disassembler.h
+++ b/runtime/vm/disassembler.h
@@ -24,7 +24,8 @@
   virtual ~DisassemblyFormatter() { }
 
   // Consume the decoded instruction at the given pc.
-  virtual void ConsumeInstruction(char* hex_buffer,
+  virtual void ConsumeInstruction(const Code& code,
+                                  char* hex_buffer,
                                   intptr_t hex_size,
                                   char* human_buffer,
                                   intptr_t human_size,
@@ -42,7 +43,8 @@
   DisassembleToStdout() : DisassemblyFormatter() { }
   ~DisassembleToStdout() { }
 
-  virtual void ConsumeInstruction(char* hex_buffer,
+  virtual void ConsumeInstruction(const Code& code,
+                                  char* hex_buffer,
                                   intptr_t hex_size,
                                   char* human_buffer,
                                   intptr_t human_size,
@@ -63,7 +65,8 @@
       : DisassemblyFormatter(), jsarr_(jsarr) { }
   ~DisassembleToJSONStream() { }
 
-  virtual void ConsumeInstruction(char* hex_buffer,
+  virtual void ConsumeInstruction(const Code& code,
+                                  char* hex_buffer,
                                   intptr_t hex_size,
                                   char* human_buffer,
                                   intptr_t human_size,
diff --git a/runtime/vm/disassembler_arm.cc b/runtime/vm/disassembler_arm.cc
index 93ff293..a544e3c 100644
--- a/runtime/vm/disassembler_arm.cc
+++ b/runtime/vm/disassembler_arm.cc
@@ -109,11 +109,16 @@
 
 
 // These register names are defined in a way to match the native disassembler
-// formatting, except for register alias pp (r9).
+// formatting, except for register alias pp (r5).
 // See for example the command "objdump -d <binary file>".
 static const char* reg_names[kNumberOfCpuRegisters] = {
-  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
-  "r8", "pp", "r10", "fp", "ip", "sp", "lr", "pc",
+#if defined(TARGET_OS_MACOS)
+  "r0", "r1", "r2", "r3", "r4", "pp", "r6", "fp",
+  "r8", "r9", "r10", "r11", "ip", "sp", "lr", "pc",
+#else
+  "r0", "r1", "r2", "r3", "r4", "pp", "r6", "r7",
+  "r8", "r9", "r10", "fp", "ip", "sp", "lr", "pc",
+#endif
 };
 
 
diff --git a/runtime/vm/disassembler_arm64.cc b/runtime/vm/disassembler_arm64.cc
index 193d5b1..e414221 100644
--- a/runtime/vm/disassembler_arm64.cc
+++ b/runtime/vm/disassembler_arm64.cc
@@ -83,12 +83,12 @@
 
 
 // These register names are defined in a way to match the native disassembler
-// formatting, except for register aliases ctx (r9) and pp (r10).
+// formatting, except for register aliases ctx (r9), pp (r10) and sp (r19).
 // See for example the command "objdump -d <binary file>".
 static const char* reg_names[kNumberOfCpuRegisters] = {
   "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
   "r8",  "r9",  "r10", "r11", "r12", "r13", "r14", "r15",
-  "ip0", "ip1", "sp", "r19", "r20", "r21", "r22", "r23",
+  "ip0", "ip1", "r18", "sp",  "r20", "r21", "r22", "r23",
   "r24", "r25", "r26", "pp",  "ctx", "fp",  "lr",  "r31",
 };
 
diff --git a/runtime/vm/disassembler_mips.cc b/runtime/vm/disassembler_mips.cc
index af84199..aabaafe 100644
--- a/runtime/vm/disassembler_mips.cc
+++ b/runtime/vm/disassembler_mips.cc
@@ -543,6 +543,10 @@
         Format(instr, "mov.'fmt 'fd, 'fs");
         break;
       }
+      case COP1_NEG: {
+        Format(instr, "neg.'fmt 'fd, 'fs");
+        break;
+      }
       case COP1_C_F: {
         Format(instr, "c.f.'fmt 'fs, 'ft");
         break;
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index d5d4b39..82bc544 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -502,9 +502,8 @@
 
 void Exceptions::PropagateError(const Error& error) {
   Thread* thread = Thread::Current();
-  Isolate* isolate = thread->isolate();
   Zone* zone = thread->zone();
-  ASSERT(isolate->top_exit_frame_info() != 0);
+  ASSERT(thread->top_exit_frame_info() != 0);
   if (error.IsUnhandledException()) {
     // If the error object represents an unhandled exception, then
     // rethrow the exception in the normal fashion.
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc
index a4753f2..4097af5 100644
--- a/runtime/vm/flow_graph.cc
+++ b/runtime/vm/flow_graph.cc
@@ -44,6 +44,7 @@
     loop_headers_(NULL),
     loop_invariant_loads_(NULL),
     guarded_fields_(parsed_function.guarded_fields()),
+    deoptimize_dependent_code_(),
     deferred_prefixes_(parsed_function.deferred_prefixes()),
     captured_parameters_(new(zone()) BitVector(zone(), variable_count())),
     inlining_id_(-1) {
diff --git a/runtime/vm/flow_graph.h b/runtime/vm/flow_graph.h
index d962f90..cf62e82 100644
--- a/runtime/vm/flow_graph.h
+++ b/runtime/vm/flow_graph.h
@@ -279,6 +279,10 @@
     return guarded_fields_;
   }
 
+  GrowableArray<const Field*>& deoptimize_dependent_code() {
+    return deoptimize_dependent_code_;
+  }
+
   ZoneGrowableArray<const LibraryPrefix*>* deferred_prefixes() const {
     return deferred_prefixes_;
   }
@@ -363,6 +367,7 @@
   ZoneGrowableArray<BlockEntryInstr*>* loop_headers_;
   ZoneGrowableArray<BitVector*>* loop_invariant_loads_;
   ZoneGrowableArray<const Field*>* guarded_fields_;
+  GrowableArray<const Field*> deoptimize_dependent_code_;
   ZoneGrowableArray<const LibraryPrefix*>* deferred_prefixes_;
   DirectChainedHashMap<ConstantPoolTrait> constant_instr_pool_;
   BitVector* captured_parameters_;
diff --git a/runtime/vm/flow_graph_allocator.cc b/runtime/vm/flow_graph_allocator.cc
index 208a4af..e832212 100644
--- a/runtime/vm/flow_graph_allocator.cc
+++ b/runtime/vm/flow_graph_allocator.cc
@@ -101,24 +101,11 @@
 
   // All registers are marked as "not blocked" (array initialized to false).
   // Mark the unavailable ones as "blocked" (true).
-  for (intptr_t i = 0; i < kFirstFreeCpuRegister; i++) {
-    blocked_cpu_registers_[i] = true;
+  for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) {
+    if ((kDartAvailableCpuRegs & (1 << i)) == 0) {
+      blocked_cpu_registers_[i] = true;
+    }
   }
-  for (intptr_t i = kLastFreeCpuRegister + 1; i < kNumberOfCpuRegisters; i++) {
-    blocked_cpu_registers_[i] = true;
-  }
-  if (TMP != kNoRegister) {
-    blocked_cpu_registers_[TMP] = true;
-  }
-  if (TMP2 != kNoRegister) {
-    blocked_cpu_registers_[TMP2] = true;
-  }
-  if (PP != kNoRegister) {
-    blocked_cpu_registers_[PP] = true;
-  }
-  blocked_cpu_registers_[SPREG] = true;
-  blocked_cpu_registers_[FPREG] = true;
-  blocked_cpu_registers_[THR] = true;
 
   // FpuTMP is used as scratch by optimized code and parallel move resolver.
   blocked_fpu_registers_[FpuTMP] = true;
@@ -128,6 +115,11 @@
   // generating intrinsic code.
   if (intrinsic_mode) {
     blocked_cpu_registers_[ARGS_DESC_REG] = true;
+#if !defined(TARGET_ARCH_IA32)
+    // Need to preserve CODE_REG to be able to store the PC marker
+    // and load the pool pointer.
+    blocked_cpu_registers_[CODE_REG] = true;
+#endif
   }
 }
 
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index ea31f96..309ad04 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -7,6 +7,7 @@
 #include "lib/invocation_mirror.h"
 #include "vm/ast_printer.h"
 #include "vm/bit_vector.h"
+#include "vm/compiler.h"
 #include "vm/class_finalizer.h"
 #include "vm/exceptions.h"
 #include "vm/flags.h"
@@ -38,8 +39,6 @@
 DEFINE_FLAG(bool, support_debugger, true, "Emit code needed for debugging");
 DEFINE_FLAG(bool, trace_type_check_elimination, false,
             "Trace type check elimination at compile time.");
-DEFINE_FLAG(bool, precompile_collect_closures, false,
-            "Collect all closure functions referenced from compiled code.");
 
 DECLARE_FLAG(int, optimization_counter_threshold);
 DECLARE_FLAG(bool, profile_vm);
@@ -549,6 +548,10 @@
     call_->previous()->AppendInstruction(branch);
     call_block->set_last_instruction(branch);
 
+    // Replace uses of the return value with null to maintain valid
+    // SSA form - even though the rest of the caller is unreachable.
+    call_->ReplaceUsesWith(caller_graph_->constant_null());
+
     // Update dominator tree.
     call_block->AddDominatedBlock(callee_entry);
     call_block->AddDominatedBlock(false_block);
@@ -954,8 +957,7 @@
 
 void TestGraphVisitor::ReturnValue(Value* value) {
   Isolate* isolate = Isolate::Current();
-  if (isolate->flags().type_checks() ||
-      isolate->flags().asserts()) {
+  if (isolate->flags().type_checks() || isolate->flags().asserts()) {
     value = Bind(new(Z) AssertBooleanInstr(condition_token_pos(), value));
   }
   Value* constant_true = Bind(new(Z) ConstantInstr(Bool::True()));
@@ -1315,8 +1317,7 @@
     node->left()->Visit(&for_left);
     EffectGraphVisitor empty(owner());
     Isolate* isolate = Isolate::Current();
-    if (isolate->flags().type_checks() ||
-        isolate->flags().asserts()) {
+    if (isolate->flags().type_checks() || isolate->flags().asserts()) {
       ValueGraphVisitor for_right(owner());
       node->right()->Visit(&for_right);
       Value* right_value = for_right.value();
@@ -1337,37 +1338,8 @@
       }
     }
     return;
-  } else if (node->kind() == Token::kIFNULL) {
-    // left ?? right. This operation cannot be overloaded.
-    // temp = left; temp === null ? right : temp
-    ValueGraphVisitor for_left_value(owner());
-    node->left()->Visit(&for_left_value);
-    Append(for_left_value);
-    Do(BuildStoreExprTemp(for_left_value.value()));
-
-    LocalVariable* temp_var = owner()->parsed_function().expression_temp_var();
-    LoadLocalNode* load_temp =
-        new(Z) LoadLocalNode(Scanner::kNoSourcePos, temp_var);
-    LiteralNode* null_constant =
-        new(Z) LiteralNode(Scanner::kNoSourcePos, Object::null_instance());
-    ComparisonNode* check_is_null =
-        new(Z) ComparisonNode(Scanner::kNoSourcePos,
-                              Token::kEQ_STRICT,
-                              load_temp,
-                              null_constant);
-    TestGraphVisitor for_test(owner(), Scanner::kNoSourcePos);
-    check_is_null->Visit(&for_test);
-
-    ValueGraphVisitor for_right_value(owner());
-    node->right()->Visit(&for_right_value);
-    for_right_value.Do(BuildStoreExprTemp(for_right_value.value()));
-
-    ValueGraphVisitor for_temp(owner());
-    // Nothing to do, left value is already loaded into temp.
-
-    Join(for_test, for_right_value, for_temp);
-    return;
   }
+  ASSERT(node->kind() != Token::kIFNULL);
   ValueGraphVisitor for_left_value(owner());
   node->left()->Visit(&for_left_value);
   Append(for_left_value);
@@ -1412,8 +1384,7 @@
     node->right()->Visit(&for_right);
     Value* right_value = for_right.value();
     Isolate* isolate = Isolate::Current();
-    if (isolate->flags().type_checks() ||
-        isolate->flags().asserts()) {
+    if (isolate->flags().type_checks() || isolate->flags().asserts()) {
       right_value =
           for_right.Bind(new(Z) AssertBooleanInstr(node->right()->token_pos(),
                                                    right_value));
@@ -1442,37 +1413,6 @@
     }
     ReturnDefinition(BuildLoadExprTemp());
     return;
-  } else if (node->kind() == Token::kIFNULL) {
-    // left ?? right. This operation cannot be overloaded.
-    // temp = left; temp === null ? right : temp
-    ValueGraphVisitor for_left_value(owner());
-    node->left()->Visit(&for_left_value);
-    Append(for_left_value);
-    Do(BuildStoreExprTemp(for_left_value.value()));
-
-    LocalVariable* temp_var = owner()->parsed_function().expression_temp_var();
-    LoadLocalNode* load_temp =
-        new(Z) LoadLocalNode(Scanner::kNoSourcePos, temp_var);
-    LiteralNode* null_constant =
-        new(Z) LiteralNode(Scanner::kNoSourcePos, Object::null_instance());
-    ComparisonNode* check_is_null =
-        new(Z) ComparisonNode(Scanner::kNoSourcePos,
-                              Token::kEQ_STRICT,
-                              load_temp,
-                              null_constant);
-    TestGraphVisitor for_test(owner(), Scanner::kNoSourcePos);
-    check_is_null->Visit(&for_test);
-
-    ValueGraphVisitor for_right_value(owner());
-    node->right()->Visit(&for_right_value);
-    for_right_value.Do(BuildStoreExprTemp(for_right_value.value()));
-
-    ValueGraphVisitor for_temp(owner());
-    // Nothing to do, left value is already loaded into temp.
-
-    Join(for_test, for_right_value, for_temp);
-    ReturnDefinition(BuildLoadExprTemp());
-    return;
   }
 
   EffectGraphVisitor::VisitBinaryOpNode(node);
@@ -1878,8 +1818,7 @@
         owner()->ic_data_array());
     if (node->kind() == Token::kNE) {
       Isolate* isolate = Isolate::Current();
-      if (isolate->flags().type_checks() ||
-          isolate->flags().asserts()) {
+      if (isolate->flags().type_checks() || isolate->flags().asserts()) {
         Value* value = Bind(result);
         result = new(Z) AssertBooleanInstr(node->token_pos(), value);
       }
@@ -1926,8 +1865,7 @@
     Append(for_value);
     Value* value = for_value.value();
     Isolate* isolate = Isolate::Current();
-    if (isolate->flags().type_checks() ||
-        isolate->flags().asserts()) {
+    if (isolate->flags().type_checks() || isolate->flags().asserts()) {
       value =
           Bind(new(Z) AssertBooleanInstr(node->operand()->token_pos(), value));
     }
@@ -2525,37 +2463,15 @@
 }
 
 
-// TODO(rmacnak): De-dup closures in inlined-finally and track down other
-// stragglers to use Class::closures instead.
-static void CollectClosureFunction(const Function& function) {
-  if (function.HasCode()) return;
-
-  // Although this is only called when precompiling, this can happen before
-  // Dart_Precompile as part of loading code, so check for a non-null work
-  // list.
-  Thread* thread = Thread::Current();
-  Isolate* isolate = thread->isolate();
-  if (isolate->collected_closures() != GrowableObjectArray::null()) {
-    const GrowableObjectArray& functions =
-        GrowableObjectArray::Handle(thread->zone(),
-                                    isolate->collected_closures());
-    functions.Add(function);
-  }
-}
-
-
 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) {
   const Function& function = node->function();
-  if (FLAG_precompile_collect_closures) {
-    CollectClosureFunction(function);
-  }
-
   if (function.IsImplicitStaticClosureFunction()) {
     const Instance& closure =
         Instance::ZoneHandle(Z, function.ImplicitStaticClosure());
     ReturnDefinition(new(Z) ConstantInstr(closure));
     return;
   }
+
   const bool is_implicit = function.IsImplicitInstanceClosureFunction();
   ASSERT(is_implicit || function.IsNonImplicitClosureFunction());
   // The context scope may have already been set by the non-optimizing
@@ -2567,25 +2483,18 @@
     ASSERT(!function.HasCode());
     ASSERT(function.context_scope() == ContextScope::null());
     function.set_context_scope(context_scope);
-    const Class& cls = Class::Handle(Z, owner()->function().Owner());
+
     // The closure is now properly setup, add it to the lookup table.
     // It is possible that the compiler creates more than one function
     // object for the same closure, e.g. when inlining nodes from
     // finally clauses. If we already have a function object for the
-    // same closure, do not add a second one. We compare the origin
-    // class, token position, and parent function to detect duplicates.
-    // Note that we can have two different closure object for the same
-    // source text representation of the closure: one with a non-closurized
-    // parent, and one with a closurized parent function.
-
-    const Function& found_func = Function::Handle(
-        Z, cls.LookupClosureFunction(function.token_pos()));
-
-    if (found_func.IsNull() ||
-        (found_func.token_pos() != function.token_pos()) ||
-        (found_func.script() != function.script()) ||
-        (found_func.parent_function() != function.parent_function())) {
-      cls.AddClosureFunction(function);
+    // same closure, do not add a second one. We compare token position,
+    // and parent function to detect duplicates.
+    const Function& parent = Function::Handle(function.parent_function());
+    const Function& found_func = Function::Handle(Z,
+        isolate()->LookupClosureFunction(parent, function.token_pos()));
+    if (found_func.IsNull()) {
+      isolate()->AddClosureFunction(function);
     }
   }
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
@@ -4673,7 +4582,7 @@
   // When compiling for OSR, use a depth first search to prune instructions
   // unreachable from the OSR entry. Catch entries are always considered
   // reachable, even if they become unreachable after OSR.
-  if (osr_id_ != Thread::kNoDeoptId) {
+  if (osr_id_ != Compiler::kNoOSRDeoptId) {
     PruneUnreachable();
   }
 
@@ -4684,7 +4593,7 @@
 
 
 void FlowGraphBuilder::PruneUnreachable() {
-  ASSERT(osr_id_ != Thread::kNoDeoptId);
+  ASSERT(osr_id_ != Compiler::kNoOSRDeoptId);
   BitVector* block_marks = new(Z) BitVector(Z, last_used_block_id_ + 1);
   bool found = graph_entry_->PruneUnreachable(this, graph_entry_, NULL, osr_id_,
                                               block_marks);
diff --git a/runtime/vm/flow_graph_builder.h b/runtime/vm/flow_graph_builder.h
index 109a9a1..bae0a52 100644
--- a/runtime/vm/flow_graph_builder.h
+++ b/runtime/vm/flow_graph_builder.h
@@ -28,34 +28,6 @@
 class NestedStatement;
 class TestGraphVisitor;
 
-// List of recognized list factories:
-// (factory-name-symbol, result-cid, fingerprint).
-#define RECOGNIZED_LIST_FACTORY_LIST(V)                                        \
-  V(_ListFactory, kArrayCid, 850375012)                                        \
-  V(_GrowableListWithData, kGrowableObjectArrayCid, 2094352700)                \
-  V(_GrowableListFactory, kGrowableObjectArrayCid, 1518848600)                 \
-  V(_Int8ArrayFactory, kTypedDataInt8ArrayCid, 439914696)                      \
-  V(_Uint8ArrayFactory, kTypedDataUint8ArrayCid, 1442599030)                   \
-  V(_Uint8ClampedArrayFactory, kTypedDataUint8ClampedArrayCid, 1320015159)     \
-  V(_Int16ArrayFactory, kTypedDataInt16ArrayCid, 2132591678)                   \
-  V(_Uint16ArrayFactory, kTypedDataUint16ArrayCid, 1704816032)                 \
-  V(_Int32ArrayFactory, kTypedDataInt32ArrayCid, 1115045147)                   \
-  V(_Uint32ArrayFactory, kTypedDataUint32ArrayCid, 1385852190)                 \
-  V(_Int64ArrayFactory, kTypedDataInt64ArrayCid, 1193438555)                   \
-  V(_Uint64ArrayFactory, kTypedDataUint64ArrayCid, 410766246)                  \
-  V(_Float64ArrayFactory, kTypedDataFloat64ArrayCid, 1430631000)               \
-  V(_Float32ArrayFactory, kTypedDataFloat32ArrayCid, 1194249144)               \
-  V(_Float32x4ArrayFactory, kTypedDataFloat32x4ArrayCid, 158753569)            \
-
-
-// Class that recognizes factories and returns corresponding result cid.
-class FactoryRecognizer : public AllStatic {
- public:
-  // Return kDynamicCid if factory is not recognized.
-  static intptr_t ResultCid(const Function& factory);
-};
-
-
 // A class to collect the exits from an inlined function during graph
 // construction so they can be plugged into the caller's flow graph.
 class InlineExitCollector: public ZoneAllocated {
@@ -124,7 +96,7 @@
 class FlowGraphBuilder : public ValueObject {
  public:
   // The inlining context is NULL if not inlining.  The osr_id is the deopt
-  // id of the OSR entry or Thread::kNoDeoptId if not compiling for OSR.
+  // id of the OSR entry or Compiler::kNoOSRDeoptId if not compiling for OSR.
   FlowGraphBuilder(const ParsedFunction& parsed_function,
                    const ZoneGrowableArray<const ICData*>& ic_data_array,
                    InlineExitCollector* exit_collector,
@@ -248,7 +220,7 @@
   // A stack of enclosing nested statements.
   NestedStatement* nesting_stack_;
 
-  // The deopt id of the OSR entry or Thread::kNoDeoptId if not compiling
+  // The deopt id of the OSR entry orCompiler::kNoOSRDeoptId if not compiling
   // for OSR.
   const intptr_t osr_id_;
 
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index dd4adfd..e40887b 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -70,18 +70,20 @@
 DECLARE_FLAG(bool, use_cha_deopt);
 DECLARE_FLAG(bool, use_osr);
 DECLARE_FLAG(bool, warn_on_javascript_compatibility);
-DECLARE_FLAG(bool, precompile_collect_closures);
 DECLARE_FLAG(bool, print_stop_message);
 DECLARE_FLAG(bool, lazy_dispatchers);
 DECLARE_FLAG(bool, interpret_irregexp);
 DECLARE_FLAG(bool, enable_mirrors);
 DECLARE_FLAG(bool, link_natives_lazily);
+DECLARE_FLAG(bool, trace_compiler);
 
+bool FLAG_precompilation = false;
 static void PrecompilationModeHandler(bool value) {
   if (value) {
 #if defined(TARGET_ARCH_IA32)
     FATAL("Precompilation not supported on IA32");
 #endif
+    FLAG_precompilation = true;
 
     FLAG_always_megamorphic_calls = true;
     FLAG_polymorphic_with_deopt = false;
@@ -111,7 +113,6 @@
     FLAG_lazy_dispatchers = false;
     FLAG_interpret_irregexp = true;
     FLAG_enable_mirrors = false;
-    FLAG_precompile_collect_closures = true;
     FLAG_link_natives_lazily = true;
     FLAG_fields_may_be_reset = true;
     FLAG_allow_absolute_addresses = false;
@@ -166,7 +167,6 @@
     const GrowableArray<const Function*>& inline_id_to_function,
     const GrowableArray<intptr_t>& caller_inline_id)
       : thread_(Thread::Current()),
-        isolate_(Isolate::Current()),
         zone_(Thread::Current()->zone()),
         assembler_(assembler),
         parsed_function_(parsed_function),
@@ -183,15 +183,15 @@
         may_reoptimize_(false),
         intrinsic_mode_(false),
         double_class_(Class::ZoneHandle(
-            isolate_->object_store()->double_class())),
+            isolate()->object_store()->double_class())),
         mint_class_(Class::ZoneHandle(
-            isolate_->object_store()->mint_class())),
+            isolate()->object_store()->mint_class())),
         float32x4_class_(Class::ZoneHandle(
-            isolate_->object_store()->float32x4_class())),
+            isolate()->object_store()->float32x4_class())),
         float64x2_class_(Class::ZoneHandle(
-            isolate_->object_store()->float64x2_class())),
+            isolate()->object_store()->float64x2_class())),
         int32x4_class_(Class::ZoneHandle(
-            isolate_->object_store()->int32x4_class())),
+            isolate()->object_store()->int32x4_class())),
         list_class_(Class::ZoneHandle(
             Library::Handle(Library::CoreLibrary()).
                 LookupClass(Symbols::List()))),
@@ -228,6 +228,27 @@
 }
 
 
+bool FlowGraphCompiler::IsUnboxedField(const Field& field) {
+  bool valid_class = (SupportsUnboxedDoubles() &&
+                      (field.guarded_cid() == kDoubleCid)) ||
+                     (SupportsUnboxedSimd128() &&
+                      (field.guarded_cid() == kFloat32x4Cid)) ||
+                     (SupportsUnboxedSimd128() &&
+                      (field.guarded_cid() == kFloat64x2Cid));
+  return field.is_unboxing_candidate()
+      && !field.is_final()
+      && !field.is_nullable()
+      && valid_class;
+}
+
+
+bool FlowGraphCompiler::IsPotentialUnboxedField(const Field& field) {
+  return field.is_unboxing_candidate() &&
+         (FlowGraphCompiler::IsUnboxedField(field) ||
+          (!field.is_final() && (field.guarded_cid() == kIllegalCid)));
+}
+
+
 void FlowGraphCompiler::InitCompiler() {
   pc_descriptors_list_ = new(zone()) DescriptorList(64);
   exception_handlers_list_ = new(zone())ExceptionHandlerList();
@@ -896,7 +917,17 @@
   }
 
   // No deoptimization allowed when 'always_optimize' is set.
-  ASSERT(!Compiler::always_optimize());
+  if (Compiler::always_optimize()) {
+    if (FLAG_trace_compiler) {
+      THR_Print(
+          "Retrying compilation %s, suppressing inlining of deopt_id:%" Pd "\n",
+          parsed_function_.function().ToFullyQualifiedCString(), deopt_id);
+    }
+    ASSERT(deopt_id != 0);  // longjmp must return non-zero value.
+    Thread::Current()->long_jump_base()->Jump(
+        deopt_id, Object::speculative_inlining_error());
+  }
+
   ASSERT(is_optimizing_);
   CompilerDeoptInfoWithStub* stub =
       new(zone()) CompilerDeoptInfoWithStub(deopt_id,
@@ -1090,6 +1121,11 @@
     intptr_t argument_count,
     LocationSummary* locs,
     const ICData& ic_data) {
+  if (Compiler::always_optimize()) {
+    EmitSwitchableInstanceCall(ic_data, argument_count,
+                               deopt_id, token_pos, locs);
+    return;
+  }
   if (FLAG_always_megamorphic_calls) {
     EmitMegamorphicInstanceCall(ic_data, argument_count,
                                 deopt_id, token_pos, locs);
@@ -1099,9 +1135,7 @@
   if (is_optimizing() && (ic_data.NumberOfUsedChecks() == 0)) {
     // Emit IC call that will count and thus may need reoptimization at
     // function entry.
-    ASSERT(!is_optimizing()
-           || may_reoptimize()
-           || flow_graph().IsCompiledForOsr());
+    ASSERT(may_reoptimize() || flow_graph().IsCompiledForOsr());
     switch (ic_data.NumArgsTested()) {
       case 1:
         EmitOptimizedInstanceCall(
@@ -1262,16 +1296,6 @@
 }
 
 
-// Mask of globally reserved registers. Some other registers are only reserved
-// in particular code (e.g., ARGS_DESC_REG in intrinsics).
-static const uword kReservedCpuRegisters = RegMaskBit(SPREG)
-                                         | RegMaskBit(FPREG)
-                                         | RegMaskBit(TMP)
-                                         | RegMaskBit(TMP2)
-                                         | RegMaskBit(PP)
-                                         | RegMaskBit(THR);
-
-
 void FlowGraphCompiler::AllocateRegistersLocally(Instruction* instr) {
   ASSERT(!is_optimizing());
 
@@ -1281,16 +1305,10 @@
 
   bool blocked_registers[kNumberOfCpuRegisters];
 
-  // Mark all available registers free.
+  // Block all registers globally reserved by the assembler, etc and mark
+  // the rest as free.
   for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) {
-    blocked_registers[i] = false;
-  }
-
-  // Block all registers globally reserved by the assembler, etc.
-  for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) {
-    if ((kReservedCpuRegisters & (1 << i)) != 0) {
-      blocked_registers[i] = true;
-    }
+    blocked_registers[i] = (kDartAvailableCpuRegs & (1 << i)) == 0;
   }
 
   // Mark all fixed input, temp and output registers as used.
@@ -1318,14 +1336,6 @@
     blocked_registers[locs->out(0).reg()] = true;
   }
 
-  // Block all non-free registers.
-  for (intptr_t i = 0; i < kFirstFreeCpuRegister; i++) {
-    blocked_registers[i] = true;
-  }
-  for (intptr_t i = kLastFreeCpuRegister + 1; i < kNumberOfCpuRegisters; i++) {
-    blocked_registers[i] = true;
-  }
-
   // Allocate all unallocated input locations.
   const bool should_pop = !instr->IsPushArgument() && !instr->IsPushTemp();
   for (intptr_t i = locs->input_count() - 1; i >= 0; i--) {
@@ -1580,12 +1590,17 @@
   if (resolver->compiler_->intrinsic_mode()) {
     // Block additional registers that must be preserved for intrinsics.
     blocked_mask |= RegMaskBit(ARGS_DESC_REG);
+#if !defined(TARGET_ARCH_IA32)
+    // Need to preserve CODE_REG to be able to store the PC marker
+    // and load the pool pointer.
+    blocked_mask |= RegMaskBit(CODE_REG);
+#endif
   }
   reg_ = static_cast<Register>(
       resolver_->AllocateScratchRegister(Location::kRegister,
                                          blocked_mask,
-                                         kFirstFreeCpuRegister,
-                                         kLastFreeCpuRegister,
+                                         0,
+                                         kNumberOfCpuRegisters - 1,
                                          &spilled_));
 
   if (spilled_) {
diff --git a/runtime/vm/flow_graph_compiler.h b/runtime/vm/flow_graph_compiler.h
index df9f7e4..075e239 100644
--- a/runtime/vm/flow_graph_compiler.h
+++ b/runtime/vm/flow_graph_compiler.h
@@ -281,6 +281,9 @@
   static bool SupportsUnboxedSimd128();
   static bool SupportsHardwareDivision();
 
+  static bool IsUnboxedField(const Field& field);
+  static bool IsPotentialUnboxedField(const Field& field);
+
   // Accessors.
   Assembler* assembler() const { return assembler_; }
   const ParsedFunction& parsed_function() const { return parsed_function_; }
@@ -417,6 +420,12 @@
                                    intptr_t token_pos,
                                    LocationSummary* locs);
 
+  void EmitSwitchableInstanceCall(const ICData& ic_data,
+                                  intptr_t argument_count,
+                                  intptr_t deopt_id,
+                                  intptr_t token_pos,
+                                  LocationSummary* locs);
+
   void EmitTestAndCall(const ICData& ic_data,
                        intptr_t arg_count,
                        const Array& arg_names,
@@ -526,7 +535,7 @@
   }
 
   Thread* thread() const { return thread_; }
-  Isolate* isolate() const { return isolate_; }
+  Isolate* isolate() const { return thread_->isolate(); }
   Zone* zone() const { return zone_; }
 
   void AddStubCallTarget(const Code& code);
@@ -683,7 +692,6 @@
   };
 
   Thread* thread_;
-  Isolate* isolate_;
   Zone* zone_;
   Assembler* assembler_;
   const ParsedFunction& parsed_function_;
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index 444a0d8..a11916d 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -407,7 +407,7 @@
 
 // Uses SubtypeTestCache to store instance class and result.
 // R0: instance to test.
-// Clobbers R1-R5.
+// Clobbers R1-R4,R9.
 // Immediate class test already done.
 // TODO(srdjan): Implement a quicker subtype check, as type test
 // arrays can grow too high, but they may be useful when optimizing
@@ -756,44 +756,44 @@
   const int min_num_pos_args = num_fixed_params;
   const int max_num_pos_args = num_fixed_params + num_opt_pos_params;
 
-  __ ldr(R10, FieldAddress(R4, ArgumentsDescriptor::positional_count_offset()));
+  __ ldr(R6, FieldAddress(R4, ArgumentsDescriptor::positional_count_offset()));
   // Check that min_num_pos_args <= num_pos_args.
   Label wrong_num_arguments;
-  __ CompareImmediate(R10, Smi::RawValue(min_num_pos_args));
+  __ CompareImmediate(R6, Smi::RawValue(min_num_pos_args));
   __ b(&wrong_num_arguments, LT);
   // Check that num_pos_args <= max_num_pos_args.
-  __ CompareImmediate(R10, Smi::RawValue(max_num_pos_args));
+  __ CompareImmediate(R6, Smi::RawValue(max_num_pos_args));
   __ b(&wrong_num_arguments, GT);
 
   // Copy positional arguments.
   // Argument i passed at fp[kParamEndSlotFromFp + num_args - i] is copied
   // to fp[kFirstLocalSlotFromFp - i].
 
-  __ ldr(R7, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
-  // Since R7 and R10 are Smi, use LSL 1 instead of LSL 2.
-  // Let R7 point to the last passed positional argument, i.e. to
+  __ ldr(NOTFP, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
+  // Since NOTFP and R6 are Smi, use LSL 1 instead of LSL 2.
+  // Let NOTFP point to the last passed positional argument, i.e. to
   // fp[kParamEndSlotFromFp + num_args - (num_pos_args - 1)].
-  __ sub(R7, R7, Operand(R10));
-  __ add(R7, FP, Operand(R7, LSL, 1));
-  __ add(R7, R7, Operand((kParamEndSlotFromFp + 1) * kWordSize));
+  __ sub(NOTFP, NOTFP, Operand(R6));
+  __ add(NOTFP, FP, Operand(NOTFP, LSL, 1));
+  __ add(NOTFP, NOTFP, Operand((kParamEndSlotFromFp + 1) * kWordSize));
 
-  // Let R6 point to the last copied positional argument, i.e. to
+  // Let R8 point to the last copied positional argument, i.e. to
   // fp[kFirstLocalSlotFromFp - (num_pos_args - 1)].
-  __ AddImmediate(R6, FP, (kFirstLocalSlotFromFp + 1) * kWordSize);
-  __ sub(R6, R6, Operand(R10, LSL, 1));  // R10 is a Smi.
-  __ SmiUntag(R10);
+  __ AddImmediate(R8, FP, (kFirstLocalSlotFromFp + 1) * kWordSize);
+  __ sub(R8, R8, Operand(R6, LSL, 1));  // R6 is a Smi.
+  __ SmiUntag(R6);
   Label loop, loop_condition;
   __ b(&loop_condition);
   // We do not use the final allocation index of the variable here, i.e.
   // scope->VariableAt(i)->index(), because captured variables still need
   // to be copied to the context that is not yet allocated.
-  const Address argument_addr(R7, R10, LSL, 2);
-  const Address copy_addr(R6, R10, LSL, 2);
+  const Address argument_addr(NOTFP, R6, LSL, 2);
+  const Address copy_addr(R8, R6, LSL, 2);
   __ Bind(&loop);
   __ ldr(IP, argument_addr);
   __ str(IP, copy_addr);
   __ Bind(&loop_condition);
-  __ subs(R10, R10, Operand(1));
+  __ subs(R6, R6, Operand(1));
   __ b(&loop, PL);
 
   // Copy or initialize optional named arguments.
@@ -823,89 +823,89 @@
       opt_param_position[i + 1] = pos;
     }
     // Generate code handling each optional parameter in alphabetical order.
-    __ ldr(R7, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
-    __ ldr(R10,
+    __ ldr(NOTFP, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
+    __ ldr(R6,
            FieldAddress(R4, ArgumentsDescriptor::positional_count_offset()));
-    __ SmiUntag(R10);
-    // Let R7 point to the first passed argument, i.e. to
-    // fp[kParamEndSlotFromFp + num_args - 0]; num_args (R7) is Smi.
-    __ add(R7, FP, Operand(R7, LSL, 1));
-    __ AddImmediate(R7, R7, kParamEndSlotFromFp * kWordSize);
-    // Let R6 point to the entry of the first named argument.
-    __ add(R6, R4, Operand(
+    __ SmiUntag(R6);
+    // Let NOTFP point to the first passed argument, i.e. to
+    // fp[kParamEndSlotFromFp + num_args - 0]; num_args (NOTFP) is Smi.
+    __ add(NOTFP, FP, Operand(NOTFP, LSL, 1));
+    __ AddImmediate(NOTFP, NOTFP, kParamEndSlotFromFp * kWordSize);
+    // Let R8 point to the entry of the first named argument.
+    __ add(R8, R4, Operand(
         ArgumentsDescriptor::first_named_entry_offset() - kHeapObjectTag));
     for (int i = 0; i < num_opt_named_params; i++) {
       Label load_default_value, assign_optional_parameter;
       const int param_pos = opt_param_position[i];
       // Check if this named parameter was passed in.
-      // Load R5 with the name of the argument.
-      __ ldr(R5, Address(R6, ArgumentsDescriptor::name_offset()));
+      // Load R9 with the name of the argument.
+      __ ldr(R9, Address(R8, ArgumentsDescriptor::name_offset()));
       ASSERT(opt_param[i]->name().IsSymbol());
-      __ CompareObject(R5, opt_param[i]->name());
+      __ CompareObject(R9, opt_param[i]->name());
       __ b(&load_default_value, NE);
-      // Load R5 with passed-in argument at provided arg_pos, i.e. at
+      // Load R9 with passed-in argument at provided arg_pos, i.e. at
       // fp[kParamEndSlotFromFp + num_args - arg_pos].
-      __ ldr(R5, Address(R6, ArgumentsDescriptor::position_offset()));
-      // R5 is arg_pos as Smi.
+      __ ldr(R9, Address(R8, ArgumentsDescriptor::position_offset()));
+      // R9 is arg_pos as Smi.
       // Point to next named entry.
-      __ add(R6, R6, Operand(ArgumentsDescriptor::named_entry_size()));
-      __ rsb(R5, R5, Operand(0));
-      Address argument_addr(R7, R5, LSL, 1);  // R5 is a negative Smi.
-      __ ldr(R5, argument_addr);
+      __ add(R8, R8, Operand(ArgumentsDescriptor::named_entry_size()));
+      __ rsb(R9, R9, Operand(0));
+      Address argument_addr(NOTFP, R9, LSL, 1);  // R9 is a negative Smi.
+      __ ldr(R9, argument_addr);
       __ b(&assign_optional_parameter);
       __ Bind(&load_default_value);
-      // Load R5 with default argument.
+      // Load R9 with default argument.
       const Instance& value = parsed_function().DefaultParameterValueAt(
           param_pos - num_fixed_params);
-      __ LoadObject(R5, value);
+      __ LoadObject(R9, value);
       __ Bind(&assign_optional_parameter);
-      // Assign R5 to fp[kFirstLocalSlotFromFp - param_pos].
+      // Assign R9 to fp[kFirstLocalSlotFromFp - param_pos].
       // We do not use the final allocation index of the variable here, i.e.
       // scope->VariableAt(i)->index(), because captured variables still need
       // to be copied to the context that is not yet allocated.
       const intptr_t computed_param_pos = kFirstLocalSlotFromFp - param_pos;
       const Address param_addr(FP, computed_param_pos * kWordSize);
-      __ str(R5, param_addr);
+      __ str(R9, param_addr);
     }
     delete[] opt_param;
     delete[] opt_param_position;
     if (check_correct_named_args) {
-      // Check that R6 now points to the null terminator in the arguments
+      // Check that R8 now points to the null terminator in the arguments
       // descriptor.
-      __ ldr(R5, Address(R6, 0));
-      __ CompareObject(R5, Object::null_object());
+      __ ldr(R9, Address(R8, 0));
+      __ CompareObject(R9, Object::null_object());
       __ b(&all_arguments_processed, EQ);
     }
   } else {
     ASSERT(num_opt_pos_params > 0);
-    __ ldr(R10,
+    __ ldr(R6,
            FieldAddress(R4, ArgumentsDescriptor::positional_count_offset()));
-    __ SmiUntag(R10);
+    __ SmiUntag(R6);
     for (int i = 0; i < num_opt_pos_params; i++) {
       Label next_parameter;
       // Handle this optional positional parameter only if k or fewer positional
       // arguments have been passed, where k is param_pos, the position of this
       // optional parameter in the formal parameter list.
       const int param_pos = num_fixed_params + i;
-      __ CompareImmediate(R10, param_pos);
+      __ CompareImmediate(R6, param_pos);
       __ b(&next_parameter, GT);
-      // Load R5 with default argument.
+      // Load R9 with default argument.
       const Object& value = parsed_function().DefaultParameterValueAt(i);
-      __ LoadObject(R5, value);
-      // Assign R5 to fp[kFirstLocalSlotFromFp - param_pos].
+      __ LoadObject(R9, value);
+      // Assign R9 to fp[kFirstLocalSlotFromFp - param_pos].
       // We do not use the final allocation index of the variable here, i.e.
       // scope->VariableAt(i)->index(), because captured variables still need
       // to be copied to the context that is not yet allocated.
       const intptr_t computed_param_pos = kFirstLocalSlotFromFp - param_pos;
       const Address param_addr(FP, computed_param_pos * kWordSize);
-      __ str(R5, param_addr);
+      __ str(R9, param_addr);
       __ Bind(&next_parameter);
     }
     if (check_correct_named_args) {
-      __ ldr(R7, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
-      __ SmiUntag(R7);
-      // Check that R10 equals R7, i.e. no named arguments passed.
-      __ cmp(R10, Operand(R7));
+      __ ldr(NOTFP, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
+      __ SmiUntag(NOTFP);
+      // Check that R6 equals NOTFP, i.e. no named arguments passed.
+      __ cmp(R6, Operand(NOTFP));
       __ b(&all_arguments_processed, EQ);
     }
   }
@@ -927,17 +927,17 @@
   // an issue anymore.
 
   // R4 : arguments descriptor array.
-  __ ldr(R10, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
-  __ SmiUntag(R10);
-  __ add(R7, FP, Operand((kParamEndSlotFromFp + 1) * kWordSize));
-  const Address original_argument_addr(R7, R10, LSL, 2);
+  __ ldr(R6, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
+  __ SmiUntag(R6);
+  __ add(NOTFP, FP, Operand((kParamEndSlotFromFp + 1) * kWordSize));
+  const Address original_argument_addr(NOTFP, R6, LSL, 2);
   __ LoadObject(IP, Object::null_object());
   Label null_args_loop, null_args_loop_condition;
   __ b(&null_args_loop_condition);
   __ Bind(&null_args_loop);
   __ str(IP, original_argument_addr);
   __ Bind(&null_args_loop_condition);
-  __ subs(R10, R10, Operand(1));
+  __ subs(R6, R6, Operand(1));
   __ b(&null_args_loop, PL);
 }
 
@@ -948,7 +948,7 @@
   // Sequence node has one return node, its input is load field node.
   __ Comment("Inlined Getter");
   __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ LoadFromOffset(kWord, R0, R0, offset - kHeapObjectTag);
+  __ LoadFieldFromOffset(kWord, R0, R0, offset);
   __ Ret();
 }
 
@@ -967,7 +967,7 @@
 }
 
 
-static const Register new_pp = R7;
+static const Register new_pp = NOTFP;
 
 
 void FlowGraphCompiler::EmitFrameEntry() {
@@ -975,7 +975,7 @@
   if (CanOptimizeFunction() &&
       function.IsOptimizable() &&
       (!is_optimizing() || may_reoptimize())) {
-    const Register function_reg = R6;
+    const Register function_reg = R8;
 
     // The pool pointer is not setup before entering the Dart frame.
     // Temporarily setup pool pointer for this dart function.
@@ -993,7 +993,7 @@
                               Function::usage_counter_offset()));
     }
     __ CompareImmediate(R3, GetOptimizationThreshold());
-    ASSERT(function_reg == R6);
+    ASSERT(function_reg == R8);
     __ Branch(*StubCode::OptimizeFunction_entry(), kNotPatchable, new_pp, GE);
   }
   __ Comment("Enter frame");
@@ -1015,7 +1015,7 @@
 //   SP: address of last argument.
 //   FP: caller's frame pointer.
 //   PP: caller's pool pointer.
-//   R5: ic-data.
+//   R9: ic-data.
 //   R4: arguments descriptor array.
 void FlowGraphCompiler::CompileGraph() {
   InitCompiler();
@@ -1225,8 +1225,8 @@
   // reoptimized and which counter needs to be incremented.
   // Pass the function explicitly, it is used in IC stub.
 
-  __ LoadObject(R6, parsed_function().function());
-  __ LoadUniqueObject(R5, ic_data);
+  __ LoadObject(R8, parsed_function().function());
+  __ LoadUniqueObject(R9, ic_data);
   GenerateDartCall(deopt_id,
                    token_pos,
                    stub_entry,
@@ -1243,7 +1243,7 @@
                                          intptr_t token_pos,
                                          LocationSummary* locs) {
   ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
-  __ LoadUniqueObject(R5, ic_data);
+  __ LoadUniqueObject(R9, ic_data);
   GenerateDartCall(deopt_id,
                    token_pos,
                    stub_entry,
@@ -1265,20 +1265,57 @@
   ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
   const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(),
       MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
-  const Register receiverR = R0;
-  const Register cacheR = R1;
-  const Register targetR = R1;
-  __ LoadFromOffset(kWord, receiverR, SP, (argument_count - 1) * kWordSize);
-  __ LoadObject(cacheR, cache);
 
+  __ Comment("MegamorphicCall");
+  __ LoadFromOffset(kWord, R0, SP, (argument_count - 1) * kWordSize);
+  __ LoadObject(R9, cache);
   if (FLAG_use_megamorphic_stub) {
     __ BranchLink(*StubCode::MegamorphicLookup_entry());
-  } else  {
-    StubCode::EmitMegamorphicLookup(assembler(), receiverR, cacheR, targetR);
+  } else {
+    StubCode::EmitMegamorphicLookup(assembler());
   }
-  __ LoadObject(R5, ic_data);
-  __ LoadObject(R4, arguments_descriptor);
-  __ blx(targetR);
+  __ blx(R1);
+
+  AddCurrentDescriptor(RawPcDescriptors::kOther, Thread::kNoDeoptId, token_pos);
+  RecordSafepoint(locs);
+  const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
+  if (is_optimizing()) {
+    AddDeoptIndexAtCall(deopt_id_after, token_pos);
+  } else {
+    // Add deoptimization continuation point after the call and before the
+    // arguments are removed.
+    AddCurrentDescriptor(RawPcDescriptors::kDeopt,
+        deopt_id_after, token_pos);
+  }
+  __ Drop(argument_count);
+}
+
+
+void FlowGraphCompiler::EmitSwitchableInstanceCall(
+    const ICData& ic_data,
+    intptr_t argument_count,
+    intptr_t deopt_id,
+    intptr_t token_pos,
+    LocationSummary* locs) {
+  __ Comment("SwitchableCall");
+  __ LoadFromOffset(kWord, R0, SP, (argument_count - 1) * kWordSize);
+  if (ic_data.NumArgsTested() == 1) {
+    __ LoadUniqueObject(R9, ic_data);
+    __ BranchLinkPatchable(*StubCode::ICLookup_entry());
+  } else {
+    const String& name = String::Handle(zone(), ic_data.target_name());
+    const Array& arguments_descriptor =
+        Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
+    ASSERT(!arguments_descriptor.IsNull() &&
+           (arguments_descriptor.Length() > 0));
+    const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(),
+        MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
+
+    __ LoadUniqueObject(R9, cache);
+    __ BranchLinkPatchable(*StubCode::MegamorphicLookup_entry());
+  }
+  __ blx(R1);
+
   AddCurrentDescriptor(RawPcDescriptors::kOther, Thread::kNoDeoptId, token_pos);
   RecordSafepoint(locs);
   const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
@@ -1302,7 +1339,7 @@
     const ICData& ic_data) {
   const StubEntry* stub_entry =
       StubCode::UnoptimizedStaticCallEntry(ic_data.NumArgsTested());
-  __ LoadObject(R5, ic_data);
+  __ LoadObject(R9, ic_data);
   GenerateDartCall(deopt_id,
                    token_pos,
                    *stub_entry,
diff --git a/runtime/vm/flow_graph_compiler_arm64.cc b/runtime/vm/flow_graph_compiler_arm64.cc
index 2c9a717..53429c8 100644
--- a/runtime/vm/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/flow_graph_compiler_arm64.cc
@@ -948,7 +948,7 @@
   // Sequence node has one return node, its input is load field node.
   __ Comment("Inlined Getter");
   __ LoadFromOffset(R0, SP, 0 * kWordSize);
-  __ LoadFromOffset(R0, R0, offset - kHeapObjectTag);
+  __ LoadFieldFromOffset(R0, R0, offset);
   __ ret();
 }
 
@@ -1255,20 +1255,57 @@
   ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
   const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(),
       MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
-  const Register receiverR = R0;
-  const Register cacheR = R1;
-  const Register targetR = R1;
-  __ LoadFromOffset(receiverR, SP, (argument_count - 1) * kWordSize);
-  __ LoadObject(cacheR, cache);
 
+  __ Comment("MegamorphicCall");
+  __ LoadFromOffset(R0, SP, (argument_count - 1) * kWordSize);
+  __ LoadObject(R5, cache);
   if (FLAG_use_megamorphic_stub) {
     __ BranchLink(*StubCode::MegamorphicLookup_entry());
   } else  {
-    StubCode::EmitMegamorphicLookup(assembler(), receiverR, cacheR, targetR);
+    StubCode::EmitMegamorphicLookup(assembler());
   }
-  __ LoadObject(R5, ic_data);
-  __ LoadObject(R4, arguments_descriptor);
-  __ blr(targetR);
+  __ blr(R1);
+
+  AddCurrentDescriptor(RawPcDescriptors::kOther,
+      Thread::kNoDeoptId, token_pos);
+  RecordSafepoint(locs);
+  const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
+  if (is_optimizing()) {
+    AddDeoptIndexAtCall(deopt_id_after, token_pos);
+  } else {
+    // Add deoptimization continuation point after the call and before the
+    // arguments are removed.
+    AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
+  }
+  __ Drop(argument_count);
+}
+
+
+void FlowGraphCompiler::EmitSwitchableInstanceCall(
+    const ICData& ic_data,
+    intptr_t argument_count,
+    intptr_t deopt_id,
+    intptr_t token_pos,
+    LocationSummary* locs) {
+  __ Comment("SwitchableCall");
+  __ LoadFromOffset(R0, SP, (argument_count - 1) * kWordSize);
+  if (ic_data.NumArgsTested() == 1) {
+    __ LoadUniqueObject(R5, ic_data);
+    __ BranchLinkPatchable(*StubCode::ICLookup_entry());
+  } else {
+    const String& name = String::Handle(zone(), ic_data.target_name());
+    const Array& arguments_descriptor =
+        Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
+    ASSERT(!arguments_descriptor.IsNull() &&
+           (arguments_descriptor.Length() > 0));
+    const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(),
+        MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
+
+    __ LoadUniqueObject(R5, cache);
+    __ BranchLinkPatchable(*StubCode::MegamorphicLookup_entry());
+  }
+  __ blr(R1);
+
   AddCurrentDescriptor(RawPcDescriptors::kOther,
       Thread::kNoDeoptId, token_pos);
   RecordSafepoint(locs);
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index 72dda0a..c6094fe 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -1285,21 +1285,17 @@
   ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
   const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(),
       MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
-  const Register receiverR = ECX;
-  const Register cacheR = EBX;
-  const Register targetR = EBX;
-  __ movl(receiverR, Address(ESP, (argument_count - 1) * kWordSize));
-  __ LoadObject(cacheR, cache);
 
+  __ Comment("MegamorphicCall");
+  __ movl(EBX, Address(ESP, (argument_count - 1) * kWordSize));
+  __ LoadObject(ECX, cache);
   if (FLAG_use_megamorphic_stub) {
     __ Call(*StubCode::MegamorphicLookup_entry());
   } else  {
-    StubCode::EmitMegamorphicLookup(assembler(), receiverR, cacheR, targetR);
+    StubCode::EmitMegamorphicLookup(assembler());
   }
+  __ call(EBX);
 
-  __ LoadObject(ECX, ic_data);
-  __ LoadObject(EDX, arguments_descriptor);
-  __ call(targetR);
   AddCurrentDescriptor(RawPcDescriptors::kOther,
       Thread::kNoDeoptId, token_pos);
   RecordSafepoint(locs);
@@ -1315,6 +1311,17 @@
 }
 
 
+void FlowGraphCompiler::EmitSwitchableInstanceCall(
+    const ICData& ic_data,
+    intptr_t argument_count,
+    intptr_t deopt_id,
+    intptr_t token_pos,
+    LocationSummary* locs) {
+  // Only generated with precompilation.
+  UNREACHABLE();
+}
+
+
 void FlowGraphCompiler::EmitOptimizedStaticCall(
     const Function& function,
     const Array& arguments_descriptor,
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index d2670eb..448b70a 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -964,7 +964,7 @@
   // Sequence node has one return node, its input is load field node.
   __ Comment("Inlined Getter");
   __ lw(V0, Address(SP, 0 * kWordSize));
-  __ lw(V0, Address(V0, offset - kHeapObjectTag));
+  __ LoadFieldFromOffset(V0, V0, offset);
   __ Ret();
 }
 
@@ -1276,21 +1276,57 @@
   ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
   const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(),
       MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
-  __ Comment("MegamorphicInstanceCall");
-  const Register receiverR = T0;
-  const Register cacheR = T1;
-  const Register targetR = T1;
-  __ lw(receiverR, Address(SP, (argument_count - 1) * kWordSize));
-  __ LoadObject(cacheR, cache);
 
+  __ Comment("MegamorphicCall");
+  __ lw(T0, Address(SP, (argument_count - 1) * kWordSize));
+  __ LoadObject(S5, cache);
   if (FLAG_use_megamorphic_stub) {
     __ BranchLink(*StubCode::MegamorphicLookup_entry());
   } else  {
-    StubCode::EmitMegamorphicLookup(assembler(), receiverR, cacheR, targetR);
+    StubCode::EmitMegamorphicLookup(assembler());
   }
-  __ LoadObject(S5, ic_data);
-  __ LoadObject(S4, arguments_descriptor);
-  __ jalr(targetR);
+  __ jalr(T1);
+
+  AddCurrentDescriptor(RawPcDescriptors::kOther,
+      Thread::kNoDeoptId, token_pos);
+  RecordSafepoint(locs);
+  const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
+  if (is_optimizing()) {
+    AddDeoptIndexAtCall(deopt_id_after, token_pos);
+  } else {
+    // Add deoptimization continuation point after the call and before the
+    // arguments are removed.
+    AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
+  }
+  __ Drop(argument_count);
+}
+
+
+void FlowGraphCompiler::EmitSwitchableInstanceCall(
+    const ICData& ic_data,
+    intptr_t argument_count,
+    intptr_t deopt_id,
+    intptr_t token_pos,
+    LocationSummary* locs) {
+  __ Comment("SwitchableCall");
+  __ lw(T0, Address(SP, (argument_count - 1) * kWordSize));
+  if (ic_data.NumArgsTested() == 1) {
+    __ LoadUniqueObject(S5, ic_data);
+    __ BranchLink(*StubCode::ICLookup_entry());
+  } else {
+    const String& name = String::Handle(zone(), ic_data.target_name());
+    const Array& arguments_descriptor =
+        Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
+    ASSERT(!arguments_descriptor.IsNull() &&
+           (arguments_descriptor.Length() > 0));
+    const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(),
+        MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
+
+    __ LoadUniqueObject(S5, cache);
+    __ BranchLink(*StubCode::MegamorphicLookup_entry());
+  }
+  __ jalr(T1);
+
   AddCurrentDescriptor(RawPcDescriptors::kOther,
       Thread::kNoDeoptId, token_pos);
   RecordSafepoint(locs);
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index 2a80633..42b3677 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -1286,20 +1286,17 @@
   ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
   const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(),
       MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
-  const Register receiverR = RDI;
-  const Register cacheR = RBX;
-  const Register targetR = RCX;
-  __ movq(receiverR, Address(RSP, (argument_count - 1) * kWordSize));
-  __ LoadObject(cacheR, cache);
 
+  __ Comment("MegamorphicCall");
+  __ movq(RDI, Address(RSP, (argument_count - 1) * kWordSize));
+  __ LoadObject(RBX, cache);
   if (FLAG_use_megamorphic_stub) {
     __ Call(*StubCode::MegamorphicLookup_entry());
   } else  {
-    StubCode::EmitMegamorphicLookup(assembler(), receiverR, cacheR, targetR);
+    StubCode::EmitMegamorphicLookup(assembler());
   }
-  __ LoadObject(RBX, ic_data);
-  __ LoadObject(R10, arguments_descriptor);
-  __ call(targetR);
+  __ call(RCX);
+
   AddCurrentDescriptor(RawPcDescriptors::kOther,
       Thread::kNoDeoptId, token_pos);
   RecordSafepoint(locs);
@@ -1315,6 +1312,46 @@
 }
 
 
+void FlowGraphCompiler::EmitSwitchableInstanceCall(
+    const ICData& ic_data,
+    intptr_t argument_count,
+    intptr_t deopt_id,
+    intptr_t token_pos,
+    LocationSummary* locs) {
+  __ Comment("SwitchableCall");
+  __ movq(RDI, Address(RSP, (argument_count - 1) * kWordSize));
+  if (ic_data.NumArgsTested() == 1) {
+    __ LoadUniqueObject(RBX, ic_data);
+    __ CallPatchable(*StubCode::ICLookup_entry());
+  } else {
+    const String& name = String::Handle(zone(), ic_data.target_name());
+    const Array& arguments_descriptor =
+        Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
+    ASSERT(!arguments_descriptor.IsNull() &&
+           (arguments_descriptor.Length() > 0));
+    const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(),
+        MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
+
+    __ LoadUniqueObject(RBX, cache);
+    __ CallPatchable(*StubCode::MegamorphicLookup_entry());
+  }
+  __ call(RCX);
+
+  AddCurrentDescriptor(RawPcDescriptors::kOther,
+                       Thread::kNoDeoptId, token_pos);
+  RecordSafepoint(locs);
+  const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
+  if (is_optimizing()) {
+    AddDeoptIndexAtCall(deopt_id_after, token_pos);
+  } else {
+    // Add deoptimization continuation point after the call and before the
+    // arguments are removed.
+    AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
+  }
+  __ Drop(argument_count, RCX);
+}
+
+
 void FlowGraphCompiler::EmitOptimizedStaticCall(
     const Function& function,
     const Array& arguments_descriptor,
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index f8bcb22..930da8d 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -618,9 +618,6 @@
                              function.ToCString(),
                              function.deoptimization_counter()));
 
-    // Make a handle for the unoptimized code so that it is not disconnected
-    // from the function while we are trying to inline it.
-    const Code& unoptimized_code = Code::Handle(function.unoptimized_code());
     // Abort if the inlinable bit on the function is low.
     if (!function.CanBeInlined()) {
       TRACE_INLINING(THR_Print("     Bailout: not inlinable\n"));
@@ -629,6 +626,16 @@
       return false;
     }
 
+    // Function has no type feedback. With precompilation we don't rely on
+    // type feedback.
+    if (!Compiler::always_optimize() &&
+        function.ic_data_array() == Object::null()) {
+      TRACE_INLINING(THR_Print("     Bailout: not compiled yet\n"));
+      PRINT_INLINING_TREE("Not compiled",
+          &call_data->caller, &function, call_data->call);
+      return false;
+    }
+
     // Abort if this function has deoptimized too much.
     if (function.deoptimization_counter() >=
         FLAG_deoptimization_counter_threshold) {
@@ -693,7 +700,8 @@
       // Load IC data for the callee.
       ZoneGrowableArray<const ICData*>* ic_data_array =
             new(Z) ZoneGrowableArray<const ICData*>();
-      function.RestoreICDataMap(ic_data_array);
+      const bool clone_descriptors = Compiler::IsBackgroundCompilation();
+      function.RestoreICDataMap(ic_data_array, clone_descriptors);
 
       // Build the callee graph.
       InlineExitCollector* exit_collector =
@@ -701,7 +709,7 @@
       FlowGraphBuilder builder(*parsed_function,
                                *ic_data_array,
                                exit_collector,
-                               Thread::kNoDeoptId);
+                               Compiler::kNoOSRDeoptId);
       builder.SetInitialBlockId(caller_graph_->max_block_id());
       FlowGraph* callee_graph;
       {
@@ -862,9 +870,6 @@
       FlowGraphInliner::SetInliningId(callee_graph,
           inliner_->NextInlineId(callee_graph->function(),
                                  call_data->caller_inlining_id_));
-      // We allocate a ZoneHandle for the unoptimized code so that it cannot be
-      // disconnected from its function during the rest of compilation.
-      Code::ZoneHandle(unoptimized_code.raw());
       TRACE_INLINING(THR_Print("     Success\n"));
       PRINT_INLINING_TREE(NULL,
           &call_data->caller, &function, call);
@@ -1128,7 +1133,12 @@
       PolymorphicInstanceCallInstr* call = call_info[call_idx].call;
       if (call->with_checks()) {
         // PolymorphicInliner introduces deoptimization paths.
-        if (!FLAG_polymorphic_with_deopt) return;
+        if (!FLAG_polymorphic_with_deopt) {
+          TRACE_INLINING(THR_Print(
+              "  => %s\n     Bailout: call with checks\n",
+              call->instance_call()->function_name().ToCString()));
+          continue;
+        }
         const Function& cl = call_info[call_idx].caller();
         intptr_t caller_inlining_id =
             call_info[call_idx].caller_graph->inlining_id();
@@ -1497,7 +1507,7 @@
     GraphEntryInstr* graph_entry =
         new(Z) GraphEntryInstr(*temp_parsed_function,
                                entry,
-                               Thread::kNoDeoptId);  // No OSR id.
+                               Compiler::kNoOSRDeoptId);
     // Update polymorphic inliner state.
     inlined_entries_.Add(graph_entry);
     exit_collector_->Union(exit_collector);
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 4a1aa37..feb72c1 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -177,9 +177,6 @@
     // Do not make the instance call megamorphic if the callee needs to decode
     // the calling code sequence to lookup the ic data and verify if a warning
     // has already been issued or not.
-    // TryCreateICData is only invoked if the ic_data target has not been called
-    // yet, so no warning can possibly have been issued.
-    ASSERT(!call->ic_data()->IssuedJSWarning());
     if (call->ic_data()->MayCheckForJSWarning()) {
       return false;
     }
@@ -187,8 +184,7 @@
   GrowableArray<intptr_t> class_ids(call->ic_data()->NumArgsTested());
   ASSERT(call->ic_data()->NumArgsTested() <= call->ArgumentCount());
   for (intptr_t i = 0; i < call->ic_data()->NumArgsTested(); i++) {
-    const intptr_t cid = call->PushArgumentAt(i)->value()->Type()->ToCid();
-    class_ids.Add(cid);
+    class_ids.Add(call->PushArgumentAt(i)->value()->Type()->ToCid());
   }
 
   const Token::Kind op_kind = call->token_kind();
@@ -218,10 +214,6 @@
   }
 
   if (all_cids_known) {
-    const Array& args_desc_array = Array::Handle(Z,
-        ArgumentsDescriptor::New(call->ArgumentCount(),
-                                 call->argument_names()));
-    ArgumentsDescriptor args_desc(args_desc_array);
     const Class& receiver_class = Class::Handle(Z,
         isolate()->class_table()->At(class_ids[0]));
     if (!receiver_class.is_finalized()) {
@@ -230,6 +222,10 @@
       // finalized yet.
       return false;
     }
+    const Array& args_desc_array = Array::Handle(Z,
+        ArgumentsDescriptor::New(call->ArgumentCount(),
+                                 call->argument_names()));
+    ArgumentsDescriptor args_desc(args_desc_array);
     const Function& function = Function::Handle(Z,
         Resolver::ResolveDynamicForReceiverClass(
             receiver_class,
@@ -724,12 +720,12 @@
              (to == kUnboxedDouble) &&
              CanConvertUnboxedMintToDouble()) {
     const intptr_t deopt_id = (deopt_target != NULL) ?
-      deopt_target->DeoptimizationTarget() : Thread::kNoDeoptId;
+        deopt_target->DeoptimizationTarget() : Thread::kNoDeoptId;
     ASSERT(CanUnboxDouble());
     converted = new MintToDoubleInstr(use->CopyWithType(), deopt_id);
   } else if ((from == kTagged) && Boxing::Supports(to)) {
     const intptr_t deopt_id = (deopt_target != NULL) ?
-      deopt_target->DeoptimizationTarget() : Thread::kNoDeoptId;
+        deopt_target->DeoptimizationTarget() : Thread::kNoDeoptId;
     converted = UnboxInstr::Create(to, use->CopyWithType(), deopt_id);
   } else if ((to == kTagged) && Boxing::Supports(from)) {
     converted = BoxInstr::Create(from, use->CopyWithType());
@@ -739,7 +735,7 @@
     // "from" and "to" representation. The inserted instructions will
     // trigger a deoptimization if executed. See #12417 for a discussion.
     const intptr_t deopt_id = (deopt_target != NULL) ?
-      deopt_target->DeoptimizationTarget() : Thread::kNoDeoptId;
+        deopt_target->DeoptimizationTarget() : Thread::kNoDeoptId;
     ASSERT(Boxing::Supports(from));
     ASSERT(Boxing::Supports(to));
     Definition* boxed = BoxInstr::Create(from, use->CopyWithType());
@@ -2328,7 +2324,7 @@
 // callee functions, then no class check is needed.
 bool FlowGraphOptimizer::InstanceCallNeedsClassCheck(
     InstanceCallInstr* call, RawFunction::Kind kind) const {
-  if (!FLAG_use_cha_deopt) {
+  if (!FLAG_use_cha_deopt && !isolate()->all_classes_finalized()) {
     // Even if class or function are private, lazy class finalization
     // may later add overriding methods.
     return true;
@@ -3072,74 +3068,7 @@
 
   if (IsSupportedByteArrayViewCid(class_ids[0]) &&
       (ic_data.NumberOfChecks() == 1)) {
-    // For elements that may not fit into a smi on all platforms, check if
-    // elements fit into a smi or the platform supports unboxed mints.
-    if ((recognized_kind == MethodRecognizer::kByteArrayBaseGetInt32) ||
-        (recognized_kind == MethodRecognizer::kByteArrayBaseGetUint32) ||
-        (recognized_kind == MethodRecognizer::kByteArrayBaseSetInt32) ||
-        (recognized_kind == MethodRecognizer::kByteArrayBaseSetUint32)) {
-      if (!CanUnboxInt32()) {
-        return false;
-      }
-    }
-
-    if ((recognized_kind == MethodRecognizer::kByteArrayBaseGetFloat32) ||
-        (recognized_kind == MethodRecognizer::kByteArrayBaseGetFloat64) ||
-        (recognized_kind == MethodRecognizer::kByteArrayBaseSetFloat32) ||
-        (recognized_kind == MethodRecognizer::kByteArrayBaseSetFloat64)) {
-      if (!CanUnboxDouble()) {
-        return false;
-      }
-    }
-
-    switch (recognized_kind) {
-      // ByteArray getters.
-      case MethodRecognizer::kByteArrayBaseGetInt8:
-        return BuildByteArrayBaseLoad(call, kTypedDataInt8ArrayCid);
-      case MethodRecognizer::kByteArrayBaseGetUint8:
-        return BuildByteArrayBaseLoad(call, kTypedDataUint8ArrayCid);
-      case MethodRecognizer::kByteArrayBaseGetInt16:
-        return BuildByteArrayBaseLoad(call, kTypedDataInt16ArrayCid);
-      case MethodRecognizer::kByteArrayBaseGetUint16:
-        return BuildByteArrayBaseLoad(call, kTypedDataUint16ArrayCid);
-      case MethodRecognizer::kByteArrayBaseGetInt32:
-        return BuildByteArrayBaseLoad(call, kTypedDataInt32ArrayCid);
-      case MethodRecognizer::kByteArrayBaseGetUint32:
-        return BuildByteArrayBaseLoad(call, kTypedDataUint32ArrayCid);
-      case MethodRecognizer::kByteArrayBaseGetFloat32:
-        return BuildByteArrayBaseLoad(call, kTypedDataFloat32ArrayCid);
-      case MethodRecognizer::kByteArrayBaseGetFloat64:
-        return BuildByteArrayBaseLoad(call, kTypedDataFloat64ArrayCid);
-      case MethodRecognizer::kByteArrayBaseGetFloat32x4:
-        return BuildByteArrayBaseLoad(call, kTypedDataFloat32x4ArrayCid);
-      case MethodRecognizer::kByteArrayBaseGetInt32x4:
-        return BuildByteArrayBaseLoad(call, kTypedDataInt32x4ArrayCid);
-
-      // ByteArray setters.
-      case MethodRecognizer::kByteArrayBaseSetInt8:
-        return BuildByteArrayBaseStore(call, kTypedDataInt8ArrayCid);
-      case MethodRecognizer::kByteArrayBaseSetUint8:
-        return BuildByteArrayBaseStore(call, kTypedDataUint8ArrayCid);
-      case MethodRecognizer::kByteArrayBaseSetInt16:
-        return BuildByteArrayBaseStore(call, kTypedDataInt16ArrayCid);
-      case MethodRecognizer::kByteArrayBaseSetUint16:
-        return BuildByteArrayBaseStore(call, kTypedDataUint16ArrayCid);
-      case MethodRecognizer::kByteArrayBaseSetInt32:
-        return BuildByteArrayBaseStore(call, kTypedDataInt32ArrayCid);
-      case MethodRecognizer::kByteArrayBaseSetUint32:
-        return BuildByteArrayBaseStore(call, kTypedDataUint32ArrayCid);
-      case MethodRecognizer::kByteArrayBaseSetFloat32:
-        return BuildByteArrayBaseStore(call, kTypedDataFloat32ArrayCid);
-      case MethodRecognizer::kByteArrayBaseSetFloat64:
-        return BuildByteArrayBaseStore(call, kTypedDataFloat64ArrayCid);
-      case MethodRecognizer::kByteArrayBaseSetFloat32x4:
-        return BuildByteArrayBaseStore(call, kTypedDataFloat32x4ArrayCid);
-      case MethodRecognizer::kByteArrayBaseSetInt32x4:
-        return BuildByteArrayBaseStore(call, kTypedDataInt32x4ArrayCid);
-      default:
-        // Unsupported method.
-        return false;
-    }
+    return TryReplaceInstanceCallWithInline(call);
   }
 
   if ((class_ids[0] == kFloat32x4Cid) && (ic_data.NumberOfChecks() == 1)) {
@@ -3932,38 +3861,6 @@
 }
 
 
-bool FlowGraphOptimizer::BuildByteArrayBaseLoad(InstanceCallInstr* call,
-                                                intptr_t view_cid) {
-  const bool simd_view = (view_cid == kTypedDataFloat32x4ArrayCid) ||
-                         (view_cid == kTypedDataInt32x4ArrayCid);
-  const bool float_view = (view_cid == kTypedDataFloat32ArrayCid) ||
-                          (view_cid == kTypedDataFloat64ArrayCid);
-  if (float_view && !CanUnboxDouble()) {
-    return false;
-  }
-  if (simd_view && !ShouldInlineSimd()) {
-    return false;
-  }
-  return TryReplaceInstanceCallWithInline(call);
-}
-
-
-bool FlowGraphOptimizer::BuildByteArrayBaseStore(InstanceCallInstr* call,
-                                                 intptr_t view_cid) {
-  const bool simd_view = (view_cid == kTypedDataFloat32x4ArrayCid) ||
-                         (view_cid == kTypedDataInt32x4ArrayCid);
-  const bool float_view = (view_cid == kTypedDataFloat32ArrayCid) ||
-                          (view_cid == kTypedDataFloat64ArrayCid);
-  if (float_view && !CanUnboxDouble()) {
-    return false;
-  }
-  if (simd_view && !ShouldInlineSimd()) {
-    return false;
-  }
-  return TryReplaceInstanceCallWithInline(call);
-}
-
-
 // If type tests specified by 'ic_data' do not depend on type arguments,
 // return mapping cid->result in 'results' (i : cid; i + 1: result).
 // If all tests yield the same result, return it otherwise return Bool::null.
@@ -4043,13 +3940,15 @@
 
   // Private classes cannot be subclassed by later loaded libs.
   if (!type_class.IsPrivate()) {
-    if (FLAG_use_cha_deopt) {
+    if (FLAG_use_cha_deopt || isolate()->all_classes_finalized()) {
       if (FLAG_trace_cha) {
         THR_Print("  **(CHA) Typecheck as class equality since no "
             "subclasses: %s\n",
             type_class.ToCString());
       }
-      thread()->cha()->AddToLeafClasses(type_class);
+      if (FLAG_use_cha_deopt) {
+        thread()->cha()->AddToLeafClasses(type_class);
+      }
     } else {
       return false;
     }
@@ -4303,23 +4202,20 @@
 }
 
 
+bool FlowGraphOptimizer::IsBlackListedForInlining(intptr_t call_deopt_id) {
+  for (intptr_t i = 0; i < inlining_black_list_->length(); ++i) {
+    if ((*inlining_black_list_)[i] == call_deopt_id) return true;
+  }
+  return false;
+}
+
 // Special optimizations when running in --noopt mode.
 void FlowGraphOptimizer::InstanceCallNoopt(InstanceCallInstr* instr) {
   // TODO(srdjan): Investigate other attempts, as they are not allowed to
   // deoptimize.
-  const Token::Kind op_kind = instr->token_kind();
-  if (instr->HasICData() && (instr->ic_data()->NumberOfUsedChecks() > 0)) {
-    const ICData& unary_checks =
-        ICData::ZoneHandle(Z, instr->ic_data()->AsUnaryClassChecks());
-
-    PolymorphicInstanceCallInstr* call =
-        new(Z) PolymorphicInstanceCallInstr(instr, unary_checks,
-                                            true /* call_with_checks*/);
-    instr->ReplaceWith(call, current_iterator());
-    return;
-  }
 
   // Type test is special as it always gets converted into inlined code.
+  const Token::Kind op_kind = instr->token_kind();
   if (Token::IsTypeTestOperator(op_kind)) {
     ReplaceWithInstanceOf(instr);
     return;
@@ -4328,6 +4224,126 @@
     ReplaceWithTypeCast(instr);
     return;
   }
+
+  if ((op_kind == Token::kGET) &&
+      TryInlineInstanceGetter(instr, false /* no checks allowed */)) {
+    return;
+  }
+  const ICData& unary_checks =
+      ICData::ZoneHandle(Z, instr->ic_data()->AsUnaryClassChecks());
+  if ((unary_checks.NumberOfChecks() > 0) &&
+      (op_kind == Token::kSET) &&
+      TryInlineInstanceSetter(instr, unary_checks, false /* no checks */)) {
+    return;
+  }
+
+  if (use_speculative_inlining_ &&
+      !IsBlackListedForInlining(instr->deopt_id()) &&
+      (unary_checks.NumberOfChecks() > 0)) {
+    if ((op_kind == Token::kINDEX) && TryReplaceWithIndexedOp(instr)) {
+      return;
+    }
+    if ((op_kind == Token::kASSIGN_INDEX) && TryReplaceWithIndexedOp(instr)) {
+      return;
+    }
+    if ((op_kind == Token::kEQ) && TryReplaceWithEqualityOp(instr, op_kind)) {
+      return;
+    }
+
+    if (Token::IsRelationalOperator(op_kind) &&
+        TryReplaceWithRelationalOp(instr, op_kind)) {
+      return;
+    }
+
+    if (Token::IsBinaryOperator(op_kind) &&
+        TryReplaceWithBinaryOp(instr, op_kind)) {
+      return;
+    }
+    if (Token::IsUnaryOperator(op_kind) &&
+        TryReplaceWithUnaryOp(instr, op_kind)) {
+      return;
+    }
+  }
+
+  bool has_one_target =
+      (unary_checks.NumberOfChecks() > 0) && unary_checks.HasOneTarget();
+  if (has_one_target) {
+    // Check if the single target is a polymorphic target, if it is,
+    // we don't have one target.
+    const Function& target =
+        Function::Handle(Z, unary_checks.GetTargetAt(0));
+    const bool polymorphic_target = MethodRecognizer::PolymorphicTarget(target);
+    has_one_target = !polymorphic_target;
+  }
+
+  if (has_one_target) {
+    RawFunction::Kind function_kind =
+        Function::Handle(Z, unary_checks.GetTargetAt(0)).kind();
+    if (!InstanceCallNeedsClassCheck(instr, function_kind)) {
+      PolymorphicInstanceCallInstr* call =
+          new(Z) PolymorphicInstanceCallInstr(instr, unary_checks,
+                                              /* with_checks = */ false);
+      instr->ReplaceWith(call, current_iterator());
+      return;
+    }
+  }
+
+  // More than one targets. Generate generic polymorphic call without
+  // deoptimization.
+  if (instr->ic_data()->NumberOfUsedChecks() > 0) {
+    ASSERT(!FLAG_polymorphic_with_deopt);
+    // OK to use checks with PolymorphicInstanceCallInstr since no
+    // deoptimization is allowed.
+    PolymorphicInstanceCallInstr* call =
+        new(Z) PolymorphicInstanceCallInstr(instr, unary_checks,
+                                            /* with_checks = */ true);
+    instr->ReplaceWith(call, current_iterator());
+    return;
+  }
+
+  // No IC data checks. Try resolve target using the propagated type.
+  // If the propagated type has a method with the target name and there are
+  // no overrides with that name according to CHA, call the method directly.
+  const intptr_t receiver_cid =
+      instr->PushArgumentAt(0)->value()->Type()->ToCid();
+  if (receiver_cid == kDynamicCid) return;
+  const Class& receiver_class = Class::Handle(Z,
+      isolate()->class_table()->At(receiver_cid));
+
+  const Array& args_desc_array = Array::Handle(Z,
+      ArgumentsDescriptor::New(instr->ArgumentCount(),
+                               instr->argument_names()));
+  ArgumentsDescriptor args_desc(args_desc_array);
+  const Function& function = Function::Handle(Z,
+      Resolver::ResolveDynamicForReceiverClass(
+          receiver_class,
+          instr->function_name(),
+          args_desc));
+  if (function.IsNull()) {
+    return;
+  }
+  if (!thread()->cha()->HasOverride(receiver_class, instr->function_name())) {
+    if (FLAG_trace_cha) {
+      THR_Print("  **(CHA) Instance call needs no check, "
+          "no overrides of '%s' '%s'\n",
+          instr->function_name().ToCString(), receiver_class.ToCString());
+    }
+    thread()->cha()->AddToLeafClasses(receiver_class);
+
+    // Create fake IC data with the resolved target.
+    const ICData& ic_data = ICData::Handle(
+        ICData::New(flow_graph_->function(),
+                    instr->function_name(),
+                    args_desc_array,
+                    Thread::kNoDeoptId,
+                    /* args_tested = */ 1));
+    ic_data.AddReceiverCheck(receiver_class.id(), function);
+    PolymorphicInstanceCallInstr* call =
+        new(Z) PolymorphicInstanceCallInstr(instr, ic_data,
+                                            /* with_checks = */ false);
+    instr->ReplaceWith(call, current_iterator());
+    return;
+  }
 }
 
 
@@ -4418,10 +4434,9 @@
     RawFunction::Kind function_kind =
         Function::Handle(Z, unary_checks.GetTargetAt(0)).kind();
     if (!InstanceCallNeedsClassCheck(instr, function_kind)) {
-      const bool call_with_checks = false;
       PolymorphicInstanceCallInstr* call =
           new(Z) PolymorphicInstanceCallInstr(instr, unary_checks,
-                                              call_with_checks);
+                                              /* call_with_checks = */ false);
       instr->ReplaceWith(call, current_iterator());
       return;
     }
@@ -4639,7 +4654,14 @@
         }
       }
       field.set_is_unboxing_candidate(false);
-      field.DeoptimizeDependentCode();
+      if (Compiler::IsBackgroundCompilation()) {
+        // Delay deoptimization of dependent code to the code installation time.
+        // The invalidation of the background compilation result occurs only
+        // when the deoptimization is triggered at code installation.
+        flow_graph()->deoptimize_dependent_code().Add(&field);
+      } else {
+        field.DeoptimizeDependentCode();
+      }
     } else {
       FlowGraph::AddToGuardedFields(flow_graph_->guarded_fields(), &field);
     }
@@ -4692,7 +4714,8 @@
 
 
 bool FlowGraphOptimizer::TryInlineInstanceSetter(InstanceCallInstr* instr,
-                                                 const ICData& unary_ic_data) {
+                                                 const ICData& unary_ic_data,
+                                                 bool allow_checks) {
   ASSERT((unary_ic_data.NumberOfChecks() > 0) &&
       (unary_ic_data.NumArgsTested() == 1));
   if (I->flags().type_checks()) {
@@ -4726,9 +4749,15 @@
   ASSERT(!field.IsNull());
 
   if (InstanceCallNeedsClassCheck(instr, RawFunction::kImplicitSetter)) {
+    if (!allow_checks) {
+      return false;
+    }
     AddReceiverCheck(instr);
   }
   if (field.guarded_cid() != kDynamicCid) {
+    if (!allow_checks) {
+      return false;
+    }
     InsertBefore(instr,
                  new(Z) GuardFieldClassInstr(
                      new(Z) Value(instr->ArgumentAt(1)),
@@ -4739,6 +4768,9 @@
   }
 
   if (field.needs_length_check()) {
+    if (!allow_checks) {
+      return false;
+    }
     InsertBefore(instr,
                  new(Z) GuardFieldLengthInstr(
                      new(Z) Value(instr->ArgumentAt(1)),
@@ -5179,8 +5211,11 @@
 
 
 void LICM::OptimisticallySpecializeSmiPhis() {
-  if (!flow_graph()->function().allows_hoisting_check_class()) {
-    // Do not hoist any.
+  if (!flow_graph()->function().allows_hoisting_check_class() ||
+      Compiler::always_optimize()) {
+    // Do not hoist any: Either deoptimized on a hoisted check,
+    // or compiling precompiled code where we can't do optimistic
+    // hoisting of checks.
     return;
   }
 
diff --git a/runtime/vm/flow_graph_optimizer.h b/runtime/vm/flow_graph_optimizer.h
index d0ae717..4a28be0 100644
--- a/runtime/vm/flow_graph_optimizer.h
+++ b/runtime/vm/flow_graph_optimizer.h
@@ -16,9 +16,16 @@
 
 class FlowGraphOptimizer : public FlowGraphVisitor {
  public:
-  explicit FlowGraphOptimizer(FlowGraph* flow_graph)
+  explicit FlowGraphOptimizer(
+      FlowGraph* flow_graph,
+      bool use_speculative_inlining = false,
+      GrowableArray<intptr_t>* inlining_black_list = NULL)
       : FlowGraphVisitor(flow_graph->reverse_postorder()),
-        flow_graph_(flow_graph) { }
+        flow_graph_(flow_graph),
+        use_speculative_inlining_(use_speculative_inlining),
+        inlining_black_list_(inlining_black_list) {
+    ASSERT(!use_speculative_inlining || (inlining_black_list != NULL));
+  }
   virtual ~FlowGraphOptimizer() {}
 
   FlowGraph* flow_graph() const { return flow_graph_; }
@@ -115,7 +122,8 @@
   bool TryInlineInstanceGetter(InstanceCallInstr* call,
                                bool allow_check = true);
   bool TryInlineInstanceSetter(InstanceCallInstr* call,
-                               const ICData& unary_ic_data);
+                               const ICData& unary_ic_data,
+                               bool allow_check = true);
 
   bool TryInlineInstanceMethod(InstanceCallInstr* call);
   bool TryInlineFloat32x4Constructor(StaticCallInstr* call,
@@ -181,11 +189,6 @@
                                         Definition* index,
                                         Instruction** cursor);
 
-  bool BuildByteArrayBaseLoad(InstanceCallInstr* call,
-                              intptr_t view_cid);
-  bool BuildByteArrayBaseStore(InstanceCallInstr* call,
-                               intptr_t view_cid);
-
   // Insert a check of 'to_check' determined by 'unary_checks'.  If the
   // check fails it will deoptimize to 'deopt_id' using the deoptimization
   // environment 'deopt_environment'.  The check is inserted immediately
@@ -268,8 +271,14 @@
 
   const Function& function() const { return flow_graph_->function(); }
 
+  bool IsBlackListedForInlining(intptr_t deopt_id);
+
   FlowGraph* flow_graph_;
 
+  const bool use_speculative_inlining_;
+
+  GrowableArray<intptr_t>* inlining_black_list_;
+
   DISALLOW_COPY_AND_ASSIGN(FlowGraphOptimizer);
 };
 
diff --git a/runtime/vm/flow_graph_range_analysis.cc b/runtime/vm/flow_graph_range_analysis.cc
index 35a7a5d..16cf90c 100644
--- a/runtime/vm/flow_graph_range_analysis.cc
+++ b/runtime/vm/flow_graph_range_analysis.cc
@@ -5,6 +5,7 @@
 #include "vm/flow_graph_range_analysis.h"
 
 #include "vm/bit_vector.h"
+#include "vm/compiler.h"
 #include "vm/il_printer.h"
 
 namespace dart {
@@ -1528,8 +1529,12 @@
 void RangeAnalysis::EliminateRedundantBoundsChecks() {
   if (FLAG_array_bounds_check_elimination) {
     const Function& function = flow_graph_->function();
+    // Generalization only if we have not deoptimized on a generalized
+    // check earlier, or we're compiling precompiled code (no
+    // optimistic hoisting of checks possible)
     const bool try_generalization =
-        function.allows_bounds_check_generalization();
+        function.allows_bounds_check_generalization() &&
+        !Compiler::always_optimize();
 
     BoundsCheckGeneralizer generalizer(this, flow_graph_);
 
@@ -3126,14 +3131,7 @@
     return false;
   }
 
-  RangeBoundary max = CanonicalizeBoundary(
-      RangeBoundary::FromDefinition(index()->definition()),
-      RangeBoundary::PositiveInfinity());
-
-  if (max.OverflowedSmi()) {
-    return false;
-  }
-
+  RangeBoundary max = RangeBoundary::FromDefinition(index()->definition());
 
   RangeBoundary max_upper = max.UpperBound();
   RangeBoundary length_lower = length.LowerBound();
diff --git a/runtime/vm/flow_graph_type_propagator.cc b/runtime/vm/flow_graph_type_propagator.cc
index 3448fd0..986615f 100644
--- a/runtime/vm/flow_graph_type_propagator.cc
+++ b/runtime/vm/flow_graph_type_propagator.cc
@@ -541,7 +541,8 @@
       cid_ = kNullCid;
     } else if (type_->HasResolvedTypeClass()) {
       const Class& type_class = Class::Handle(type_->type_class());
-      CHA* cha = Thread::Current()->cha();
+      Thread* thread = Thread::Current();
+      CHA* cha = thread->cha();
       // Don't infer a cid from an abstract type for signature classes since
       // there can be multiple compatible classes with different cids.
       if (!type_class.IsSignatureClass() &&
@@ -550,12 +551,15 @@
         if (type_class.IsPrivate()) {
           // Type of a private class cannot change through later loaded libs.
           cid_ = type_class.id();
-        } else if (FLAG_use_cha_deopt) {
+        } else if (FLAG_use_cha_deopt ||
+                   thread->isolate()->all_classes_finalized()) {
           if (FLAG_trace_cha) {
             THR_Print("  **(CHA) Compile type not subclassed: %s\n",
                 type_class.ToCString());
           }
-          cha->AddToLeafClasses(type_class);
+          if (FLAG_use_cha_deopt) {
+            cha->AddToLeafClasses(type_class);
+          }
           cid_ = type_class.id();
         } else {
           cid_ = kDynamicCid;
@@ -584,7 +588,11 @@
 
 const AbstractType* CompileType::ToAbstractType() {
   if (type_ == NULL) {
-    ASSERT(cid_ != kIllegalCid);
+    // Type propagation has not run. Return dynamic-type.
+    if (cid_ == kIllegalCid) {
+      type_ = &Type::ZoneHandle(Type::DynamicType());
+      return type_;
+    }
 
     // VM-internal objects don't have a compile-type. Return dynamic-type
     // in this case.
@@ -793,13 +801,16 @@
           // Private classes can never be subclassed by later loaded libs.
           cid = type_class.id();
         } else {
-          if (FLAG_use_cha_deopt) {
+          if (FLAG_use_cha_deopt ||
+              thread->isolate()->all_classes_finalized()) {
             if (FLAG_trace_cha) {
-              THR_Print("  **(CHA) Computing exact type of parameters, "
+              THR_Print("  **(CHA) Computing exact type of receiver, "
                   "no subclasses: %s\n",
                   type_class.ToCString());
             }
-            thread->cha()->AddToLeafClasses(type_class);
+            if (FLAG_use_cha_deopt) {
+              thread->cha()->AddToLeafClasses(type_class);
+            }
             cid = type_class.id();
           }
         }
diff --git a/runtime/vm/globals.h b/runtime/vm/globals.h
index dc7932e..77e486a 100644
--- a/runtime/vm/globals.h
+++ b/runtime/vm/globals.h
@@ -109,7 +109,11 @@
 #elif defined(HOST_ARCH_X64)
 #define COPY_FP_REGISTER(fp) asm volatile ("movq %%rbp, %0" : "=r" (fp) );
 #elif defined(HOST_ARCH_ARM)
+#  if defined(TARGET_OS_MAC)
+#define COPY_FP_REGISTER(fp) asm volatile ("mov %0, r7" : "=r" (fp) );
+#  else
 #define COPY_FP_REGISTER(fp) asm volatile ("mov %0, r11" : "=r" (fp) );
+#  endif
 #elif defined(HOST_ARCH_ARM64)
 #define COPY_FP_REGISTER(fp) asm volatile ("mov %0, x29" : "=r" (fp) );
 #elif defined(HOST_ARCH_MIPS)
diff --git a/runtime/vm/growable_array.h b/runtime/vm/growable_array.h
index 9023948..42b787b 100644
--- a/runtime/vm/growable_array.h
+++ b/runtime/vm/growable_array.h
@@ -110,6 +110,17 @@
     data_[j] = temp;
   }
 
+  // NOTE: Does not preserve array order.
+  void RemoveAt(intptr_t i) {
+    ASSERT(i >= 0);
+    ASSERT(i < length_);
+    intptr_t last = length_ - 1;
+    if (i < last) {
+      Swap(i, last);
+    }
+    RemoveLast();
+  }
+
   // The content is uninitialized after calling it.
   void SetLength(intptr_t new_length);
 
diff --git a/runtime/vm/guard_field_test.cc b/runtime/vm/guard_field_test.cc
index 193d4b7..6d8c47c 100644
--- a/runtime/vm/guard_field_test.cc
+++ b/runtime/vm/guard_field_test.cc
@@ -54,8 +54,10 @@
       "  }\n"
       "}\n"
       "main() {\n"
-      "  runFoo();\n"
-      "  runBar();\n"
+      "  for (int i = 0; i < 100; i++) {\n"
+      "    runFoo();\n"
+      "    runBar();\n"
+      "  }\n"
       "}\n";
   Dart_Handle lib = TestCase::LoadTestScript(script_chars, NULL);
   Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
@@ -103,8 +105,10 @@
       "  }\n"
       "}\n"
       "main() {\n"
-      "  runFoo();\n"
-      "  runBar();\n"
+      "  for (int i = 0; i < 100; i++) {\n"
+      "    runFoo();\n"
+      "    runBar();\n"
+      "  }\n"
       "}\n";
   Dart_Handle lib = TestCase::LoadTestScript(script_chars, NULL);
   Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
@@ -154,8 +158,10 @@
       "  }\n"
       "}\n"
       "main() {\n"
-      "  runFoo();\n"
-      "  runBar();\n"
+      "  for (int i = 0; i < 100; i++) {\n"
+      "    runFoo();\n"
+      "    runBar();\n"
+      "  }\n"
       "}\n";
   Dart_Handle lib = TestCase::LoadTestScript(script_chars, NULL);
   Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
@@ -209,8 +215,10 @@
       "  }\n"
       "}\n"
       "main() {\n"
-      "  runFoo();\n"
-      "  runBar();\n"
+      "  for (int i = 0; i < 100; i++) {\n"
+      "    runFoo();\n"
+      "    runBar();\n"
+      "  }\n"
       "}\n";
   Dart_Handle lib = TestCase::LoadTestScript(script_chars, NULL);
   Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
@@ -256,8 +264,10 @@
       "  var a = new A(l);\n"
       "}\n"
       "main() {\n"
-      "  runFoo();\n"
-      "  runBar();\n"
+      "  for (int i = 0; i < 100; i++) {\n"
+      "    runFoo();\n"
+      "    runBar();\n"
+      "  }\n"
       "}\n";
   Dart_Handle lib = TestCase::LoadTestScript(script_chars, NULL);
   Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
diff --git a/runtime/vm/handles.cc b/runtime/vm/handles.cc
index 7057739..311bd98 100644
--- a/runtime/vm/handles.cc
+++ b/runtime/vm/handles.cc
@@ -8,7 +8,6 @@
 #include "platform/utils.h"
 #include "vm/dart_api_state.h"
 #include "vm/flags.h"
-#include "vm/isolate.h"
 #include "vm/os.h"
 #include "vm/raw_object.h"
 #include "vm/visitor.h"
diff --git a/runtime/vm/handles.h b/runtime/vm/handles.h
index c5bcac7..5e07d6e 100644
--- a/runtime/vm/handles.h
+++ b/runtime/vm/handles.h
@@ -22,12 +22,12 @@
 // - allocation of handles in the current zone (Handle::AllocateZoneHandle).
 //   Handles allocated in this manner are destroyed when the zone is destroyed.
 // - allocation of handles in a scoped manner (Handle::AllocateHandle).
-//   A new scope can be started using HANDLESCOPE(isolate).
+//   A new scope can be started using HANDLESCOPE(thread).
 //   Handles allocated in this manner are destroyed when the HandleScope
 //   object is destroyed.
 // Code that uses scoped handles typically looks as follows:
 //   {
-//     HANDLESCOPE(isolate);
+//     HANDLESCOPE(thread);
 //     const String& str = String::Handle(String::New("abc"));
 //     .....
 //     .....
@@ -50,7 +50,7 @@
 // raw dart objects directly. We use NOHANDLESCOPE to assert that we do not
 // add code that will allocate new handles during this critical area.
 // {
-//   NOHANDLESCOPE(isolate);
+//   NOHANDLESCOPE(thread);
 //   ....
 //   ....
 // }
@@ -316,8 +316,8 @@
 };
 
 // Macro to start a new Handle scope.
-#define HANDLESCOPE(isolate_or_thread)                                         \
-    dart::HandleScope vm_internal_handles_scope_(isolate_or_thread);
+#define HANDLESCOPE(thread)                                                    \
+    dart::HandleScope vm_internal_handles_scope_(thread);
 
 
 // The class NoHandleScope is used in critical regions of the virtual machine
@@ -345,7 +345,6 @@
 class NoHandleScope : public ValueObject {
  public:
   explicit NoHandleScope(Thread* thread) { }
-  explicit NoHandleScope(Isolate* isolate) { }
   NoHandleScope() { }
   ~NoHandleScope() { }
 
@@ -355,8 +354,8 @@
 #endif  // defined(DEBUG)
 
 // Macro to start a no handles scope in the code.
-#define NOHANDLESCOPE(isolate_or_thread)                                       \
-    dart::NoHandleScope no_vm_internal_handles_scope_(isolate_or_thread);
+#define NOHANDLESCOPE(thread)                                                  \
+    dart::NoHandleScope no_vm_internal_handles_scope_(thread);
 
 }  // namespace dart
 
diff --git a/runtime/vm/heap.cc b/runtime/vm/heap.cc
index 2b319fd..71109ee 100644
--- a/runtime/vm/heap.cc
+++ b/runtime/vm/heap.cc
@@ -161,6 +161,7 @@
 void Heap::AllocateExternal(intptr_t size, Space space) {
   ASSERT(Thread::Current()->no_safepoint_scope_depth() == 0);
   if (space == kNew) {
+    isolate()->AssertCurrentThreadIsMutator();
     new_space_.AllocateExternal(size);
     if (new_space_.ExternalInWords() > (FLAG_new_gen_ext_limit * MBInWords)) {
       // Attempt to free some external allocation by a scavenge. (If the total
@@ -473,10 +474,10 @@
 }
 
 
-void Heap::WriteProtect(bool read_only) {
+void Heap::WriteProtect(bool read_only, bool include_code_pages) {
   read_only_ = read_only;
   new_space_.WriteProtect(read_only);
-  old_space_.WriteProtect(read_only);
+  old_space_.WriteProtect(read_only, include_code_pages);
 }
 
 
@@ -787,7 +788,7 @@
 
 
 NoHeapGrowthControlScope::NoHeapGrowthControlScope()
-    : StackResource(Isolate::Current()) {
+    : StackResource(Thread::Current()) {
     Heap* heap = reinterpret_cast<Isolate*>(isolate())->heap();
     current_growth_controller_state_ = heap->GrowthControlState();
     heap->DisableGrowthControl();
@@ -800,15 +801,16 @@
 }
 
 
-WritableVMIsolateScope::WritableVMIsolateScope(Thread* thread)
-    : StackResource(thread) {
-  Dart::vm_isolate()->heap()->WriteProtect(false);
+WritableVMIsolateScope::WritableVMIsolateScope(Thread* thread,
+                                               bool include_code_pages)
+    : StackResource(thread), include_code_pages_(include_code_pages) {
+  Dart::vm_isolate()->heap()->WriteProtect(false, include_code_pages_);
 }
 
 
 WritableVMIsolateScope::~WritableVMIsolateScope() {
   ASSERT(Dart::vm_isolate()->heap()->UsedInWords(Heap::kNew) == 0);
-  Dart::vm_isolate()->heap()->WriteProtect(true);
+  Dart::vm_isolate()->heap()->WriteProtect(true, include_code_pages_);
 }
 
 }  // namespace dart
diff --git a/runtime/vm/heap.h b/runtime/vm/heap.h
index 22a109e..2ef3e3c 100644
--- a/runtime/vm/heap.h
+++ b/runtime/vm/heap.h
@@ -104,7 +104,6 @@
   bool NewContains(uword addr) const;
   bool OldContains(uword addr) const;
   bool CodeContains(uword addr) const;
-  bool StubCodeContains(uword addr) const;
 
   void IterateObjects(ObjectVisitor* visitor) const;
   void IterateOldObjects(ObjectVisitor* visitor) const;
@@ -136,7 +135,7 @@
 
   // Protect access to the heap. Note: Code pages are made
   // executable/non-executable when 'read_only' is true/false, respectively.
-  void WriteProtect(bool read_only);
+  void WriteProtect(bool read_only, bool include_code_pages);
   void WriteProtectCode(bool read_only) {
     old_space_.WriteProtectCode(read_only);
   }
@@ -377,8 +376,11 @@
 // Note: During this scope, the code pages are non-executable.
 class WritableVMIsolateScope : StackResource {
  public:
-  explicit WritableVMIsolateScope(Thread* thread);
+  explicit WritableVMIsolateScope(Thread* thread, bool include_code_pages);
   ~WritableVMIsolateScope();
+
+ private:
+  bool include_code_pages_;
 };
 
 }  // namespace dart
diff --git a/runtime/vm/heap_test.cc b/runtime/vm/heap_test.cc
index e609901..f52a81c 100644
--- a/runtime/vm/heap_test.cc
+++ b/runtime/vm/heap_test.cc
@@ -280,9 +280,9 @@
   const String& obj = String::Handle(String::New("x", Heap::kOld));
   Heap* heap = Thread::Current()->isolate()->heap();
   EXPECT(heap->Contains(RawObject::ToAddr(obj.raw())));
-  heap->WriteProtect(true);
+  heap->WriteProtect(true, true /* include_code_pages */);
   EXPECT(heap->Contains(RawObject::ToAddr(obj.raw())));
-  heap->WriteProtect(false);
+  heap->WriteProtect(false, true /* include_code_pages */);
   EXPECT(heap->Contains(RawObject::ToAddr(obj.raw())));
 }
 
diff --git a/runtime/vm/instructions.h b/runtime/vm/instructions.h
index 0f5b8a5..a271672 100644
--- a/runtime/vm/instructions.h
+++ b/runtime/vm/instructions.h
@@ -21,4 +21,15 @@
 #error Unknown architecture.
 #endif
 
+namespace dart {
+
+class Object;
+class Code;
+
+bool DecodeLoadObjectFromPoolOrThread(uword pc,
+                                      const Code& code,
+                                      Object* obj);
+
+}  // namespace dart
+
 #endif  // VM_INSTRUCTIONS_H_
diff --git a/runtime/vm/instructions_arm.cc b/runtime/vm/instructions_arm.cc
index eec6cfe..36281df 100644
--- a/runtime/vm/instructions_arm.cc
+++ b/runtime/vm/instructions_arm.cc
@@ -65,7 +65,7 @@
   InstructionPattern::DecodeLoadWordFromPool(native_function_load_end,
                                              &reg,
                                              &native_function_pool_index_);
-  ASSERT(reg == R5);
+  ASSERT(reg == R9);
 }
 
 
@@ -169,6 +169,18 @@
 }
 
 
+static bool IsLoadWithOffset(int32_t instr, Register base,
+                             intptr_t* offset, Register* dst) {
+  if ((instr & 0xffff0000) == (0xe5900000 | (base << 16))) {
+    // ldr reg, [base, #+offset]
+    *offset = instr & 0xfff;
+    *dst = static_cast<Register>((instr & 0xf000) >> 12);
+    return true;
+  }
+  return false;
+}
+
+
 // Decodes a load sequence ending at 'end' (the last instruction of the load
 // sequence is the instruction before the one at end).  Returns a pointer to
 // the first instruction in the sequence.  Returns the register being loaded
@@ -180,21 +192,22 @@
   uword start = end - Instr::kInstrSize;
   int32_t instr = Instr::At(start)->InstructionBits();
   intptr_t offset = 0;
-  if ((instr & 0xffff0000) == 0xe5990000) {  // ldr reg, [pp, #+offset]
-    offset = instr & 0xfff;
-    *reg = static_cast<Register>((instr & 0xf000) >> 12);
+  if (IsLoadWithOffset(instr, PP, &offset, reg)) {
+    // ldr reg, [PP, #+offset]
   } else {
     ASSERT((instr & 0xfff00000) == 0xe5900000);  // ldr reg, [reg, #+offset]
     offset = instr & 0xfff;
     start -= Instr::kInstrSize;
     instr = Instr::At(start)->InstructionBits();
-    if ((instr & 0xffff0000) == 0xe2890000) {  // add reg, pp, operand
+    if ((instr & 0xffff0000) == (0xe2850000 | (PP << 16))) {
+      // add reg, pp, operand
       const intptr_t rot = (instr & 0xf00) >> 7;
       const intptr_t imm8 = instr & 0xff;
       offset += (imm8 >> rot) | (imm8 << (32 - rot));
       *reg = static_cast<Register>((instr & 0xf000) >> 12);
     } else {
-      ASSERT((instr & 0xffff0000) == 0xe0890000);  // add reg, pp, reg
+      ASSERT((instr & 0xffff0000) == (0xe0800000 | (PP << 16)));
+      // add reg, pp, reg
       end = DecodeLoadWordImmediate(end, reg, &offset);
     }
   }
@@ -203,6 +216,30 @@
 }
 
 
+bool DecodeLoadObjectFromPoolOrThread(uword pc,
+                                      const Code& code,
+                                      Object* obj) {
+  ASSERT(code.ContainsInstructionAt(pc));
+
+  int32_t instr = Instr::At(pc)->InstructionBits();
+  intptr_t offset;
+  Register dst;
+  if (IsLoadWithOffset(instr, PP, &offset, &dst)) {
+    intptr_t index = ObjectPool::IndexFromOffset(offset);
+    const ObjectPool& pool = ObjectPool::Handle(code.object_pool());
+    if (pool.InfoAt(index) == ObjectPool::kTaggedObject) {
+      *obj = pool.ObjectAt(index);
+      return true;
+    }
+  } else if (IsLoadWithOffset(instr, THR, &offset, &dst)) {
+    return Thread::ObjectAtOffset(offset, obj);
+  }
+  // TODO(rmacnak): Sequence for loads beyond 12 bits.
+
+  return false;
+}
+
+
 RawICData* CallPattern::IcData() {
   if (ic_data_.IsNull()) {
     Register reg;
@@ -210,7 +247,7 @@
                                          object_pool_,
                                          &reg,
                                          &ic_data_);
-    ASSERT(reg == R5);
+    ASSERT(reg == R9);
   }
   return ic_data_.raw();
 }
@@ -270,6 +307,45 @@
 }
 
 
+SwitchableCallPattern::SwitchableCallPattern(uword pc, const Code& code)
+    : object_pool_(ObjectPool::Handle(code.GetObjectPool())),
+      cache_pool_index_(-1),
+      stub_pool_index_(-1) {
+  ASSERT(code.ContainsInstructionAt(pc));
+  // Last instruction: blx r1.
+  ASSERT(*(reinterpret_cast<uword*>(pc) - 1) == 0xe12fff31);
+
+  Register reg;
+  uword stub_load_end =
+      InstructionPattern::DecodeLoadWordFromPool(pc - 3 * Instr::kInstrSize,
+                                                 &reg,
+                                                 &stub_pool_index_);
+  ASSERT(reg == CODE_REG);
+  InstructionPattern::DecodeLoadWordFromPool(stub_load_end,
+                                             &reg,
+                                             &cache_pool_index_);
+  ASSERT(reg == R9);
+}
+
+
+RawObject* SwitchableCallPattern::cache() const {
+  return reinterpret_cast<RawCode*>(
+      object_pool_.ObjectAt(cache_pool_index_));
+}
+
+
+void SwitchableCallPattern::SetCache(const MegamorphicCache& cache) const {
+  ASSERT(Object::Handle(object_pool_.ObjectAt(cache_pool_index_)).IsICData());
+  object_pool_.SetObjectAt(cache_pool_index_, cache);
+}
+
+
+void SwitchableCallPattern::SetLookupStub(const Code& lookup_stub) const {
+  ASSERT(Object::Handle(object_pool_.ObjectAt(stub_pool_index_)).IsCode());
+  object_pool_.SetObjectAt(stub_pool_index_, lookup_stub);
+}
+
+
 ReturnPattern::ReturnPattern(uword pc)
     : pc_(pc) {
 }
diff --git a/runtime/vm/instructions_arm.h b/runtime/vm/instructions_arm.h
index ad82da1..57d4824 100644
--- a/runtime/vm/instructions_arm.h
+++ b/runtime/vm/instructions_arm.h
@@ -98,6 +98,27 @@
 };
 
 
+// Instance call that can switch from an IC call to a megamorphic call
+//   load ICData             load MegamorphicCache
+//   call ICLookup stub  ->  call MegamorphicLookup stub
+//   call target             call target
+class SwitchableCallPattern : public ValueObject {
+ public:
+  SwitchableCallPattern(uword pc, const Code& code);
+
+  RawObject* cache() const;
+  void SetCache(const MegamorphicCache& cache) const;
+  void SetLookupStub(const Code& stub) const;
+
+ private:
+  const ObjectPool& object_pool_;
+  intptr_t cache_pool_index_;
+  intptr_t stub_pool_index_;
+
+  DISALLOW_COPY_AND_ASSIGN(SwitchableCallPattern);
+};
+
+
 class ReturnPattern : public ValueObject {
  public:
   explicit ReturnPattern(uword pc);
diff --git a/runtime/vm/instructions_arm64.cc b/runtime/vm/instructions_arm64.cc
index 62b3ff2..99c57ba 100644
--- a/runtime/vm/instructions_arm64.cc
+++ b/runtime/vm/instructions_arm64.cc
@@ -259,6 +259,34 @@
 }
 
 
+bool DecodeLoadObjectFromPoolOrThread(uword pc,
+                                      const Code& code,
+                                      Object* obj) {
+  ASSERT(code.ContainsInstructionAt(pc));
+
+  Instr* instr = Instr::At(pc);
+  if (instr->IsLoadStoreRegOp() && (instr->Bit(22) == 1) &&
+      (instr->Bits(30, 2) == 3) && instr->Bit(24) == 1) {
+    intptr_t offset = (instr->Imm12Field() << 3);
+    if (instr->RnField() == PP) {
+      // PP is untagged on ARM64.
+      ASSERT(Utils::IsAligned(offset, 8));
+      intptr_t index = ObjectPool::IndexFromOffset(offset - kHeapObjectTag);
+      const ObjectPool& pool = ObjectPool::Handle(code.object_pool());
+      if (pool.InfoAt(index) == ObjectPool::kTaggedObject) {
+        *obj = pool.ObjectAt(index);
+        return true;
+      }
+    } else if (instr->RnField() == THR) {
+      return Thread::ObjectAtOffset(offset, obj);
+    }
+  }
+  // TODO(rmacnak): Loads with offsets beyond 12 bits.
+
+  return false;
+}
+
+
 // Encodes a load sequence ending at 'end'. Encodes a fixed length two
 // instruction load from the pool pointer in PP using the destination
 // register reg as a temporary for the base address.
@@ -329,6 +357,45 @@
 }
 
 
+SwitchableCallPattern::SwitchableCallPattern(uword pc, const Code& code)
+    : object_pool_(ObjectPool::Handle(code.GetObjectPool())),
+      cache_pool_index_(-1),
+      stub_pool_index_(-1) {
+  ASSERT(code.ContainsInstructionAt(pc));
+  // Last instruction: blr r1.
+  ASSERT(*(reinterpret_cast<uint32_t*>(pc) - 1) == 0xd63f0020);
+
+  Register reg;
+  uword stub_load_end =
+      InstructionPattern::DecodeLoadWordFromPool(pc - 3 * Instr::kInstrSize,
+                                                 &reg,
+                                                 &stub_pool_index_);
+  ASSERT(reg == CODE_REG);
+  InstructionPattern::DecodeLoadWordFromPool(stub_load_end,
+                                             &reg,
+                                             &cache_pool_index_);
+  ASSERT(reg == R5);
+}
+
+
+RawObject* SwitchableCallPattern::cache() const {
+  return reinterpret_cast<RawCode*>(
+      object_pool_.ObjectAt(cache_pool_index_));
+}
+
+
+void SwitchableCallPattern::SetCache(const MegamorphicCache& cache) const {
+  ASSERT(Object::Handle(object_pool_.ObjectAt(cache_pool_index_)).IsICData());
+  object_pool_.SetObjectAt(cache_pool_index_, cache);
+}
+
+
+void SwitchableCallPattern::SetLookupStub(const Code& lookup_stub) const {
+  ASSERT(Object::Handle(object_pool_.ObjectAt(stub_pool_index_)).IsCode());
+  object_pool_.SetObjectAt(stub_pool_index_, lookup_stub);
+}
+
+
 ReturnPattern::ReturnPattern(uword pc)
     : pc_(pc) {
 }
diff --git a/runtime/vm/instructions_arm64.h b/runtime/vm/instructions_arm64.h
index 0d2c96d..6195d52 100644
--- a/runtime/vm/instructions_arm64.h
+++ b/runtime/vm/instructions_arm64.h
@@ -106,6 +106,27 @@
 };
 
 
+// Instance call that can switch from an IC call to a megamorphic call
+//   load ICData             load MegamorphicCache
+//   call ICLookup stub  ->  call MegamorphicLookup stub
+//   call target             call target
+class SwitchableCallPattern : public ValueObject {
+ public:
+  SwitchableCallPattern(uword pc, const Code& code);
+
+  RawObject* cache() const;
+  void SetCache(const MegamorphicCache& cache) const;
+  void SetLookupStub(const Code& stub) const;
+
+ private:
+  const ObjectPool& object_pool_;
+  intptr_t cache_pool_index_;
+  intptr_t stub_pool_index_;
+
+  DISALLOW_COPY_AND_ASSIGN(SwitchableCallPattern);
+};
+
+
 class ReturnPattern : public ValueObject {
  public:
   explicit ReturnPattern(uword pc);
diff --git a/runtime/vm/instructions_ia32.cc b/runtime/vm/instructions_ia32.cc
index 84ba433..2b9f638 100644
--- a/runtime/vm/instructions_ia32.cc
+++ b/runtime/vm/instructions_ia32.cc
@@ -11,6 +11,13 @@
 
 namespace dart {
 
+bool DecodeLoadObjectFromPoolOrThread(uword pc,
+                                      const Code& code,
+                                      Object* obj) {
+  ASSERT(code.ContainsInstructionAt(pc));
+  return false;
+}
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_IA32
diff --git a/runtime/vm/instructions_mips.cc b/runtime/vm/instructions_mips.cc
index dcca54f..cdb2cbe 100644
--- a/runtime/vm/instructions_mips.cc
+++ b/runtime/vm/instructions_mips.cc
@@ -121,6 +121,31 @@
 }
 
 
+bool DecodeLoadObjectFromPoolOrThread(uword pc,
+                                      const Code& code,
+                                      Object* obj) {
+  ASSERT(code.ContainsInstructionAt(pc));
+
+  Instr* instr = Instr::At(pc);
+  if ((instr->OpcodeField() == LW)) {
+    intptr_t offset = instr->SImmField();
+    if (instr->RsField() == PP) {
+      intptr_t index = ObjectPool::IndexFromOffset(offset);
+      const ObjectPool& pool = ObjectPool::Handle(code.object_pool());
+      if (pool.InfoAt(index) == ObjectPool::kTaggedObject) {
+        *obj = pool.ObjectAt(index);
+        return true;
+      }
+    } else if (instr->RsField() == THR) {
+      return Thread::ObjectAtOffset(offset, obj);
+    }
+  }
+  // TODO(rmacnak): Sequence for loads beyond 16 bits.
+
+  return false;
+}
+
+
 RawICData* CallPattern::IcData() {
   if (ic_data_.IsNull()) {
     Register reg;
@@ -210,6 +235,46 @@
 }
 
 
+SwitchableCallPattern::SwitchableCallPattern(uword pc, const Code& code)
+    : object_pool_(ObjectPool::Handle(code.GetObjectPool())),
+      cache_pool_index_(-1),
+      stub_pool_index_(-1) {
+  ASSERT(code.ContainsInstructionAt(pc));
+  // Last instruction: jalr t1.
+  ASSERT(*(reinterpret_cast<uword*>(pc) - 1) == 0);  // Delay slot.
+  ASSERT(*(reinterpret_cast<uword*>(pc) - 2) == 0x0120f809);
+
+  Register reg;
+  uword stub_load_end =
+      InstructionPattern::DecodeLoadWordFromPool(pc - 5 * Instr::kInstrSize,
+                                                 &reg,
+                                                 &stub_pool_index_);
+  ASSERT(reg == CODE_REG);
+  InstructionPattern::DecodeLoadWordFromPool(stub_load_end,
+                                             &reg,
+                                             &cache_pool_index_);
+  ASSERT(reg == S5);
+}
+
+
+RawObject* SwitchableCallPattern::cache() const {
+  return reinterpret_cast<RawCode*>(
+      object_pool_.ObjectAt(cache_pool_index_));
+}
+
+
+void SwitchableCallPattern::SetCache(const MegamorphicCache& cache) const {
+  ASSERT(Object::Handle(object_pool_.ObjectAt(cache_pool_index_)).IsICData());
+  object_pool_.SetObjectAt(cache_pool_index_, cache);
+}
+
+
+void SwitchableCallPattern::SetLookupStub(const Code& lookup_stub) const {
+  ASSERT(Object::Handle(object_pool_.ObjectAt(stub_pool_index_)).IsCode());
+  object_pool_.SetObjectAt(stub_pool_index_, lookup_stub);
+}
+
+
 ReturnPattern::ReturnPattern(uword pc)
     : pc_(pc) {
 }
diff --git a/runtime/vm/instructions_mips.h b/runtime/vm/instructions_mips.h
index fb2e22b..607e835 100644
--- a/runtime/vm/instructions_mips.h
+++ b/runtime/vm/instructions_mips.h
@@ -97,6 +97,27 @@
 };
 
 
+// Instance call that can switch from an IC call to a megamorphic call
+//   load ICData             load MegamorphicCache
+//   call ICLookup stub  ->  call MegamorphicLookup stub
+//   call target             call target
+class SwitchableCallPattern : public ValueObject {
+ public:
+  SwitchableCallPattern(uword pc, const Code& code);
+
+  RawObject* cache() const;
+  void SetCache(const MegamorphicCache& cache) const;
+  void SetLookupStub(const Code& stub) const;
+
+ private:
+  const ObjectPool& object_pool_;
+  intptr_t cache_pool_index_;
+  intptr_t stub_pool_index_;
+
+  DISALLOW_COPY_AND_ASSIGN(SwitchableCallPattern);
+};
+
+
 class ReturnPattern : public ValueObject {
  public:
   explicit ReturnPattern(uword pc);
diff --git a/runtime/vm/instructions_x64.cc b/runtime/vm/instructions_x64.cc
index dc691a4..2dc98bc 100644
--- a/runtime/vm/instructions_x64.cc
+++ b/runtime/vm/instructions_x64.cc
@@ -6,6 +6,7 @@
 #if defined(TARGET_ARCH_X64)
 
 #include "vm/cpu.h"
+#include "vm/constants_x64.h"
 #include "vm/instructions.h"
 #include "vm/object.h"
 
@@ -18,6 +19,44 @@
 }
 
 
+bool DecodeLoadObjectFromPoolOrThread(uword pc,
+                                      const Code& code,
+                                      Object* obj) {
+  ASSERT(code.ContainsInstructionAt(pc));
+
+  uint8_t* bytes = reinterpret_cast<uint8_t*>(pc);
+  COMPILE_ASSERT(PP == R15);
+  if (((bytes[0] == 0x49) && (bytes[1] == 0x8b) && (bytes[2] == 0x9f)) ||
+      ((bytes[0] == 0x49) && (bytes[1] == 0x8b) && (bytes[2] == 0x87)) ||
+      ((bytes[0] == 0x4d) && (bytes[1] == 0x8b) && (bytes[2] == 0xa7)) ||
+      ((bytes[0] == 0x4d) && (bytes[1] == 0x8b) && (bytes[2] == 0x9f)) ||
+      ((bytes[0] == 0x4d) && (bytes[1] == 0x8b) && (bytes[2] == 0x97))) {
+    intptr_t index = IndexFromPPLoad(pc + 3);
+    const ObjectPool& pool = ObjectPool::Handle(code.object_pool());
+    if (pool.InfoAt(index) == ObjectPool::kTaggedObject) {
+      *obj = pool.ObjectAt(index);
+      return true;
+    }
+  }
+  COMPILE_ASSERT(THR == R14);
+  if (((bytes[0] == 0x49) && (bytes[1] == 0x8b) && (bytes[2] == 0x86)) ||
+      ((bytes[0] == 0x49) && (bytes[1] == 0x8b) && (bytes[2] == 0xb6)) ||
+      ((bytes[0] == 0x49) && (bytes[1] == 0x8b) && (bytes[2] == 0x96)) ||
+      ((bytes[0] == 0x49) && (bytes[1] == 0x8b) && (bytes[2] == 0x9e)) ||
+      ((bytes[0] == 0x4d) && (bytes[1] == 0x8b) && (bytes[2] == 0x9e)) ||
+      ((bytes[0] == 0x4d) && (bytes[1] == 0x8b) && (bytes[2] == 0xa6))) {
+    int32_t offset = *reinterpret_cast<int32_t*>(pc + 3);
+    return Thread::ObjectAtOffset(offset, obj);
+  }
+  if (((bytes[0] == 0x4d) && (bytes[1] == 0x8b) && (bytes[2] == 0x5e)) ||
+      ((bytes[0] == 0x4d) && (bytes[1] == 0x8b) && (bytes[2] == 0x6e))) {
+    uint8_t offset = *reinterpret_cast<uint8_t*>(pc + 3);
+    return Thread::ObjectAtOffset(offset, obj);
+  }
+
+  return false;
+}
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_X64
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 2389dfc..4b38ab3 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -5,6 +5,8 @@
 #include "vm/intermediate_language.h"
 
 #include "vm/bit_vector.h"
+#include "vm/bootstrap.h"
+#include "vm/compiler.h"
 #include "vm/constant_propagator.h"
 #include "vm/cpu.h"
 #include "vm/dart_entry.h"
@@ -259,14 +261,14 @@
 bool LoadFieldInstr::IsUnboxedLoad() const {
   return FLAG_unbox_numeric_fields
       && (field() != NULL)
-      && field()->IsUnboxedField();
+      && FlowGraphCompiler::IsUnboxedField(*field());
 }
 
 
 bool LoadFieldInstr::IsPotentialUnboxedLoad() const {
   return FLAG_unbox_numeric_fields
       && (field() != NULL)
-      && field()->IsPotentialUnboxedField();
+      && FlowGraphCompiler::IsPotentialUnboxedField(*field());
 }
 
 
@@ -291,14 +293,14 @@
 bool StoreInstanceFieldInstr::IsUnboxedStore() const {
   return FLAG_unbox_numeric_fields
       && !field().IsNull()
-      && field().IsUnboxedField();
+      && FlowGraphCompiler::IsUnboxedField(field());
 }
 
 
 bool StoreInstanceFieldInstr::IsPotentialUnboxedStore() const {
   return FLAG_unbox_numeric_fields
       && !field().IsNull()
-      && field().IsPotentialUnboxedField();
+      && FlowGraphCompiler::IsPotentialUnboxedField(field());
 }
 
 
@@ -537,6 +539,11 @@
 }
 
 
+bool GraphEntryInstr::IsCompiledForOsr() const {
+  return osr_id_ != Compiler::kNoOSRDeoptId;
+}
+
+
 // ==== Support for visiting flow graphs.
 
 #define DEFINE_ACCEPT(ShortName)                                               \
@@ -3650,6 +3657,30 @@
 }
 
 
+void NativeCallInstr::SetupNative() {
+  Zone* Z = Thread::Current()->zone();
+  const Class& cls = Class::Handle(Z, function().Owner());
+  const Library& library = Library::Handle(Z, cls.library());
+  const int num_params =
+      NativeArguments::ParameterCountForResolution(function());
+  bool auto_setup_scope = true;
+  NativeFunction native_function = NativeEntry::ResolveNative(
+      library, native_name(), num_params, &auto_setup_scope);
+  if (native_function == NULL) {
+    Report::MessageF(Report::kError,
+                     Script::Handle(function().script()),
+                     function().token_pos(),
+                     "native function '%s' (%" Pd " arguments) cannot be found",
+                     native_name().ToCString(),
+                     function().NumParameters());
+  }
+  set_native_c_function(native_function);
+  function().SetIsNativeAutoSetupScope(auto_setup_scope);
+  Dart_NativeEntryResolver resolver = library.native_entry_resolver();
+  bool is_bootstrap_native = Bootstrap::IsBootstapResolver(resolver);
+  set_is_bootstrap_native(is_bootstrap_native);
+}
+
 #undef __
 
 }  // namespace dart
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 7f01ecc..2b9b762 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -337,8 +337,6 @@
 
   const char* ToCString() const;
 
-  const char* DebugName() const { return "Value"; }
-
   bool IsSmiValue() { return Type()->ToCid() == kSmiCid; }
 
   // Returns true if this value binds to the constant: 0xFFFFFFFF.
@@ -1331,7 +1329,7 @@
   }
   ConstantInstr* constant_null();
 
-  bool IsCompiledForOsr() const { return osr_id_ != Thread::kNoDeoptId; }
+  bool IsCompiledForOsr() const;
 
   intptr_t entry_count() const { return entry_count_; }
   void set_entry_count(intptr_t count) { entry_count_ = count; }
@@ -3395,7 +3393,9 @@
 class NativeCallInstr : public TemplateDefinition<0, Throws> {
  public:
   explicit NativeCallInstr(NativeBodyNode* node)
-      : ast_node_(*node) {}
+      : ast_node_(*node),
+        native_c_function_(NULL),
+        is_bootstrap_native_(false) { }
 
   DECLARE_INSTRUCTION(NativeCall)
 
@@ -3408,11 +3408,11 @@
   }
 
   NativeFunction native_c_function() const {
-    return ast_node_.native_c_function();
+    return native_c_function_;
   }
 
   bool is_bootstrap_native() const {
-    return ast_node_.is_bootstrap_native();
+    return is_bootstrap_native_;
   }
 
   bool link_lazily() const {
@@ -3425,8 +3425,18 @@
 
   virtual EffectSet Effects() const { return EffectSet::All(); }
 
+  void SetupNative();
+
  private:
+  void set_native_c_function(NativeFunction value) {
+    native_c_function_ = value;
+  }
+
+  void set_is_bootstrap_native(bool value) { is_bootstrap_native_ = value; }
+
   const NativeBodyNode& ast_node_;
+  NativeFunction native_c_function_;
+  bool is_bootstrap_native_;
 
   DISALLOW_COPY_AND_ASSIGN(NativeCallInstr);
 };
@@ -4366,7 +4376,8 @@
         field_(NULL),
         token_pos_(token_pos) {
     ASSERT(offset_in_bytes >= 0);
-    ASSERT(type.IsZoneHandle());  // May be null if field is not an instance.
+    // May be null if field is not an instance.
+    ASSERT(type.IsZoneHandle() || type.IsReadOnlyHandle());
     SetInputAt(0, instance);
   }
 
@@ -4382,7 +4393,8 @@
         field_(field),
         token_pos_(token_pos) {
     ASSERT(field->IsZoneHandle());
-    ASSERT(type.IsZoneHandle());  // May be null if field is not an instance.
+    // May be null if field is not an instance.
+    ASSERT(type.IsZoneHandle() || type.IsReadOnlyHandle());
     SetInputAt(0, instance);
   }
 
@@ -4457,7 +4469,7 @@
         token_pos_(token_pos),
         type_(type),
         instantiator_class_(instantiator_class) {
-    ASSERT(type.IsZoneHandle());
+    ASSERT(type.IsZoneHandle() || type.IsReadOnlyHandle());
     SetInputAt(0, instantiator);
   }
 
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index f7030f8..878dba1 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -227,8 +227,8 @@
   __ ldr(R2, FieldAddress(R0, Function::entry_point_offset()));
 
   // R2: instructions entry point.
-  // R5: Smi 0 (no IC data; the lazy-compile stub expects a GC-safe value).
-  __ LoadImmediate(R5, 0);
+  // R9: Smi 0 (no IC data; the lazy-compile stub expects a GC-safe value).
+  __ LoadImmediate(R9, 0);
   __ blx(R2);
   compiler->RecordSafepoint(locs());
   // Marks either the continuation point in unoptimized code or the
@@ -925,6 +925,7 @@
 
 
 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  SetupNative();
   const Register result = locs()->out(0).reg();
 
   // Push the result place holder initialized to NULL.
@@ -942,7 +943,7 @@
   uword entry;
   const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function());
   const bool is_leaf_call =
-    (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0;
+      (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0;
   const StubEntry* stub_entry;
   if (link_lazily()) {
     stub_entry = StubCode::CallBootstrapCFunction_entry();
@@ -970,7 +971,7 @@
   }
   __ LoadImmediate(R1, argc_tag);
   ExternalLabel label(entry);
-  __ LoadNativeEntry(R5, &label, link_lazily() ? kPatchable : kNotPatchable);
+  __ LoadNativeEntry(R9, &label, link_lazily() ? kPatchable : kNotPatchable);
   compiler->GenerateCall(token_pos(),
                          *stub_entry,
                          RawPcDescriptors::kOther,
@@ -2008,7 +2009,7 @@
   } else if (IsPotentialUnboxedStore()) {
     summary->set_in(1, ShouldEmitStoreBarrier()
         ? Location::WritableRegister()
-        :  Location::RequiresRegister());
+        : Location::RequiresRegister());
     summary->set_temp(0, Location::RequiresRegister());
     summary->set_temp(1, Location::RequiresRegister());
     summary->set_temp(2, opt ? Location::RequiresFpuRegister()
@@ -2325,8 +2326,8 @@
   __ TryAllocateArray(kArrayCid, instance_size, slow_path,
                       R0,  // instance
                       R3,  // end address
-                      R6,
-                      R10);
+                      R8,
+                      R6);
   // R0: new object start as a tagged pointer.
   // R3: new object end address.
 
@@ -2343,26 +2344,26 @@
   // Initialize all array elements to raw_null.
   // R0: new object start as a tagged pointer.
   // R3: new object end address.
-  // R10: iterator which initially points to the start of the variable
+  // R6: iterator which initially points to the start of the variable
   // data area to be initialized.
-  // R6: null
+  // R8: null
   if (num_elements > 0) {
     const intptr_t array_size = instance_size - sizeof(RawArray);
-    __ LoadObject(R6, Object::null_object());
+    __ LoadObject(R8, Object::null_object());
     if (num_elements >= 2) {
-      __ mov(R7, Operand(R6));
+      __ mov(R9, Operand(R8));
     } else {
 #if defined(DEBUG)
-      // Clobber R7 with an invalid pointer.
-      __ LoadImmediate(R7, 0x1);
+      // Clobber R9 with an invalid pointer.
+      __ LoadImmediate(R9, 0x1);
 #endif  // DEBUG
     }
-    __ AddImmediate(R10, R0, sizeof(RawArray) - kHeapObjectTag);
+    __ AddImmediate(R6, R0, sizeof(RawArray) - kHeapObjectTag);
     if (array_size < (kInlineArraySize * kWordSize)) {
-      __ InitializeFieldsNoBarrierUnrolled(R0, R10, 0, num_elements * kWordSize,
-                                           R6, R7);
+      __ InitializeFieldsNoBarrierUnrolled(R0, R6, 0, num_elements * kWordSize,
+                                           R8, R9);
     } else {
-      __ InitializeFieldsNoBarrier(R0, R10, R3, R6, R7);
+      __ InitializeFieldsNoBarrier(R0, R6, R3, R8, R9);
     }
   }
   __ b(done);
@@ -2445,7 +2446,7 @@
   if (IsUnboxedLoad() && compiler->is_optimizing()) {
     const DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg());
     const Register temp = locs()->temp(0).reg();
-    __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes()));
+    __ LoadFieldFromOffset(kWord, temp, instance_reg, offset_in_bytes());
     const intptr_t cid = field()->UnboxedFieldCid();
     switch (cid) {
       case kDoubleCid:
diff --git a/runtime/vm/intermediate_language_arm64.cc b/runtime/vm/intermediate_language_arm64.cc
index 892a296..7707e0b 100644
--- a/runtime/vm/intermediate_language_arm64.cc
+++ b/runtime/vm/intermediate_language_arm64.cc
@@ -779,6 +779,7 @@
 
 
 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  SetupNative();
   const Register result = locs()->out(0).reg();
 
   // Push the result place holder initialized to NULL.
@@ -796,7 +797,7 @@
   uword entry;
   const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function());
   const bool is_leaf_call =
-    (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0;
+      (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0;
   const StubEntry* stub_entry;
   if (link_lazily()) {
     stub_entry = StubCode::CallBootstrapCFunction_entry();
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index eab55fb..b5a851f 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -818,6 +818,7 @@
 
 
 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  SetupNative();
   Register result = locs()->out(0).reg();
   const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function());
   const bool is_leaf_call =
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index 8c07b90..c005041 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -975,6 +975,7 @@
 
 
 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  SetupNative();
   __ Comment("NativeCallInstr");
   Register result = locs()->out(0).reg();
 
@@ -993,7 +994,7 @@
   uword entry;
   const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function());
   const bool is_leaf_call =
-    (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0;
+      (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0;
   const StubEntry* stub_entry;
   if (link_lazily()) {
     stub_entry = StubCode::CallBootstrapCFunction_entry();
@@ -2300,7 +2301,7 @@
   if (IsUnboxedLoad() && compiler->is_optimizing()) {
     DRegister result = locs()->out(0).fpu_reg();
     Register temp = locs()->temp(0).reg();
-    __ lw(temp, FieldAddress(instance_reg, offset_in_bytes()));
+    __ LoadFieldFromOffset(temp, instance_reg, offset_in_bytes());
     intptr_t cid = field()->UnboxedFieldCid();
     switch (cid) {
       case kDoubleCid:
@@ -4118,25 +4119,19 @@
 LocationSummary* UnaryDoubleOpInstr::MakeLocationSummary(Zone* zone,
                                                          bool opt) const {
   const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 1;
+  const intptr_t kNumTemps = 0;
   LocationSummary* summary = new(zone) LocationSummary(
       zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
   summary->set_in(0, Location::RequiresFpuRegister());
   summary->set_out(0, Location::RequiresFpuRegister());
-  summary->set_temp(0, Location::RequiresFpuRegister());
   return summary;
 }
 
 
 void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  // TODO(zra): Implement vneg.
-  const Double& minus_one = Double::ZoneHandle(Double::NewCanonical(-1));
-  __ LoadObject(TMP, minus_one);
   FpuRegister result = locs()->out(0).fpu_reg();
   FpuRegister value = locs()->in(0).fpu_reg();
-  FpuRegister temp_fp = locs()->temp(0).fpu_reg();
-  __ LoadDFromOffset(temp_fp, TMP, Double::value_offset() - kHeapObjectTag);
-  __ muld(result, value, temp_fp);
+  __ negd(result, value);
 }
 
 
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index cc19675..3d30dc0 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -772,10 +772,11 @@
 
 
 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  SetupNative();
   Register result = locs()->out(0).reg();
   const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function());
   const bool is_leaf_call =
-    (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0;
+      (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0;
 
   // Push the result place holder initialized to NULL.
   __ PushObject(Object::null_object());
diff --git a/runtime/vm/intrinsifier.cc b/runtime/vm/intrinsifier.cc
index 83681cd..c3356b3 100644
--- a/runtime/vm/intrinsifier.cc
+++ b/runtime/vm/intrinsifier.cc
@@ -4,18 +4,19 @@
 // Class for intrinsifying functions.
 
 #include "vm/assembler.h"
-#include "vm/intrinsifier.h"
+#include "vm/compiler.h"
 #include "vm/flags.h"
-#include "vm/object.h"
-#include "vm/symbols.h"
-
 #include "vm/flow_graph.h"
 #include "vm/flow_graph_compiler.h"
 #include "vm/flow_graph_allocator.h"
 #include "vm/flow_graph_builder.h"
 #include "vm/il_printer.h"
 #include "vm/intermediate_language.h"
+#include "vm/intrinsifier.h"
+#include "vm/object.h"
 #include "vm/parser.h"
+#include "vm/symbols.h"
+
 
 namespace dart {
 
@@ -133,14 +134,14 @@
   FlowGraphBuilder builder(parsed_function,
                            *ic_data_array,
                            NULL,  // NULL = not inlining.
-                           Thread::kNoDeoptId);  // No OSR id.
+                           Compiler::kNoOSRDeoptId);
 
   intptr_t block_id = builder.AllocateBlockId();
   TargetEntryInstr* normal_entry =
       new TargetEntryInstr(block_id,
                            CatchClauseNode::kInvalidTryIndex);
   GraphEntryInstr* graph_entry = new GraphEntryInstr(
-      parsed_function, normal_entry, Thread::kNoDeoptId);  // No OSR id.
+      parsed_function, normal_entry, Compiler::kNoOSRDeoptId);
   FlowGraph* graph = new FlowGraph(parsed_function, graph_entry, block_id);
   const Function& function = parsed_function.function();
   switch (function.recognized_kind()) {
@@ -867,4 +868,23 @@
   return true;
 }
 
+
+bool Intrinsifier::Build_DoubleFlipSignBit(FlowGraph* flow_graph) {
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  TargetEntryInstr* normal_entry = graph_entry->normal_entry();
+  BlockBuilder builder(flow_graph, normal_entry);
+
+  Definition* receiver = builder.AddParameter(1);
+  Definition* unboxed_value =
+      builder.AddUnboxInstr(kUnboxedDouble, new Value(receiver));
+  Definition* unboxed_result = builder.AddDefinition(
+      new UnaryDoubleOpInstr(Token::kNEGATE,
+                             new Value(unboxed_value),
+                             Thread::kNoDeoptId));
+  Definition* result = builder.AddDefinition(
+      BoxInstr::Create(kUnboxedDouble, new Value(unboxed_result)));
+  builder.AddIntrinsicReturn(new Value(result));
+  return true;
+}
+
 }  // namespace dart
diff --git a/runtime/vm/intrinsifier_arm.cc b/runtime/vm/intrinsifier_arm.cc
index dd6d509..bb3121f 100644
--- a/runtime/vm/intrinsifier_arm.cc
+++ b/runtime/vm/intrinsifier_arm.cc
@@ -21,13 +21,12 @@
 DECLARE_FLAG(bool, interpret_irregexp);
 
 // When entering intrinsics code:
-// R5: IC Data
 // R4: Arguments descriptor
 // LR: Return address
-// The R5, R4 registers can be destroyed only if there is no slow-path, i.e.
+// The R4 register can be destroyed only if there is no slow-path, i.e.
 // if the intrinsified method always executes a return.
 // The FP register should not be modified, because it is used by the profiler.
-// The THR register (see constants_arm.h) must be preserved.
+// The PP and THR registers (see constants_arm.h) must be preserved.
 
 #define __ assembler->
 
@@ -216,18 +215,18 @@
   /* R2: allocation size. */                                                   \
   /* R3: iterator which initially points to the start of the variable */       \
   /* R4: allocation stats address */                                           \
-  /* R6, R7: zero. */                                                          \
+  /* R8, R9: zero. */                                                          \
   /* data area to be initialized. */                                           \
-  __ LoadImmediate(R6, 0);                                                     \
-  __ mov(R7, Operand(R6));                                                     \
+  __ LoadImmediate(R8, 0);                                                     \
+  __ mov(R9, Operand(R8));                                                     \
   __ AddImmediate(R3, R0, sizeof(Raw##type_name) - 1);                         \
   Label init_loop;                                                             \
   __ Bind(&init_loop);                                                         \
   __ AddImmediate(R3, 2 * kWordSize);                                          \
   __ cmp(R3, Operand(R1));                                                     \
-  __ strd(R6, R3, -2 * kWordSize, LS);                                         \
+  __ strd(R8, R9, R3, -2 * kWordSize, LS);                                     \
   __ b(&init_loop, CC);                                                        \
-  __ str(R6, Address(R3, -2 * kWordSize), HI);                                 \
+  __ str(R8, Address(R3, -2 * kWordSize), HI);                                 \
                                                                                \
   __ IncrementAllocationStatsWithSize(R4, R2, space);                          \
   __ Ret();                                                                    \
@@ -314,7 +313,7 @@
 void Intrinsifier::Integer_mulFromInteger(Assembler* assembler) {
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);  // checks two smis
-  __ SmiUntag(R0);  // Untags R6. We only want result shifted by one.
+  __ SmiUntag(R0);  // Untags R0. We only want result shifted by one.
   __ smull(R0, IP, R0, R1);  // IP:R0 <- R0 * R1.
   __ cmp(IP, Operand(R0, ASR, 31));
   __ bx(LR, EQ);
@@ -507,7 +506,7 @@
   ASSERT(kSmiTagShift == 1);
   ASSERT(kSmiTag == 0);
   Label fall_through;
-  __ Push(R10);
+  __ Push(R6);
   TestBothArgumentsSmis(assembler, &fall_through);
   __ CompareImmediate(R0, Smi::RawValue(Smi::kBits));
   __ b(&fall_through, HI);
@@ -532,14 +531,14 @@
   // ((1 << R0) - 1), shifting it to the left, masking R1, then shifting back.
   // high bits = (((1 << R0) - 1) << (32 - R0)) & R1) >> (32 - R0)
   // lo bits = R1 << R0
-  __ LoadImmediate(R7, 1);
-  __ mov(R7, Operand(R7, LSL, R0));  // R7 <- 1 << R0
-  __ sub(R7, R7, Operand(1));  // R7 <- R7 - 1
-  __ rsb(R10, R0, Operand(32));  // R10 <- 32 - R0
-  __ mov(R7, Operand(R7, LSL, R10));  // R7 <- R7 << R10
-  __ and_(R7, R1, Operand(R7));  // R7 <- R7 & R1
-  __ mov(R7, Operand(R7, LSR, R10));  // R7 <- R7 >> R10
-  // Now R7 has the bits that fall off of R1 on a left shift.
+  __ LoadImmediate(NOTFP, 1);
+  __ mov(NOTFP, Operand(NOTFP, LSL, R0));  // NOTFP <- 1 << R0
+  __ sub(NOTFP, NOTFP, Operand(1));  // NOTFP <- NOTFP - 1
+  __ rsb(R6, R0, Operand(32));  // R6 <- 32 - R0
+  __ mov(NOTFP, Operand(NOTFP, LSL, R6));  // NOTFP <- NOTFP << R6
+  __ and_(NOTFP, R1, Operand(NOTFP));  // NOTFP <- NOTFP & R1
+  __ mov(NOTFP, Operand(NOTFP, LSR, R6));  // NOTFP <- NOTFP >> R6
+  // Now NOTFP has the bits that fall off of R1 on a left shift.
   __ mov(R1, Operand(R1, LSL, R0));  // R1 gets the low bits.
 
   const Class& mint_class = Class::Handle(
@@ -548,12 +547,12 @@
 
 
   __ str(R1, FieldAddress(R0, Mint::value_offset()));
-  __ str(R7, FieldAddress(R0, Mint::value_offset() + kWordSize));
-  __ Pop(R10);
+  __ str(NOTFP, FieldAddress(R0, Mint::value_offset() + kWordSize));
+  __ Pop(R6);
   __ Ret();
   __ Bind(&fall_through);
-  ASSERT(CODE_REG == R10);
-  __ Pop(R10);
+  ASSERT(CODE_REG == R6);
+  __ Pop(R6);
 }
 
 
@@ -622,16 +621,16 @@
   // Get left as 64 bit integer.
   Get64SmiOrMint(assembler, R3, R2, R1, &fall_through);
   // Get right as 64 bit integer.
-  Get64SmiOrMint(assembler, R7, R6, R0, &fall_through);
+  Get64SmiOrMint(assembler, NOTFP, R8, R0, &fall_through);
   // R3: left high.
   // R2: left low.
-  // R7: right high.
-  // R6: right low.
+  // NOTFP: right high.
+  // R8: right low.
 
-  __ cmp(R3, Operand(R7));  // Compare left hi, right high.
+  __ cmp(R3, Operand(NOTFP));  // Compare left hi, right high.
   __ b(&is_false, hi_false_cond);
   __ b(&is_true, hi_true_cond);
-  __ cmp(R2, Operand(R6));  // Compare left lo, right lo.
+  __ cmp(R2, Operand(R8));  // Compare left lo, right lo.
   __ b(&is_false, lo_false_cond);
   // Else is true.
   __ b(&is_true);
@@ -768,37 +767,37 @@
   // static void _lsh(Uint32List x_digits, int x_used, int n,
   //                  Uint32List r_digits)
 
-  // R2 = x_used, R3 = x_digits, x_used > 0, x_used is Smi.
-  __ ldrd(R2, SP, 2 * kWordSize);
-  // R4 = r_digits, R5 = n, n is Smi, n % _DIGIT_BITS != 0.
-  __ ldrd(R4, SP, 0 * kWordSize);
-  __ SmiUntag(R5);
-  // R0 = n ~/ _DIGIT_BITS
-  __ Asr(R0, R5, Operand(5));
-  // R6 = &x_digits[0]
-  __ add(R6, R3, Operand(TypedData::data_offset() - kHeapObjectTag));
-  // R7 = &x_digits[x_used]
-  __ add(R7, R6, Operand(R2, LSL, 1));
-  // R10 = &r_digits[1]
-  __ add(R10, R4, Operand(TypedData::data_offset() - kHeapObjectTag +
+  // R0 = x_used, R1 = x_digits, x_used > 0, x_used is Smi.
+  __ ldrd(R0, R1, SP, 2 * kWordSize);
+  // R2 = r_digits, R3 = n, n is Smi, n % _DIGIT_BITS != 0.
+  __ ldrd(R2, R3, SP, 0 * kWordSize);
+  __ SmiUntag(R3);
+  // R4 = n ~/ _DIGIT_BITS
+  __ Asr(R4, R3, Operand(5));
+  // R8 = &x_digits[0]
+  __ add(R8, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
+  // NOTFP = &x_digits[x_used]
+  __ add(NOTFP, R8, Operand(R0, LSL, 1));
+  // R6 = &r_digits[1]
+  __ add(R6, R2, Operand(TypedData::data_offset() - kHeapObjectTag +
                          Bigint::kBytesPerDigit));
-  // R10 = &r_digits[x_used + n ~/ _DIGIT_BITS + 1]
-  __ add(R0, R0, Operand(R2, ASR, 1));
-  __ add(R10, R10, Operand(R0, LSL, 2));
-  // R3 = n % _DIGIT_BITS
-  __ and_(R3, R5, Operand(31));
-  // R2 = 32 - R3
-  __ rsb(R2, R3, Operand(32));
-  __ mov(R1, Operand(0));
+  // R6 = &r_digits[x_used + n ~/ _DIGIT_BITS + 1]
+  __ add(R4, R4, Operand(R0, ASR, 1));
+  __ add(R6, R6, Operand(R4, LSL, 2));
+  // R1 = n % _DIGIT_BITS
+  __ and_(R1, R3, Operand(31));
+  // R0 = 32 - R1
+  __ rsb(R0, R1, Operand(32));
+  __ mov(R9, Operand(0));
   Label loop;
   __ Bind(&loop);
-  __ ldr(R0, Address(R7, -Bigint::kBytesPerDigit, Address::PreIndex));
-  __ orr(R1, R1, Operand(R0, LSR, R2));
-  __ str(R1, Address(R10, -Bigint::kBytesPerDigit, Address::PreIndex));
-  __ mov(R1, Operand(R0, LSL, R3));
-  __ teq(R7, Operand(R6));
+  __ ldr(R4, Address(NOTFP, -Bigint::kBytesPerDigit, Address::PreIndex));
+  __ orr(R9, R9, Operand(R4, LSR, R0));
+  __ str(R9, Address(R6, -Bigint::kBytesPerDigit, Address::PreIndex));
+  __ mov(R9, Operand(R4, LSL, R1));
+  __ teq(NOTFP, Operand(R8));
   __ b(&loop, NE);
-  __ str(R1, Address(R10, -Bigint::kBytesPerDigit, Address::PreIndex));
+  __ str(R9, Address(R6, -Bigint::kBytesPerDigit, Address::PreIndex));
   // Returning Object::null() is not required, since this method is private.
   __ Ret();
 }
@@ -808,41 +807,41 @@
   // static void _lsh(Uint32List x_digits, int x_used, int n,
   //                  Uint32List r_digits)
 
-  // R2 = x_used, R3 = x_digits, x_used > 0, x_used is Smi.
-  __ ldrd(R2, SP, 2 * kWordSize);
-  // R4 = r_digits, R5 = n, n is Smi, n % _DIGIT_BITS != 0.
-  __ ldrd(R4, SP, 0 * kWordSize);
-  __ SmiUntag(R5);
-  // R0 = n ~/ _DIGIT_BITS
-  __ Asr(R0, R5, Operand(5));
-  // R10 = &r_digits[0]
-  __ add(R10, R4, Operand(TypedData::data_offset() - kHeapObjectTag));
-  // R7 = &x_digits[n ~/ _DIGIT_BITS]
-  __ add(R7, R3, Operand(TypedData::data_offset() - kHeapObjectTag));
-  __ add(R7, R7, Operand(R0, LSL, 2));
-  // R6 = &r_digits[x_used - n ~/ _DIGIT_BITS - 1]
-  __ add(R0, R0, Operand(1));
-  __ rsb(R0, R0, Operand(R2, ASR, 1));
-  __ add(R6, R10, Operand(R0, LSL, 2));
-  // R3 = n % _DIGIT_BITS
-  __ and_(R3, R5, Operand(31));
-  // R2 = 32 - R3
-  __ rsb(R2, R3, Operand(32));
-  // R1 = x_digits[n ~/ _DIGIT_BITS] >> (n % _DIGIT_BITS)
-  __ ldr(R1, Address(R7, Bigint::kBytesPerDigit, Address::PostIndex));
-  __ mov(R1, Operand(R1, LSR, R3));
+  // R0 = x_used, R1 = x_digits, x_used > 0, x_used is Smi.
+  __ ldrd(R0, R1, SP, 2 * kWordSize);
+  // R2 = r_digits, R3 = n, n is Smi, n % _DIGIT_BITS != 0.
+  __ ldrd(R2, R3, SP, 0 * kWordSize);
+  __ SmiUntag(R3);
+  // R4 = n ~/ _DIGIT_BITS
+  __ Asr(R4, R3, Operand(5));
+  // R6 = &r_digits[0]
+  __ add(R6, R2, Operand(TypedData::data_offset() - kHeapObjectTag));
+  // NOTFP = &x_digits[n ~/ _DIGIT_BITS]
+  __ add(NOTFP, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
+  __ add(NOTFP, NOTFP, Operand(R4, LSL, 2));
+  // R8 = &r_digits[x_used - n ~/ _DIGIT_BITS - 1]
+  __ add(R4, R4, Operand(1));
+  __ rsb(R4, R4, Operand(R0, ASR, 1));
+  __ add(R8, R6, Operand(R4, LSL, 2));
+  // R1 = n % _DIGIT_BITS
+  __ and_(R1, R3, Operand(31));
+  // R0 = 32 - R1
+  __ rsb(R0, R1, Operand(32));
+  // R9 = x_digits[n ~/ _DIGIT_BITS] >> (n % _DIGIT_BITS)
+  __ ldr(R9, Address(NOTFP, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ mov(R9, Operand(R9, LSR, R1));
   Label loop_entry;
   __ b(&loop_entry);
   Label loop;
   __ Bind(&loop);
-  __ ldr(R0, Address(R7, Bigint::kBytesPerDigit, Address::PostIndex));
-  __ orr(R1, R1, Operand(R0, LSL, R2));
-  __ str(R1, Address(R10, Bigint::kBytesPerDigit, Address::PostIndex));
-  __ mov(R1, Operand(R0, LSR, R3));
+  __ ldr(R4, Address(NOTFP, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ orr(R9, R9, Operand(R4, LSL, R0));
+  __ str(R9, Address(R6, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ mov(R9, Operand(R4, LSR, R1));
   __ Bind(&loop_entry);
-  __ teq(R10, Operand(R6));
+  __ teq(R6, Operand(R8));
   __ b(&loop, NE);
-  __ str(R1, Address(R10, 0));
+  __ str(R9, Address(R6, 0));
   // Returning Object::null() is not required, since this method is private.
   __ Ret();
 }
@@ -853,55 +852,55 @@
   //                     Uint32List a_digits, int a_used,
   //                     Uint32List r_digits)
 
-  // R2 = used, R3 = digits
-  __ ldrd(R2, SP, 3 * kWordSize);
-  // R3 = &digits[0]
+  // R0 = used, R1 = digits
+  __ ldrd(R0, R1, SP, 3 * kWordSize);
+  // R1 = &digits[0]
+  __ add(R1, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
+
+  // R2 = a_used, R3 = a_digits
+  __ ldrd(R2, R3, SP, 1 * kWordSize);
+  // R3 = &a_digits[0]
   __ add(R3, R3, Operand(TypedData::data_offset() - kHeapObjectTag));
 
-  // R4 = a_used, R5 = a_digits
-  __ ldrd(R4, SP, 1 * kWordSize);
-  // R5 = &a_digits[0]
-  __ add(R5, R5, Operand(TypedData::data_offset() - kHeapObjectTag));
+  // R8 = r_digits
+  __ ldr(R8, Address(SP, 0 * kWordSize));
+  // R8 = &r_digits[0]
+  __ add(R8, R8, Operand(TypedData::data_offset() - kHeapObjectTag));
 
-  // R6 = r_digits
-  __ ldr(R6, Address(SP, 0 * kWordSize));
-  // R6 = &r_digits[0]
-  __ add(R6, R6, Operand(TypedData::data_offset() - kHeapObjectTag));
+  // NOTFP = &digits[a_used >> 1], a_used is Smi.
+  __ add(NOTFP, R1, Operand(R2, LSL, 1));
 
-  // R7 = &digits[a_used >> 1], a_used is Smi.
-  __ add(R7, R3, Operand(R4, LSL, 1));
+  // R6 = &digits[used >> 1], used is Smi.
+  __ add(R6, R1, Operand(R0, LSL, 1));
 
-  // R10 = &digits[used >> 1], used is Smi.
-  __ add(R10, R3, Operand(R2, LSL, 1));
-
-  __ adds(R0, R0, Operand(0));  // carry flag = 0
+  __ adds(R4, R4, Operand(0));  // carry flag = 0
   Label add_loop;
   __ Bind(&add_loop);
   // Loop a_used times, a_used > 0.
-  __ ldr(R0, Address(R3, Bigint::kBytesPerDigit, Address::PostIndex));
-  __ ldr(R1, Address(R5, Bigint::kBytesPerDigit, Address::PostIndex));
-  __ adcs(R0, R0, Operand(R1));
-  __ teq(R3, Operand(R7));  // Does not affect carry flag.
-  __ str(R0, Address(R6, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ ldr(R4, Address(R1, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ ldr(R9, Address(R3, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ adcs(R4, R4, Operand(R9));
+  __ teq(R1, Operand(NOTFP));  // Does not affect carry flag.
+  __ str(R4, Address(R8, Bigint::kBytesPerDigit, Address::PostIndex));
   __ b(&add_loop, NE);
 
   Label last_carry;
-  __ teq(R3, Operand(R10));  // Does not affect carry flag.
+  __ teq(R1, Operand(R6));  // Does not affect carry flag.
   __ b(&last_carry, EQ);  // If used - a_used == 0.
 
   Label carry_loop;
   __ Bind(&carry_loop);
   // Loop used - a_used times, used - a_used > 0.
-  __ ldr(R0, Address(R3, Bigint::kBytesPerDigit, Address::PostIndex));
-  __ adcs(R0, R0, Operand(0));
-  __ teq(R3, Operand(R10));  // Does not affect carry flag.
-  __ str(R0, Address(R6, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ ldr(R4, Address(R1, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ adcs(R4, R4, Operand(0));
+  __ teq(R1, Operand(R6));  // Does not affect carry flag.
+  __ str(R4, Address(R8, Bigint::kBytesPerDigit, Address::PostIndex));
   __ b(&carry_loop, NE);
 
   __ Bind(&last_carry);
-  __ mov(R0, Operand(0));
-  __ adc(R0, R0, Operand(0));
-  __ str(R0, Address(R6, 0));
+  __ mov(R4, Operand(0));
+  __ adc(R4, R4, Operand(0));
+  __ str(R4, Address(R8, 0));
 
   // Returning Object::null() is not required, since this method is private.
   __ Ret();
@@ -913,49 +912,49 @@
   //                     Uint32List a_digits, int a_used,
   //                     Uint32List r_digits)
 
-  // R2 = used, R3 = digits
-  __ ldrd(R2, SP, 3 * kWordSize);
-  // R3 = &digits[0]
+  // R0 = used, R1 = digits
+  __ ldrd(R0, R1, SP, 3 * kWordSize);
+  // R1 = &digits[0]
+  __ add(R1, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
+
+  // R2 = a_used, R3 = a_digits
+  __ ldrd(R2, R3, SP, 1 * kWordSize);
+  // R3 = &a_digits[0]
   __ add(R3, R3, Operand(TypedData::data_offset() - kHeapObjectTag));
 
-  // R4 = a_used, R5 = a_digits
-  __ ldrd(R4, SP, 1 * kWordSize);
-  // R5 = &a_digits[0]
-  __ add(R5, R5, Operand(TypedData::data_offset() - kHeapObjectTag));
+  // R8 = r_digits
+  __ ldr(R8, Address(SP, 0 * kWordSize));
+  // R8 = &r_digits[0]
+  __ add(R8, R8, Operand(TypedData::data_offset() - kHeapObjectTag));
 
-  // R6 = r_digits
-  __ ldr(R6, Address(SP, 0 * kWordSize));
-  // R6 = &r_digits[0]
-  __ add(R6, R6, Operand(TypedData::data_offset() - kHeapObjectTag));
+  // NOTFP = &digits[a_used >> 1], a_used is Smi.
+  __ add(NOTFP, R1, Operand(R2, LSL, 1));
 
-  // R7 = &digits[a_used >> 1], a_used is Smi.
-  __ add(R7, R3, Operand(R4, LSL, 1));
+  // R6 = &digits[used >> 1], used is Smi.
+  __ add(R6, R1, Operand(R0, LSL, 1));
 
-  // R10 = &digits[used >> 1], used is Smi.
-  __ add(R10, R3, Operand(R2, LSL, 1));
-
-  __ subs(R0, R0, Operand(0));  // carry flag = 1
+  __ subs(R4, R4, Operand(0));  // carry flag = 1
   Label sub_loop;
   __ Bind(&sub_loop);
   // Loop a_used times, a_used > 0.
-  __ ldr(R0, Address(R3, Bigint::kBytesPerDigit, Address::PostIndex));
-  __ ldr(R1, Address(R5, Bigint::kBytesPerDigit, Address::PostIndex));
-  __ sbcs(R0, R0, Operand(R1));
-  __ teq(R3, Operand(R7));  // Does not affect carry flag.
-  __ str(R0, Address(R6, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ ldr(R4, Address(R1, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ ldr(R9, Address(R3, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ sbcs(R4, R4, Operand(R9));
+  __ teq(R1, Operand(NOTFP));  // Does not affect carry flag.
+  __ str(R4, Address(R8, Bigint::kBytesPerDigit, Address::PostIndex));
   __ b(&sub_loop, NE);
 
   Label done;
-  __ teq(R3, Operand(R10));  // Does not affect carry flag.
+  __ teq(R1, Operand(R6));  // Does not affect carry flag.
   __ b(&done, EQ);  // If used - a_used == 0.
 
   Label carry_loop;
   __ Bind(&carry_loop);
   // Loop used - a_used times, used - a_used > 0.
-  __ ldr(R0, Address(R3, Bigint::kBytesPerDigit, Address::PostIndex));
-  __ sbcs(R0, R0, Operand(0));
-  __ teq(R3, Operand(R10));  // Does not affect carry flag.
-  __ str(R0, Address(R6, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ ldr(R4, Address(R1, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ sbcs(R4, R4, Operand(0));
+  __ teq(R1, Operand(R6));  // Does not affect carry flag.
+  __ str(R4, Address(R8, Bigint::kBytesPerDigit, Address::PostIndex));
   __ b(&carry_loop, NE);
 
   __ Bind(&done);
@@ -994,26 +993,26 @@
 
   Label done;
   // R3 = x, no_op if x == 0
-  __ ldrd(R0, SP, 5 * kWordSize);  // R0 = xi as Smi, R1 = x_digits.
+  __ ldrd(R0, R1, SP, 5 * kWordSize);  // R0 = xi as Smi, R1 = x_digits.
   __ add(R1, R1, Operand(R0, LSL, 1));
   __ ldr(R3, FieldAddress(R1, TypedData::data_offset()));
   __ tst(R3, Operand(R3));
   __ b(&done, EQ);
 
-  // R6 = SmiUntag(n), no_op if n == 0
-  __ ldr(R6, Address(SP, 0 * kWordSize));
-  __ Asrs(R6, R6, Operand(kSmiTagSize));
+  // R8 = SmiUntag(n), no_op if n == 0
+  __ ldr(R8, Address(SP, 0 * kWordSize));
+  __ Asrs(R8, R8, Operand(kSmiTagSize));
   __ b(&done, EQ);
 
   // R4 = mip = &m_digits[i >> 1]
-  __ ldrd(R0, SP, 3 * kWordSize);  // R0 = i as Smi, R1 = m_digits.
+  __ ldrd(R0, R1, SP, 3 * kWordSize);  // R0 = i as Smi, R1 = m_digits.
   __ add(R1, R1, Operand(R0, LSL, 1));
   __ add(R4, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
 
-  // R5 = ajp = &a_digits[j >> 1]
-  __ ldrd(R0, SP, 1 * kWordSize);  // R0 = j as Smi, R1 = a_digits.
+  // R9 = ajp = &a_digits[j >> 1]
+  __ ldrd(R0, R1, SP, 1 * kWordSize);  // R0 = j as Smi, R1 = a_digits.
   __ add(R1, R1, Operand(R0, LSL, 1));
-  __ add(R5, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
+  __ add(R9, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
 
   // R1 = c = 0
   __ mov(R1, Operand(0));
@@ -1022,42 +1021,42 @@
   __ Bind(&muladd_loop);
   // x:   R3
   // mip: R4
-  // ajp: R5
+  // ajp: R9
   // c:   R1
-  // n:   R6
+  // n:   R8
 
   // uint32_t mi = *mip++
   __ ldr(R2, Address(R4, Bigint::kBytesPerDigit, Address::PostIndex));
 
   // uint32_t aj = *ajp
-  __ ldr(R0, Address(R5, 0));
+  __ ldr(R0, Address(R9, 0));
 
   // uint64_t t = x*mi + aj + c
   __ umaal(R0, R1, R2, R3);  // R1:R0 = R2*R3 + R1 + R0.
 
   // *ajp++ = low32(t) = R0
-  __ str(R0, Address(R5, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ str(R0, Address(R9, Bigint::kBytesPerDigit, Address::PostIndex));
 
   // c = high32(t) = R1
 
   // while (--n > 0)
-  __ subs(R6, R6, Operand(1));  // --n
+  __ subs(R8, R8, Operand(1));  // --n
   __ b(&muladd_loop, NE);
 
   __ tst(R1, Operand(R1));
   __ b(&done, EQ);
 
   // *ajp++ += c
-  __ ldr(R0, Address(R5, 0));
+  __ ldr(R0, Address(R9, 0));
   __ adds(R0, R0, Operand(R1));
-  __ str(R0, Address(R5, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ str(R0, Address(R9, Bigint::kBytesPerDigit, Address::PostIndex));
   __ b(&done, CC);
 
   Label propagate_carry_loop;
   __ Bind(&propagate_carry_loop);
-  __ ldr(R0, Address(R5, 0));
+  __ ldr(R0, Address(R9, 0));
   __ adds(R0, R0, Operand(1));
-  __ str(R0, Address(R5, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ str(R0, Address(R9, Bigint::kBytesPerDigit, Address::PostIndex));
   __ b(&propagate_carry_loop, CS);
 
   __ Bind(&done);
@@ -1094,7 +1093,7 @@
   // }
 
   // R4 = xip = &x_digits[i >> 1]
-  __ ldrd(R2, SP, 2 * kWordSize);  // R2 = i as Smi, R3 = x_digits
+  __ ldrd(R2, R3, SP, 2 * kWordSize);  // R2 = i as Smi, R3 = x_digits
   __ add(R3, R3, Operand(R2, LSL, 1));
   __ add(R4, R3, Operand(TypedData::data_offset() - kHeapObjectTag));
 
@@ -1104,28 +1103,28 @@
   __ tst(R3, Operand(R3));
   __ b(&x_zero, EQ);
 
-  // R5 = ajp = &a_digits[i]
+  // NOTFP = ajp = &a_digits[i]
   __ ldr(R1, Address(SP, 1 * kWordSize));  // a_digits
   __ add(R1, R1, Operand(R2, LSL, 2));  // j == 2*i, i is Smi.
-  __ add(R5, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
+  __ add(NOTFP, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
 
-  // R6:R0 = t = x*x + *ajp
-  __ ldr(R0, Address(R5, 0));
-  __ mov(R6, Operand(0));
-  __ umaal(R0, R6, R3, R3);  // R6:R0 = R3*R3 + R6 + R0.
+  // R8:R0 = t = x*x + *ajp
+  __ ldr(R0, Address(NOTFP, 0));
+  __ mov(R8, Operand(0));
+  __ umaal(R0, R8, R3, R3);  // R8:R0 = R3*R3 + R8 + R0.
 
   // *ajp++ = low32(t) = R0
-  __ str(R0, Address(R5, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ str(R0, Address(NOTFP, Bigint::kBytesPerDigit, Address::PostIndex));
 
-  // R6 = low32(c) = high32(t)
-  // R7 = high32(c) = 0
-  __ mov(R7, Operand(0));
+  // R8 = low32(c) = high32(t)
+  // R9 = high32(c) = 0
+  __ mov(R9, Operand(0));
 
   // int n = used - i - 1; while (--n >= 0) ...
   __ ldr(R0, Address(SP, 0 * kWordSize));  // used is Smi
-  __ sub(R10, R0, Operand(R2));
+  __ sub(R6, R0, Operand(R2));
   __ mov(R0, Operand(2));  // n = used - i - 2; if (n >= 0) ... while (--n >= 0)
-  __ rsbs(R10, R0, Operand(R10, ASR, kSmiTagSize));
+  __ rsbs(R6, R0, Operand(R6, ASR, kSmiTagSize));
 
   Label loop, done;
   __ b(&done, MI);
@@ -1133,46 +1132,46 @@
   __ Bind(&loop);
   // x:   R3
   // xip: R4
-  // ajp: R5
-  // c:   R7:R6
+  // ajp: NOTFP
+  // c:   R9:R8
   // t:   R2:R1:R0 (not live at loop entry)
-  // n:   R10
+  // n:   R6
 
   // uint32_t xi = *xip++
   __ ldr(R2, Address(R4, Bigint::kBytesPerDigit, Address::PostIndex));
 
-  // uint96_t t = R7:R6:R0 = 2*x*xi + aj + c
+  // uint96_t t = R9:R8:R0 = 2*x*xi + aj + c
   __ umull(R0, R1, R2, R3);  // R1:R0 = R2*R3.
   __ adds(R0, R0, Operand(R0));
   __ adcs(R1, R1, Operand(R1));
   __ mov(R2, Operand(0));
   __ adc(R2, R2, Operand(0));  // R2:R1:R0 = 2*x*xi.
-  __ adds(R0, R0, Operand(R6));
-  __ adcs(R1, R1, Operand(R7));
+  __ adds(R0, R0, Operand(R8));
+  __ adcs(R1, R1, Operand(R9));
   __ adc(R2, R2, Operand(0));  // R2:R1:R0 = 2*x*xi + c.
-  __ ldr(R6, Address(R5, 0));  // R6 = aj = *ajp.
-  __ adds(R0, R0, Operand(R6));
-  __ adcs(R6, R1, Operand(0));
-  __ adc(R7, R2, Operand(0));  // R7:R6:R0 = 2*x*xi + c + aj.
+  __ ldr(R8, Address(NOTFP, 0));  // R8 = aj = *ajp.
+  __ adds(R0, R0, Operand(R8));
+  __ adcs(R8, R1, Operand(0));
+  __ adc(R9, R2, Operand(0));  // R9:R8:R0 = 2*x*xi + c + aj.
 
   // *ajp++ = low32(t) = R0
-  __ str(R0, Address(R5, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ str(R0, Address(NOTFP, Bigint::kBytesPerDigit, Address::PostIndex));
 
   // while (--n >= 0)
-  __ subs(R10, R10, Operand(1));  // --n
+  __ subs(R6, R6, Operand(1));  // --n
   __ b(&loop, PL);
 
   __ Bind(&done);
   // uint32_t aj = *ajp
-  __ ldr(R0, Address(R5, 0));
+  __ ldr(R0, Address(NOTFP, 0));
 
   // uint64_t t = aj + c
-  __ adds(R6, R6, Operand(R0));
-  __ adc(R7, R7, Operand(0));
+  __ adds(R8, R8, Operand(R0));
+  __ adc(R9, R9, Operand(0));
 
-  // *ajp = low32(t) = R6
-  // *(ajp + 1) = high32(t) = R7
-  __ strd(R6, R5, 0);
+  // *ajp = low32(t) = R8
+  // *(ajp + 1) = high32(t) = R9
+  __ strd(R8, R9, NOTFP, 0);
 
   __ Bind(&x_zero);
   __ mov(R0, Operand(Smi::RawValue(1)));  // One digit processed.
@@ -1203,7 +1202,7 @@
                           TypedData::data_offset() + 2*Bigint::kBytesPerDigit));
 
   // R2 = digits[i >> 1]
-  __ ldrd(R0, SP, 0 * kWordSize);  // R0 = i as Smi, R1 = digits
+  __ ldrd(R0, R1, SP, 0 * kWordSize);  // R0 = i as Smi, R1 = digits
   __ add(R1, R1, Operand(R0, LSL, 1));
   __ ldr(R2, FieldAddress(R1, TypedData::data_offset()));
 
@@ -1514,11 +1513,11 @@
   __ LoadImmediate(R0, a_int32_value);
   __ LoadFromOffset(kWord, R2, R1, disp_0 - kHeapObjectTag);
   __ LoadFromOffset(kWord, R3, R1, disp_1 - kHeapObjectTag);
-  __ mov(R6, Operand(0));  // Zero extend unsigned _state[kSTATE_HI].
-  // Unsigned 32-bit multiply and 64-bit accumulate into R6:R3.
-  __ umlal(R3, R6, R0, R2);  // R6:R3 <- R6:R3 + R0 * R2.
+  __ mov(R8, Operand(0));  // Zero extend unsigned _state[kSTATE_HI].
+  // Unsigned 32-bit multiply and 64-bit accumulate into R8:R3.
+  __ umlal(R3, R8, R0, R2);  // R8:R3 <- R8:R3 + R0 * R2.
   __ StoreToOffset(kWord, R3, R1, disp_0 - kHeapObjectTag);
-  __ StoreToOffset(kWord, R6, R1, disp_1 - kHeapObjectTag);
+  __ StoreToOffset(kWord, R8, R1, disp_1 - kHeapObjectTag);
   __ Ret();
 }
 
@@ -1598,6 +1597,127 @@
 }
 
 
+void GenerateSubstringMatchesSpecialization(Assembler* assembler,
+                                            intptr_t receiver_cid,
+                                            intptr_t other_cid,
+                                            Label* return_true,
+                                            Label* return_false) {
+  __ SmiUntag(R1);
+  __ ldr(R8, FieldAddress(R0, String::length_offset()));  // this.length
+  __ SmiUntag(R8);
+  __ ldr(R9, FieldAddress(R2, String::length_offset()));  // other.length
+  __ SmiUntag(R9);
+
+  // if (other.length == 0) return true;
+  __ cmp(R9, Operand(0));
+  __ b(return_true, EQ);
+
+  // if (start < 0) return false;
+  __ cmp(R1, Operand(0));
+  __ b(return_false, LT);
+
+  // if (start + other.length > this.length) return false;
+  __ add(R3, R1, Operand(R9));
+  __ cmp(R3, Operand(R8));
+  __ b(return_false, GT);
+
+  if (receiver_cid == kOneByteStringCid) {
+    __ AddImmediate(R0, R0, OneByteString::data_offset() - kHeapObjectTag);
+    __ add(R0, R0, Operand(R1));
+  } else {
+    ASSERT(receiver_cid == kTwoByteStringCid);
+    __ AddImmediate(R0, R0, TwoByteString::data_offset() - kHeapObjectTag);
+    __ add(R0, R0, Operand(R1));
+    __ add(R0, R0, Operand(R1));
+  }
+  if (other_cid == kOneByteStringCid) {
+    __ AddImmediate(R2, R2, OneByteString::data_offset() - kHeapObjectTag);
+  } else {
+    ASSERT(other_cid == kTwoByteStringCid);
+    __ AddImmediate(R2, R2, TwoByteString::data_offset() - kHeapObjectTag);
+  }
+
+  // i = 0
+  __ LoadImmediate(R3, 0);
+
+  // do
+  Label loop;
+  __ Bind(&loop);
+
+  if (receiver_cid == kOneByteStringCid) {
+    __ ldrb(R4, Address(R0, 0));     // this.codeUnitAt(i + start)
+  } else {
+    __ ldrh(R4, Address(R0, 0));     // this.codeUnitAt(i + start)
+  }
+  if (other_cid == kOneByteStringCid) {
+    __ ldrb(NOTFP, Address(R2, 0));  // other.codeUnitAt(i)
+  } else {
+    __ ldrh(NOTFP, Address(R2, 0));  // other.codeUnitAt(i)
+  }
+  __ cmp(R4, Operand(NOTFP));
+  __ b(return_false, NE);
+
+  // i++, while (i < len)
+  __ AddImmediate(R3, R3, 1);
+  __ AddImmediate(R0, R0, receiver_cid == kOneByteStringCid ? 1 : 2);
+  __ AddImmediate(R2, R2, other_cid == kOneByteStringCid ? 1 : 2);
+  __ cmp(R3, Operand(R9));
+  __ b(&loop, LT);
+
+  __ b(return_true);
+}
+
+
+// bool _substringMatches(int start, String other)
+// This intrinsic handles a OneByteString or TwoByteString receiver with a
+// OneByteString other.
+void Intrinsifier::StringBaseSubstringMatches(Assembler* assembler) {
+  Label fall_through, return_true, return_false, try_two_byte;
+  __ ldr(R0, Address(SP, 2 * kWordSize));  // this
+  __ ldr(R1, Address(SP, 1 * kWordSize));  // start
+  __ ldr(R2, Address(SP, 0 * kWordSize));  // other
+  __ Push(R4);  // Make ARGS_DESC_REG available.
+
+  __ tst(R1, Operand(kSmiTagMask));
+  __ b(&fall_through, NE);  // 'start' is not a Smi.
+
+  __ CompareClassId(R2, kOneByteStringCid, R3);
+  __ b(&fall_through, NE);
+
+  __ CompareClassId(R0, kOneByteStringCid, R3);
+  __ b(&try_two_byte, NE);
+
+  GenerateSubstringMatchesSpecialization(assembler,
+                                         kOneByteStringCid,
+                                         kOneByteStringCid,
+                                         &return_true,
+                                         &return_false);
+
+  __ Bind(&try_two_byte);
+  __ CompareClassId(R0, kTwoByteStringCid, R3);
+  __ b(&fall_through, NE);
+
+  GenerateSubstringMatchesSpecialization(assembler,
+                                         kTwoByteStringCid,
+                                         kOneByteStringCid,
+                                         &return_true,
+                                         &return_false);
+
+  __ Bind(&return_true);
+  __ Pop(R4);
+  __ LoadObject(R0, Bool::True());
+  __ Ret();
+
+  __ Bind(&return_false);
+  __ Pop(R4);
+  __ LoadObject(R0, Bool::False());
+  __ Ret();
+
+  __ Bind(&fall_through);
+  __ Pop(R4);
+}
+
+
 void Intrinsifier::StringBaseCharAt(Assembler* assembler) {
   Label fall_through, try_two_byte_string;
 
@@ -1664,11 +1784,11 @@
 
   __ SmiUntag(R2);
   __ mov(R3, Operand(0));
-  __ AddImmediate(R6, R1, OneByteString::data_offset() - kHeapObjectTag);
+  __ AddImmediate(R8, R1, OneByteString::data_offset() - kHeapObjectTag);
   // R1: Instance of OneByteString.
   // R2: String length, untagged integer.
   // R3: Loop counter, untagged integer.
-  // R6: String data.
+  // R8: String data.
   // R0: Hash code, untagged integer.
 
   Label loop;
@@ -1678,11 +1798,11 @@
   // hash_ ^= hash_ >> 6;
   // Get one characters (ch).
   __ Bind(&loop);
-  __ ldrb(R7, Address(R6, 0));
-  // R7: ch.
+  __ ldrb(NOTFP, Address(R8, 0));
+  // NOTFP: ch.
   __ add(R3, R3, Operand(1));
-  __ add(R6, R6, Operand(1));
-  __ add(R0, R0, Operand(R7));
+  __ add(R8, R8, Operand(1));
+  __ add(R0, R0, Operand(NOTFP));
   __ add(R0, R0, Operand(R0, LSL, 10));
   __ eor(R0, R0, Operand(R0, LSR, 6));
   __ cmp(R3, Operand(R2));
@@ -1719,7 +1839,7 @@
   Label fail;
   __ MaybeTraceAllocation(kOneByteStringCid, R0, failure,
                           /* inline_isolate = */ false);
-  __ mov(R6, Operand(length_reg));  // Save the length register.
+  __ mov(R8, Operand(length_reg));  // Save the length register.
   // TODO(koda): Protect against negative length and overflow here.
   __ SmiUntag(length_reg);
   const intptr_t fixed_size = sizeof(RawString) + kObjectAlignment - 1;
@@ -1740,8 +1860,8 @@
   // R1: potential next object start.
   // R2: allocation size.
   // R3: heap.
-  __ ldr(R7, Address(R3, Heap::EndOffset(space)));
-  __ cmp(R1, Operand(R7));
+  __ ldr(NOTFP, Address(R3, Heap::EndOffset(space)));
+  __ cmp(R1, Operand(NOTFP));
   __ b(&fail, CS);
 
   // Successfully allocated the object(s), now update top to point to
@@ -1769,10 +1889,10 @@
     __ str(R3, FieldAddress(R0, String::tags_offset()));  // Store tags.
   }
 
-  // Set the length field using the saved length (R6).
+  // Set the length field using the saved length (R8).
   __ InitializeFieldNoBarrier(R0,
                               FieldAddress(R0, String::length_offset()),
-                              R6);
+                              R8);
   // Clear hash.
   __ LoadImmediate(TMP, 0);
   __ InitializeFieldNoBarrier(R0,
@@ -1824,21 +1944,21 @@
   // R3: Start address to copy from (untagged).
   // R2: Untagged number of bytes to copy.
   // R0: Tagged result string.
-  // R6: Pointer into R3.
-  // R7: Pointer into R0.
+  // R8: Pointer into R3.
+  // NOTFP: Pointer into R0.
   // R1: Scratch register.
   Label loop, done;
   __ cmp(R2, Operand(0));
   __ b(&done, LE);
-  __ mov(R6, Operand(R3));
-  __ mov(R7, Operand(R0));
+  __ mov(R8, Operand(R3));
+  __ mov(NOTFP, Operand(R0));
   __ Bind(&loop);
-  __ ldrb(R1, Address(R6, 0));
-  __ AddImmediate(R6, 1);
+  __ ldrb(R1, Address(R8, 0));
+  __ AddImmediate(R8, 1);
   __ sub(R2, R2, Operand(1));
   __ cmp(R2, Operand(0));
-  __ strb(R1, FieldAddress(R7, OneByteString::data_offset()));
-  __ AddImmediate(R7, 1);
+  __ strb(R1, FieldAddress(NOTFP, OneByteString::data_offset()));
+  __ AddImmediate(NOTFP, 1);
   __ b(&loop, GT);
 
   __ Bind(&done);
@@ -1955,7 +2075,7 @@
   // Incoming registers:
   // R0: Function. (Will be reloaded with the specialized matcher function.)
   // R4: Arguments descriptor. (Will be preserved.)
-  // R5: Unknown. (Must be GC safe on tail call.)
+  // R9: Unknown. (Must be GC safe on tail call.)
 
   // Load the specialized function pointer into R0. Leverage the fact the
   // string CIDs as well as stored function pointers are in sequence.
@@ -1967,8 +2087,8 @@
   __ ldr(R0, FieldAddress(R1, JSRegExp::function_offset(kOneByteStringCid)));
 
   // Registers are now set up for the lazy compile stub. It expects the function
-  // in R0, the argument descriptor in R4, and IC-Data in R5.
-  __ eor(R5, R5, Operand(R5));
+  // in R0, the argument descriptor in R4, and IC-Data in R9.
+  __ eor(R9, R9, Operand(R9));
 
   // Tail-call the function.
   __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
diff --git a/runtime/vm/intrinsifier_arm64.cc b/runtime/vm/intrinsifier_arm64.cc
index 4441fe2..265d5d4 100644
--- a/runtime/vm/intrinsifier_arm64.cc
+++ b/runtime/vm/intrinsifier_arm64.cc
@@ -20,12 +20,12 @@
 DECLARE_FLAG(bool, interpret_irregexp);
 
 // When entering intrinsics code:
-// R5: IC Data
 // R4: Arguments descriptor
 // LR: Return address
-// The R5, R4 registers can be destroyed only if there is no slow-path, i.e.
+// The R4 register can be destroyed only if there is no slow-path, i.e.
 // if the intrinsified method always executes a return.
 // The FP register should not be modified, because it is used by the profiler.
+// The PP and THR registers (see constants_arm64.h) must be preserved.
 
 #define __ assembler->
 
@@ -1677,6 +1677,119 @@
 }
 
 
+void GenerateSubstringMatchesSpecialization(Assembler* assembler,
+                                            intptr_t receiver_cid,
+                                            intptr_t other_cid,
+                                            Label* return_true,
+                                            Label* return_false) {
+  __ SmiUntag(R1);
+  __ ldr(R8, FieldAddress(R0, String::length_offset()));  // this.length
+  __ SmiUntag(R8);
+  __ ldr(R9, FieldAddress(R2, String::length_offset()));  // other.length
+  __ SmiUntag(R9);
+
+  // if (other.length == 0) return true;
+  __ cmp(R9, Operand(0));
+  __ b(return_true, EQ);
+
+  // if (start < 0) return false;
+  __ cmp(R1, Operand(0));
+  __ b(return_false, LT);
+
+  // if (start + other.length > this.length) return false;
+  __ add(R3, R1, Operand(R9));
+  __ cmp(R3, Operand(R8));
+  __ b(return_false, GT);
+
+  if (receiver_cid == kOneByteStringCid) {
+    __ AddImmediate(R0, R0, OneByteString::data_offset() - kHeapObjectTag);
+    __ add(R0, R0, Operand(R1));
+  } else {
+    ASSERT(receiver_cid == kTwoByteStringCid);
+    __ AddImmediate(R0, R0, TwoByteString::data_offset() - kHeapObjectTag);
+    __ add(R0, R0, Operand(R1));
+    __ add(R0, R0, Operand(R1));
+  }
+  if (other_cid == kOneByteStringCid) {
+    __ AddImmediate(R2, R2, OneByteString::data_offset() - kHeapObjectTag);
+  } else {
+    ASSERT(other_cid == kTwoByteStringCid);
+    __ AddImmediate(R2, R2, TwoByteString::data_offset() - kHeapObjectTag);
+  }
+
+  // i = 0
+  __ LoadImmediate(R3, 0);
+
+  // do
+  Label loop;
+  __ Bind(&loop);
+
+  // this.codeUnitAt(i + start)
+  __ ldr(R10, Address(R0, 0),
+         receiver_cid == kOneByteStringCid ? kUnsignedByte : kUnsignedHalfword);
+  // other.codeUnitAt(i)
+  __ ldr(R11, Address(R2, 0),
+         other_cid == kOneByteStringCid ? kUnsignedByte : kUnsignedHalfword);
+  __ cmp(R10, Operand(R11));
+  __ b(return_false, NE);
+
+  // i++, while (i < len)
+  __ add(R3, R3, Operand(1));
+  __ add(R0, R0, Operand(receiver_cid == kOneByteStringCid ? 1 : 2));
+  __ add(R2, R2, Operand(other_cid == kOneByteStringCid ? 1 : 2));
+  __ cmp(R3, Operand(R9));
+  __ b(&loop, LT);
+
+  __ b(return_true);
+}
+
+
+// bool _substringMatches(int start, String other)
+// This intrinsic handles a OneByteString or TwoByteString receiver with a
+// OneByteString other.
+void Intrinsifier::StringBaseSubstringMatches(Assembler* assembler) {
+  Label fall_through, return_true, return_false, try_two_byte;
+  __ ldr(R0, Address(SP, 2 * kWordSize));  // this
+  __ ldr(R1, Address(SP, 1 * kWordSize));  // start
+  __ ldr(R2, Address(SP, 0 * kWordSize));  // other
+
+  __ tsti(R1, Immediate(kSmiTagMask));
+  __ b(&fall_through, NE);  // 'start' is not a Smi.
+
+  __ CompareClassId(R2, kOneByteStringCid);
+  __ b(&fall_through, NE);
+
+  __ CompareClassId(R0, kOneByteStringCid);
+  __ b(&fall_through, NE);
+
+  GenerateSubstringMatchesSpecialization(assembler,
+                                         kOneByteStringCid,
+                                         kOneByteStringCid,
+                                         &return_true,
+                                         &return_false);
+
+  __ Bind(&try_two_byte);
+  __ CompareClassId(R0, kTwoByteStringCid);
+  __ b(&fall_through, NE);
+
+  GenerateSubstringMatchesSpecialization(assembler,
+                                         kTwoByteStringCid,
+                                         kOneByteStringCid,
+                                         &return_true,
+                                         &return_false);
+
+  __ Bind(&return_true);
+  __ LoadObject(R0, Bool::True());
+  __ ret();
+
+  __ Bind(&return_false);
+  __ LoadObject(R0, Bool::False());
+  __ ret();
+
+  __ Bind(&fall_through);
+}
+
+
 void Intrinsifier::StringBaseCharAt(Assembler* assembler) {
   Label fall_through, try_two_byte_string;
 
diff --git a/runtime/vm/intrinsifier_ia32.cc b/runtime/vm/intrinsifier_ia32.cc
index d39f3b6..577775e 100644
--- a/runtime/vm/intrinsifier_ia32.cc
+++ b/runtime/vm/intrinsifier_ia32.cc
@@ -33,6 +33,7 @@
 // The ECX, EDX registers can be destroyed only if there is no slow-path, i.e.
 // if the intrinsified method always executes a return.
 // The EBP register should not be modified, because it is used by the profiler.
+// The THR register (see constants_ia32.h) must be preserved.
 
 #define __ assembler->
 
@@ -1740,6 +1741,12 @@
 }
 
 
+// bool _substringMatches(int start, String other)
+void Intrinsifier::StringBaseSubstringMatches(Assembler* assembler) {
+  // For precompilation, not implemented on IA32.
+}
+
+
 void Intrinsifier::StringBaseCharAt(Assembler* assembler) {
   Label fall_through, try_two_byte_string;
   __ movl(EBX, Address(ESP, + 1 * kWordSize));  // Index.
diff --git a/runtime/vm/intrinsifier_mips.cc b/runtime/vm/intrinsifier_mips.cc
index 7349e85..2be1114 100644
--- a/runtime/vm/intrinsifier_mips.cc
+++ b/runtime/vm/intrinsifier_mips.cc
@@ -20,12 +20,12 @@
 DECLARE_FLAG(bool, interpret_irregexp);
 
 // When entering intrinsics code:
-// S5: IC Data
 // S4: Arguments descriptor
 // RA: Return address
-// The S5, S4 registers can be destroyed only if there is no slow-path, i.e.
+// The S4 register can be destroyed only if there is no slow-path, i.e.
 // if the intrinsified method always executes a return.
 // The FP register should not be modified, because it is used by the profiler.
+// The PP and THR registers (see constants_mips.h) must be preserved.
 
 #define __ assembler->
 
@@ -1470,7 +1470,7 @@
 
   __ lw(T0, Address(SP, 0 * kWordSize));
   __ andi(CMPRES1, T0, Immediate(kSmiTagMask));
-  __ bne(T0, ZR, &fall_through);
+  __ bne(CMPRES1, ZR, &fall_through);
 
   // Is Smi.
   __ SmiUntag(T0);
@@ -1681,7 +1681,7 @@
 
   // Checks.
   __ andi(CMPRES1, T1, Immediate(kSmiTagMask));
-  __ bne(T1, ZR, &fall_through);  // Index is not a Smi.
+  __ bne(CMPRES1, ZR, &fall_through);  // Index is not a Smi.
   __ lw(T2, FieldAddress(T0, String::length_offset()));  // Range check.
   // Runtime throws exception.
   __ BranchUnsignedGreaterEqual(T1, T2, &fall_through);
@@ -1708,6 +1708,118 @@
 }
 
 
+void GenerateSubstringMatchesSpecialization(Assembler* assembler,
+                                            intptr_t receiver_cid,
+                                            intptr_t other_cid,
+                                            Label* return_true,
+                                            Label* return_false) {
+  __ SmiUntag(A1);
+  __ lw(T1, FieldAddress(A0, String::length_offset()));  // this.length
+  __ SmiUntag(T1);
+  __ lw(T2, FieldAddress(A2, String::length_offset()));  // other.length
+  __ SmiUntag(T2);
+
+  // if (other.length == 0) return true;
+  __ beq(T2, ZR, return_true);
+
+  // if (start < 0) return false;
+  __ bltz(A1, return_false);
+
+  // if (start + other.length > this.length) return false;
+  __ addu(T0, A1, T2);
+  __ BranchSignedGreater(T0, T1, return_false);
+
+  if (receiver_cid == kOneByteStringCid) {
+    __ AddImmediate(A0, A0, OneByteString::data_offset() - kHeapObjectTag);
+    __ addu(A0, A0, A1);
+  } else {
+    ASSERT(receiver_cid == kTwoByteStringCid);
+    __ AddImmediate(A0, A0, TwoByteString::data_offset() - kHeapObjectTag);
+    __ addu(A0, A0, A1);
+    __ addu(A0, A0, A1);
+  }
+  if (other_cid == kOneByteStringCid) {
+    __ AddImmediate(A2, A2, OneByteString::data_offset() - kHeapObjectTag);
+  } else {
+    ASSERT(other_cid == kTwoByteStringCid);
+    __ AddImmediate(A2, A2, TwoByteString::data_offset() - kHeapObjectTag);
+  }
+
+  // i = 0
+  __ LoadImmediate(T0, 0);
+
+  // do
+  Label loop;
+  __ Bind(&loop);
+
+  if (receiver_cid == kOneByteStringCid) {
+    __ lbu(T3, Address(A0, 0));  // this.codeUnitAt(i + start)
+  } else {
+    __ lhu(T3, Address(A0, 0));  // this.codeUnitAt(i + start)
+  }
+  if (other_cid == kOneByteStringCid) {
+    __ lbu(T4, Address(A2, 0));  // other.codeUnitAt(i)
+  } else {
+    __ lhu(T4, Address(A2, 0));  // other.codeUnitAt(i)
+  }
+  __ bne(T3, T4, return_false);
+
+  // i++, while (i < len)
+  __ AddImmediate(T0, T0, 1);
+  __ AddImmediate(A0, A0, receiver_cid == kOneByteStringCid ? 1 : 2);
+  __ AddImmediate(A2, A2, other_cid == kOneByteStringCid ? 1 : 2);
+  __ BranchSignedLess(T0, T2, &loop);
+
+  __ b(return_true);
+}
+
+
+// bool _substringMatches(int start, String other)
+// This intrinsic handles a OneByteString or TwoByteString receiver with a
+// OneByteString other.
+void Intrinsifier::StringBaseSubstringMatches(Assembler* assembler) {
+  Label fall_through, return_true, return_false, try_two_byte;
+  __ lw(A0, Address(SP, 2 * kWordSize));  // this
+  __ lw(A1, Address(SP, 1 * kWordSize));  // start
+  __ lw(A2, Address(SP, 0 * kWordSize));  // other
+
+  __ andi(CMPRES1, A1, Immediate(kSmiTagMask));
+  __ bne(CMPRES1, ZR, &fall_through);  // 'start' is not a Smi.
+
+  __ LoadClassId(CMPRES1, A2);
+  __ BranchNotEqual(CMPRES1, Immediate(kOneByteStringCid), &fall_through);
+
+  __ LoadClassId(CMPRES1, A0);
+  __ BranchNotEqual(CMPRES1, Immediate(kOneByteStringCid), &try_two_byte);
+
+  GenerateSubstringMatchesSpecialization(assembler,
+                                         kOneByteStringCid,
+                                         kOneByteStringCid,
+                                         &return_true,
+                                         &return_false);
+
+  __ Bind(&try_two_byte);
+  __ LoadClassId(CMPRES1, A0);
+  __ BranchNotEqual(CMPRES1, Immediate(kTwoByteStringCid), &fall_through);
+
+  GenerateSubstringMatchesSpecialization(assembler,
+                                         kTwoByteStringCid,
+                                         kOneByteStringCid,
+                                         &return_true,
+                                         &return_false);
+
+  __ Bind(&return_true);
+  __ LoadObject(V0, Bool::True());
+  __ Ret();
+
+  __ Bind(&return_false);
+  __ LoadObject(V0, Bool::False());
+  __ Ret();
+
+  __ Bind(&fall_through);
+}
+
+
 void Intrinsifier::StringBaseCharAt(Assembler* assembler) {
   Label fall_through, try_two_byte_string;
 
@@ -1716,7 +1828,7 @@
 
   // Checks.
   __ andi(CMPRES1, T1, Immediate(kSmiTagMask));
-  __ bne(T1, ZR, &fall_through);  // Index is not a Smi.
+  __ bne(CMPRES1, ZR, &fall_through);  // Index is not a Smi.
   __ lw(T2, FieldAddress(T0, String::length_offset()));  // Range check.
   // Runtime throws exception.
   __ BranchUnsignedGreaterEqual(T1, T2, &fall_through);
diff --git a/runtime/vm/intrinsifier_x64.cc b/runtime/vm/intrinsifier_x64.cc
index 4598ddd..e3f2ca4 100644
--- a/runtime/vm/intrinsifier_x64.cc
+++ b/runtime/vm/intrinsifier_x64.cc
@@ -20,12 +20,12 @@
 DECLARE_FLAG(bool, interpret_irregexp);
 
 // When entering intrinsics code:
-// RBX: IC Data
 // R10: Arguments descriptor
 // TOS: Return address
-// The RBX, R10 registers can be destroyed only if there is no slow-path, i.e.
+// The R10 registers can be destroyed only if there is no slow-path, i.e.
 // if the intrinsified method always executes a return.
 // The RBP register should not be modified, because it is used by the profiler.
+// The PP and THR registers (see constants_x64.h) must be preserved.
 
 #define __ assembler->
 
@@ -1595,6 +1595,115 @@
 }
 
 
+void GenerateSubstringMatchesSpecialization(Assembler* assembler,
+                                            intptr_t receiver_cid,
+                                            intptr_t other_cid,
+                                            Label* return_true,
+                                            Label* return_false) {
+  __ movq(R8, FieldAddress(RAX, String::length_offset()));
+  __ movq(R9, FieldAddress(RCX, String::length_offset()));
+
+  // if (other.length == 0) return true;
+  __ testq(R9, R9);
+  __ j(ZERO, return_true);
+
+  // if (start < 0) return false;
+  __ testq(RBX, RBX);
+  __ j(SIGN, return_false);
+
+  // if (start + other.length > this.length) return false;
+  __ movq(R11, RBX);
+  __ addq(R11, R9);
+  __ cmpq(R11, R8);
+  __ j(GREATER, return_false);
+
+  __ SmiUntag(RBX);  // start
+  __ SmiUntag(R9);   // other.length
+  __ movq(R11, Immediate(0));  // i = 0
+
+  // do
+  Label loop;
+  __ Bind(&loop);
+
+  // this.codeUnitAt(i + start)
+  // clobbering this.length
+  __ movq(R8, R11);
+  __ addq(R8, RBX);
+  if (receiver_cid == kOneByteStringCid) {
+    __ movzxb(R12,
+              FieldAddress(RAX, R8, TIMES_1, OneByteString::data_offset()));
+  } else {
+    ASSERT(receiver_cid == kTwoByteStringCid);
+    __ movzxw(R12,
+              FieldAddress(RAX, R8, TIMES_2, TwoByteString::data_offset()));
+  }
+  // other.codeUnitAt(i)
+  if (other_cid == kOneByteStringCid) {
+    __ movzxb(R13,
+              FieldAddress(RCX, R11, TIMES_1, OneByteString::data_offset()));
+  } else {
+    ASSERT(other_cid == kTwoByteStringCid);
+    __ movzxw(R13,
+              FieldAddress(RCX, R11, TIMES_2, TwoByteString::data_offset()));
+  }
+  __ cmpq(R12, R13);
+  __ j(NOT_EQUAL, return_false);
+
+  // i++, while (i < len)
+  __ addq(R11, Immediate(1));
+  __ cmpq(R11, R9);
+  __ j(LESS, &loop, Assembler::kNearJump);
+
+  __ jmp(return_true);
+}
+
+
+// bool _substringMatches(int start, String other)
+// This intrinsic handles a OneByteString or TwoByteString receiver with a
+// OneByteString other.
+void Intrinsifier::StringBaseSubstringMatches(Assembler* assembler) {
+  Label fall_through, return_true, return_false, try_two_byte;
+  __ movq(RAX, Address(RSP, + 3 * kWordSize));  // receiver
+  __ movq(RBX, Address(RSP, + 2 * kWordSize));  // start
+  __ movq(RCX, Address(RSP, + 1 * kWordSize));  // other
+
+  __ testq(RBX, Immediate(kSmiTagMask));
+  __ j(NOT_ZERO, &fall_through);  // 'start' is not Smi.
+
+  __ CompareClassId(RCX, kOneByteStringCid);
+  __ j(NOT_EQUAL, &fall_through);
+
+  __ CompareClassId(RAX, kOneByteStringCid);
+  __ j(NOT_EQUAL, &try_two_byte);
+
+  GenerateSubstringMatchesSpecialization(assembler,
+                                         kOneByteStringCid,
+                                         kOneByteStringCid,
+                                         &return_true,
+                                         &return_false);
+
+  __ Bind(&try_two_byte);
+  __ CompareClassId(RAX, kTwoByteStringCid);
+  __ j(NOT_EQUAL, &fall_through);
+
+  GenerateSubstringMatchesSpecialization(assembler,
+                                         kTwoByteStringCid,
+                                         kOneByteStringCid,
+                                         &return_true,
+                                         &return_false);
+
+  __ Bind(&return_true);
+  __ LoadObject(RAX, Bool::True());
+  __ ret();
+
+  __ Bind(&return_false);
+  __ LoadObject(RAX, Bool::False());
+  __ ret();
+
+  __ Bind(&fall_through);
+}
+
+
 void Intrinsifier::StringBaseCharAt(Assembler* assembler) {
   Label fall_through, try_two_byte_string;
   __ movq(RCX, Address(RSP, + 1 * kWordSize));  // Index.
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index f7caee1..6d20157 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -217,7 +217,7 @@
 // [ OOB dispatch, Isolate library dispatch, <message specific data> ]
 RawError* IsolateMessageHandler::HandleLibMessage(const Array& message) {
   if (message.Length() < 2) return Error::null();
-  Zone* zone = I->current_zone();
+  Zone* zone = T->zone();
   const Object& type = Object::Handle(zone, message.At(1));
   if (!type.IsSmi()) return Error::null();
   const intptr_t msg_type = Smi::Cast(type).Value();
@@ -640,10 +640,10 @@
   }
 
   // Generate the error and stacktrace strings for the error message.
-  String& exc_str = String::Handle(I->current_zone());
-  String& stacktrace_str = String::Handle(I->current_zone());
+  String& exc_str = String::Handle(T->zone());
+  String& stacktrace_str = String::Handle(T->zone());
   if (result.IsUnhandledException()) {
-    Zone* zone = I->current_zone();
+    Zone* zone = T->zone();
     const UnhandledException& uhe = UnhandledException::Cast(result);
     const Instance& exception = Instance::Handle(zone, uhe.exception());
     Object& tmp = Object::Handle(zone);
@@ -718,7 +718,7 @@
 
 void BaseIsolate::AssertCurrentThreadIsMutator() const {
   ASSERT(Isolate::Current() == this);
-  ASSERT(Isolate::Current()->MutatorThreadIsCurrentThread());
+  ASSERT(Thread::Current()->IsMutatorThread());
 }
 #endif  // defined(DEBUG)
 
@@ -736,7 +736,6 @@
   :   stack_limit_(0),
       store_buffer_(new StoreBuffer()),
       heap_(NULL),
-      vm_tag_(0),
       user_tag_(0),
       current_tag_(UserTag::null()),
       default_tag_(UserTag::null()),
@@ -777,7 +776,6 @@
       gc_epilogue_callback_(NULL),
       defer_finalization_count_(0),
       deopt_context_(NULL),
-      background_compiler_(NULL),
       compiler_stats_(NULL),
       is_service_isolate_(false),
       stacktrace_(NULL),
@@ -786,17 +784,19 @@
       last_allocationprofile_gc_timestamp_(0),
       object_id_ring_(NULL),
       trace_buffer_(NULL),
-      profiler_data_(NULL),
       tag_table_(GrowableObjectArray::null()),
-      collected_closures_(GrowableObjectArray::null()),
       deoptimized_code_array_(GrowableObjectArray::null()),
-      background_compilation_queue_(GrowableObjectArray::null()),
+      background_compiler_(NULL),
       pending_service_extension_calls_(GrowableObjectArray::null()),
       registered_service_extension_handlers_(GrowableObjectArray::null()),
       metrics_list_head_(NULL),
       compilation_allowed_(true),
+      all_classes_finalized_(false),
       next_(NULL),
-      pause_loop_monitor_(NULL) {
+      pause_loop_monitor_(NULL),
+      cha_invalidation_gen_(kInvalidGen),
+      field_invalidation_gen_(kInvalidGen),
+      prefix_invalidation_gen_(kInvalidGen) {
   flags_.CopyFrom(api_flags);
   Thread::Current()->set_vm_tag(VMTag::kEmbedderTagId);
   set_user_tag(UserTags::kDefaultUserTag);
@@ -864,7 +864,6 @@
   // Initialize Timeline streams.
 #define ISOLATE_TIMELINE_STREAM_INIT(name, enabled_by_default)                 \
   result->stream_##name##_.Init(#name,                                         \
-                                Timeline::EnableStreamByDefault(#name) ||      \
                                 enabled_by_default,                            \
                                 Timeline::Stream##name##EnabledFlag());
   ISOLATE_TIMELINE_STREAM_LIST(ISOLATE_TIMELINE_STREAM_INIT);
@@ -891,11 +890,6 @@
   ASSERT(state != NULL);
   result->set_api_state(state);
 
-  // Initialize stack limit (wait until later for the VM isolate, since the
-  // needed GetStackPointer stub has not yet been generated in that case).
-  if (!is_vm_isolate) {
-    result->InitializeStackLimit();
-  }
   result->set_main_port(PortMap::CreatePort(result->message_handler()));
 #if defined(DEBUG)
   // Verify that we are never reusing a live origin id.
@@ -935,11 +929,6 @@
 }
 
 
-void Isolate::InitializeStackLimit() {
-  SetStackLimitFromStackBase(Isolate::GetCurrentStackPointer());
-}
-
-
 /* static */
 uword Isolate::GetCurrentStackPointer() {
   // Since AddressSanitizer's detect_stack_use_after_return instruments the
@@ -1076,6 +1065,7 @@
       lib.SetLoaded();
     }
   }
+  TokenStream::CloseSharedTokenList(this);
 }
 
 
@@ -1453,11 +1443,8 @@
     }
     Dart::RunShutdownCallback();
   }
-  {
-    // Shut the isolate down.
-    SwitchIsolateScope switch_scope(isolate);
-    Dart::ShutdownIsolate();
-  }
+  // Shut the isolate down.
+  Dart::ShutdownIsolate(isolate);
 }
 
 
@@ -1530,6 +1517,62 @@
 }
 
 
+void Isolate::AddClosureFunction(const Function& function) const {
+  GrowableObjectArray& closures =
+      GrowableObjectArray::Handle(object_store()->closure_functions());
+  ASSERT(!closures.IsNull());
+  ASSERT(function.IsNonImplicitClosureFunction());
+  closures.Add(function, Heap::kOld);
+}
+
+
+// If the linear lookup turns out to be too expensive, the list
+// of closures could be maintained in a hash map, with the key
+// being the token position of the closure. There are almost no
+// collisions with this simple hash value. However, iterating over
+// all closure functions becomes more difficult, especially when
+// the list/map changes while iterating over it.
+RawFunction* Isolate::LookupClosureFunction(const Function& parent,
+                                            intptr_t token_pos) const {
+  const GrowableObjectArray& closures =
+      GrowableObjectArray::Handle(object_store()->closure_functions());
+  ASSERT(!closures.IsNull());
+  Function& closure = Function::Handle();
+  intptr_t num_closures = closures.Length();
+  for (intptr_t i = 0; i < num_closures; i++) {
+    closure ^= closures.At(i);
+    if ((closure.token_pos() == token_pos) &&
+        (closure.parent_function() == parent.raw())) {
+      return closure.raw();
+    }
+  }
+  return Function::null();
+}
+
+
+intptr_t Isolate::FindClosureIndex(const Function& needle) const {
+  const GrowableObjectArray& closures_array =
+      GrowableObjectArray::Handle(object_store()->closure_functions());
+  intptr_t num_closures = closures_array.Length();
+  for (intptr_t i = 0; i < num_closures; i++) {
+    if (closures_array.At(i) == needle.raw()) {
+      return i;
+    }
+  }
+  return -1;
+}
+
+
+RawFunction* Isolate::ClosureFunctionFromIndex(intptr_t idx) const {
+  const GrowableObjectArray& closures_array =
+      GrowableObjectArray::Handle(object_store()->closure_functions());
+  if ((idx < 0) || (idx >= closures_array.Length())) {
+    return Function::null();
+  }
+  return Function::RawCast(closures_array.At(idx));
+}
+
+
 static void AddFunctionsFromClass(const Class& cls,
                                   GrowableArray<const Function*>* functions) {
   const Array& class_functions = Array::Handle(cls.functions());
@@ -1616,7 +1659,7 @@
   set_message_handler(NULL);
 
   // Before analyzing the isolate's timeline blocks- reclaim all cached blocks.
-  ReclaimTimelineBlocks();
+  Timeline::ReclaimCachedBlocksFromThreads();
 
   // Dump all timing data for the isolate.
   if (FLAG_timing) {
@@ -1651,7 +1694,9 @@
 
 void Isolate::Shutdown() {
   ASSERT(this == Isolate::Current());
-  ASSERT(top_resource() == NULL);
+  // Wait until all background compilation has finished.
+  BackgroundCompiler::Stop(background_compiler_);
+
 #if defined(DEBUG)
   if (heap_ != NULL) {
     // The VM isolate keeps all objects marked.
@@ -1661,6 +1706,9 @@
 
   Thread* thread = Thread::Current();
 
+  // Don't allow anymore dart code to execution on this isolate.
+  ClearStackLimit();
+
   // First, perform higher-level cleanup that may need to allocate.
   {
     // Ensure we have a zone and handle scope so that we can call VM functions.
@@ -1707,23 +1755,11 @@
   }
 #endif
 
-  BackgroundCompiler::Stop(background_compiler_);
-
   // TODO(5411455): For now just make sure there are no current isolates
   // as we are shutting down the isolate.
   Thread::ExitIsolate();
   // All threads should have exited by now.
   thread_registry()->CheckNotScheduled(this);
-  Profiler::ShutdownProfilingForIsolate(this);
-}
-
-
-void Isolate::ReclaimTimelineBlocks() {
-  TimelineEventRecorder* recorder = Timeline::recorder();
-  if (recorder == NULL) {
-    return;
-  }
-  thread_registry_->ReclaimTimelineBlocks();
 }
 
 
@@ -1778,11 +1814,9 @@
   // Visit the tag table which is stored in the isolate.
   visitor->VisitPointer(reinterpret_cast<RawObject**>(&tag_table_));
 
-  // Visit array of closures pending precompilation.
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&collected_closures_));
-
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(
-      &background_compilation_queue_));
+  if (background_compiler() != NULL) {
+    background_compiler()->VisitPointers(visitor);
+  }
 
   // Visit the deoptimized code array which is stored in the isolate.
   visitor->VisitPointer(
@@ -1842,17 +1876,17 @@
 void Isolate::PrintJSON(JSONStream* stream, bool ref) {
   JSONObject jsobj(stream);
   jsobj.AddProperty("type", (ref ? "@Isolate" : "Isolate"));
-  jsobj.AddFixedServiceId("isolates/%" Pd "",
-                          static_cast<intptr_t>(main_port()));
+  jsobj.AddFixedServiceId("isolates/%" Pd64 "",
+                          static_cast<int64_t>(main_port()));
 
   jsobj.AddProperty("name", debugger_name());
-  jsobj.AddPropertyF("number", "%" Pd "",
-                     static_cast<intptr_t>(main_port()));
+  jsobj.AddPropertyF("number", "%" Pd64 "",
+                     static_cast<int64_t>(main_port()));
   if (ref) {
     return;
   }
-  jsobj.AddPropertyF("_originNumber", "%" Pd "",
-                     static_cast<intptr_t>(origin_id()));
+  jsobj.AddPropertyF("_originNumber", "%" Pd64 "",
+                     static_cast<int64_t>(origin_id()));
   int64_t start_time_millis = start_time() / kMicrosecondsPerMillisecond;
   jsobj.AddPropertyTimeMillis("startTime", start_time_millis);
   {
@@ -1900,8 +1934,7 @@
     vm_tag_counters()->PrintToJSONObject(&tagCounters);
   }
   if (object_store()->sticky_error() != Object::null()) {
-    Error& error = Error::Handle(current_zone(),
-        object_store()->sticky_error());
+    Error& error = Error::Handle(object_store()->sticky_error());
     ASSERT(!error.IsNull());
     jsobj.AddProperty("error", error, false);
   }
@@ -1931,62 +1964,6 @@
 }
 
 
-intptr_t Isolate::ProfileInterrupt() {
-  // Other threads might be modifying these fields. Save them in locals so that
-  // we can at least trust the NULL check.
-  IsolateProfilerData* prof_data = profiler_data();
-  if (prof_data == NULL) {
-    // Profiler not setup for isolate.
-    return 0;
-  }
-  if (prof_data->blocked()) {
-    // Profiler blocked for this isolate.
-    return 0;
-  }
-  Debugger* debug = debugger();
-  if ((debug != NULL) && debug->IsPaused()) {
-    // Paused at breakpoint. Don't tick.
-    return 0;
-  }
-  MessageHandler* msg_handler = message_handler();
-  if ((msg_handler != NULL) &&
-      (msg_handler->paused_on_start() ||
-       msg_handler->paused_on_exit())) {
-    // Paused at start / exit . Don't tick.
-    return 0;
-  }
-  // Make sure that the isolate's mutator thread does not change behind our
-  // backs. Otherwise we find the entry in the registry and end up reading
-  // the field again. Only by that time it has been reset to NULL because the
-  // thread was in process of exiting the isolate.
-  Thread* mutator = mutator_thread_;
-  if (mutator == NULL) {
-    // No active mutator.
-    ProfileIdle();
-    return 1;
-  }
-
-  // TODO(johnmccutchan): Sample all threads, not just the mutator thread.
-  // TODO(johnmccutchan): Keep a global list of threads and use that
-  // instead of Isolate.
-  ThreadRegistry::EntryIterator it(thread_registry());
-  while (it.HasNext()) {
-    const ThreadRegistry::Entry& entry = it.Next();
-    if (entry.thread == mutator) {
-      ThreadInterrupter::InterruptThread(mutator);
-      break;
-    }
-  }
-  return 1;
-}
-
-
-void Isolate::ProfileIdle() {
-  // Currently we are only sampling the mutator thread.
-  vm_tag_counters_.Increment(VMTag::kIdleTagId);
-}
-
-
 void Isolate::set_tag_table(const GrowableObjectArray& value) {
   tag_table_ = value.raw();
 }
@@ -2004,23 +1981,17 @@
   default_tag_ = tag.raw();
 }
 
-
-void Isolate::set_collected_closures(const GrowableObjectArray& value) {
-  collected_closures_ = value.raw();
+void Isolate::set_ic_miss_code(const Code& code) {
+  ic_miss_code_ = code.raw();
 }
 
 
 void Isolate::set_deoptimized_code_array(const GrowableObjectArray& value) {
+  ASSERT(Thread::Current()->IsMutatorThread());
   deoptimized_code_array_ = value.raw();
 }
 
 
-void Isolate::set_background_compilation_queue(
-    const GrowableObjectArray& value) {
-  background_compilation_queue_ = value.raw();
-}
-
-
 void Isolate::TrackDeoptimizedCode(const Code& code) {
   ASSERT(!code.IsNull());
   const GrowableObjectArray& deoptimized_code =
@@ -2436,6 +2407,8 @@
 
 
 IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
+                                     Dart_Port origin_id,
+                                     void* init_data,
                                      const Function& func,
                                      const Instance& message,
                                      bool paused,
@@ -2444,6 +2417,8 @@
                                      Dart_Port on_error_port)
     : isolate_(NULL),
       parent_port_(parent_port),
+      origin_id_(origin_id),
+      init_data_(init_data),
       on_exit_port_(on_exit_port),
       on_error_port_(on_error_port),
       script_url_(NULL),
@@ -2481,6 +2456,7 @@
 
 
 IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
+                                     void* init_data,
                                      const char* script_url,
                                      const char* package_root,
                                      const char** package_map,
@@ -2492,6 +2468,8 @@
                                      Dart_Port on_error_port)
     : isolate_(NULL),
       parent_port_(parent_port),
+      origin_id_(ILLEGAL_PORT),
+      init_data_(init_data),
       on_exit_port_(on_exit_port),
       on_error_port_(on_error_port),
       script_url_(script_url),
@@ -2621,9 +2599,4 @@
 }
 
 
-void IsolateSpawnState::Cleanup() {
-  SwitchIsolateScope switch_scope(I);
-  Dart::ShutdownIsolate();
-}
-
 }  // namespace dart
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 00abb13..547ce08 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -138,6 +138,10 @@
     return OFFSET_OF(Isolate, class_table_);
   }
 
+  static intptr_t ic_miss_code_offset() {
+    return OFFSET_OF(Isolate, ic_miss_code_);
+  }
+
   Dart_MessageNotifyCallback message_notify_callback() const {
     return message_notify_callback_;
   }
@@ -151,8 +155,8 @@
   bool HasMutatorThread() {
     return mutator_thread_ != NULL;
   }
-  bool MutatorThreadIsCurrentThread() {
-    return mutator_thread_ == Thread::Current();
+  Thread* mutator_thread() const {
+    return mutator_thread_;
   }
 
   const char* name() const { return name_; }
@@ -188,26 +192,6 @@
   ObjectStore* object_store() const { return object_store_; }
   void set_object_store(ObjectStore* value) { object_store_ = value; }
 
-  // DEPRECATED: Use Thread's methods instead. During migration, these default
-  // to using the mutator thread (which must also be the current thread).
-  StackResource* top_resource() const {
-    ASSERT(Thread::Current() == mutator_thread_);
-    return mutator_thread_->top_resource();
-  }
-  void set_top_resource(StackResource* value) {
-    ASSERT(Thread::Current() == mutator_thread_);
-    mutator_thread_->set_top_resource(value);
-  }
-  // DEPRECATED: Use Thread's methods instead. During migration, these default
-  // to using the mutator thread.
-  // NOTE: These are also used by the profiler.
-  uword top_exit_frame_info() const {
-    return mutator_thread_->top_exit_frame_info();
-  }
-  void set_top_exit_frame_info(uword value) {
-    mutator_thread_->set_top_exit_frame_info(value);
-  }
-
   ApiState* api_state() const { return api_state_; }
   void set_api_state(ApiState* value) { api_state_ = value; }
 
@@ -232,7 +216,6 @@
     library_tag_handler_ = value;
   }
 
-  void InitializeStackLimit();
   void SetStackLimit(uword value);
   void SetStackLimitFromStackBase(uword stack_base);
   void ClearStackLimit();
@@ -570,27 +553,12 @@
     return defer_finalization_count_ == 0;
   }
 
-  Mutex* profiler_data_mutex() {
-    return &profiler_data_mutex_;
-  }
-
-  void set_profiler_data(IsolateProfilerData* profiler_data) {
-    profiler_data_ = profiler_data;
-  }
-
-  IsolateProfilerData* profiler_data() const {
-    return profiler_data_;
-  }
-
   void PrintJSON(JSONStream* stream, bool ref = true);
 
   CompilerStats* compiler_stats() {
     return compiler_stats_;
   }
 
-  // Returns the number of sampled threads.
-  intptr_t ProfileInterrupt();
-
   VMTagCounters* vm_tag_counters() {
     return &vm_tag_counters_;
   }
@@ -629,15 +597,7 @@
   RawUserTag* default_tag() const { return default_tag_; }
   void set_default_tag(const UserTag& tag);
 
-  RawGrowableObjectArray* collected_closures() const {
-    return collected_closures_;
-  }
-  void set_collected_closures(const GrowableObjectArray& value);
-
-  RawGrowableObjectArray* background_compilation_queue() const {
-    return background_compilation_queue_;
-  }
-  void set_background_compilation_queue(const GrowableObjectArray& value);
+  void set_ic_miss_code(const Code& code);
 
   Metric* metrics_list_head() {
     return metrics_list_head_;
@@ -658,6 +618,37 @@
     compilation_allowed_ = allowed;
   }
 
+  // In precompilation we finalize all regular classes before compiling.
+  bool all_classes_finalized() const { return all_classes_finalized_; }
+  void set_all_classes_finalized(bool value) {
+    all_classes_finalized_ = value;
+  }
+
+  static const uint32_t kInvalidGen = 0;
+
+  void IncrCHAInvalidationGen() {
+    cha_invalidation_gen_++;
+    if (cha_invalidation_gen_ == kInvalidGen) cha_invalidation_gen_++;
+  }
+  void ResetCHAInvalidationGen() { cha_invalidation_gen_ = kInvalidGen; }
+  uint32_t cha_invalidation_gen() const { return cha_invalidation_gen_; }
+
+
+  void IncrFieldInvalidationGen() {
+    field_invalidation_gen_++;
+    if (field_invalidation_gen_ == kInvalidGen) field_invalidation_gen_++;
+  }
+
+  void ResetFieldInvalidationGen() { field_invalidation_gen_ = kInvalidGen; }
+  uint32_t field_invalidation_gen() const { return field_invalidation_gen_; }
+
+  void IncrPrefixInvalidationGen() {
+    prefix_invalidation_gen_++;
+    if (prefix_invalidation_gen_ == kInvalidGen) prefix_invalidation_gen_++;
+  }
+  void ResetPrefixInvalidationGen() { prefix_invalidation_gen_ = kInvalidGen; }
+  uint32_t prefix_invalidation_gen() const { return prefix_invalidation_gen_; }
+
   RawObject* InvokePendingServiceExtensionCalls();
   void AppendServiceExtensionCall(const Instance& closure,
                            const String& method_name,
@@ -674,16 +665,11 @@
   // Handle service messages until we are told to resume execution.
   void PauseEventHandler();
 
-  // DEPRECATED: Use Thread's methods instead. During migration, these default
-  // to using the mutator thread (which must also be the current thread).
-  Zone* current_zone() const {
-    ASSERT(Thread::Current() == mutator_thread_);
-    return mutator_thread_->zone();
-  }
-  void set_current_zone(Zone* zone) {
-    ASSERT(Thread::Current() == mutator_thread_);
-    mutator_thread_->set_zone(zone);
-  }
+  void AddClosureFunction(const Function& function) const;
+  RawFunction* LookupClosureFunction(const Function& parent,
+                                     intptr_t token_pos) const;
+  intptr_t FindClosureIndex(const Function& needle) const;
+  RawFunction* ClosureFunctionFromIndex(intptr_t idx) const;
 
   bool is_service_isolate() const { return is_service_isolate_; }
 
@@ -709,7 +695,6 @@
 
   void LowLevelShutdown();
   void Shutdown();
-  void ReclaimTimelineBlocks();
 
   void BuildName(const char* name_prefix);
   void PrintInvokedFunctions();
@@ -749,14 +734,21 @@
   bool IsIsolateOf(Thread* thread);
 #endif  // DEBUG
 
+  // DEPRECATED: Use Thread's methods instead. During migration, these default
+  // to using the mutator thread (which must also be the current thread).
+  Zone* current_zone() const {
+    ASSERT(Thread::Current() == mutator_thread_);
+    return mutator_thread_->zone();
+  }
+
   // Accessed from generated code:
   uword stack_limit_;
   StoreBuffer* store_buffer_;
   Heap* heap_;
-  uword vm_tag_;
   uword user_tag_;
   RawUserTag* current_tag_;
   RawUserTag* default_tag_;
+  RawCode* ic_miss_code_;
   ClassTable class_table_;
   bool single_step_;
 
@@ -783,7 +775,7 @@
   Flags flags_;
   Random random_;
   Simulator* simulator_;
-  Mutex* mutex_;  // protects stack_limit_ and saved_stack_limit_.
+  Mutex* mutex_;  // protects stack_limit_, saved_stack_limit_, compiler stats.
   uword saved_stack_limit_;
   uword stack_base_;
   uword stack_overflow_flags_;
@@ -795,7 +787,6 @@
   Dart_GcEpilogueCallback gc_epilogue_callback_;
   intptr_t defer_finalization_count_;
   DeoptContext* deopt_context_;
-  BackgroundCompiler* background_compiler_;
 
   CompilerStats* compiler_stats_;
 
@@ -815,16 +806,13 @@
   // Trace buffer support.
   TraceBuffer* trace_buffer_;
 
-  IsolateProfilerData* profiler_data_;
-  Mutex profiler_data_mutex_;
-
   VMTagCounters vm_tag_counters_;
   RawGrowableObjectArray* tag_table_;
 
-
-  RawGrowableObjectArray* collected_closures_;
   RawGrowableObjectArray* deoptimized_code_array_;
-  RawGrowableObjectArray* background_compilation_queue_;
+
+  // Background compilation.
+  BackgroundCompiler* background_compiler_;
 
   // We use 6 list entries for each pending service extension calls.
   enum {
@@ -849,6 +837,7 @@
   Metric* metrics_list_head_;
 
   bool compilation_allowed_;
+  bool all_classes_finalized_;
 
   // Isolate list next pointer.
   Isolate* next_;
@@ -856,6 +845,13 @@
   // Used to wake the isolate when it is in the pause event loop.
   Monitor* pause_loop_monitor_;
 
+  // Invalidation generations; used to track events occuring in parallel
+  // to background compilation. The counters may overflow, which is OK
+  // since we check for equality to detect if an event occured.
+  uint32_t cha_invalidation_gen_;
+  uint32_t field_invalidation_gen_;
+  uint32_t prefix_invalidation_gen_;
+
 #define ISOLATE_METRIC_VARIABLE(type, variable, name, unit)                    \
   type metric_##variable##_;
   ISOLATE_METRIC_LIST(ISOLATE_METRIC_VARIABLE);
@@ -911,28 +907,29 @@
       : new_isolate_(new_isolate), saved_isolate_(Isolate::Current()) {
     // TODO(koda): Audit users; passing NULL goes against naming of this class.
     if (new_isolate_ == NULL) {
+      ASSERT(Isolate::Current() == NULL);
       // Do nothing.
       return;
     }
     if (saved_isolate_ != new_isolate_) {
       ASSERT(Isolate::Current() == NULL);
+      // Ensure this is not a nested 'isolate enter' with prior state.
+      ASSERT(new_isolate_->stack_base() == 0);
       Thread::EnterIsolate(new_isolate_);
-      new_isolate_->SetStackLimitFromStackBase(
-          Isolate::GetCurrentStackPointer());
     }
   }
 
   ~StartIsolateScope() {
     if (new_isolate_ == NULL) {
+      ASSERT(Isolate::Current() == NULL);
       // Do nothing.
       return;
     }
     if (saved_isolate_ != new_isolate_) {
-      new_isolate_->ClearStackLimit();
+      ASSERT(saved_isolate_ == NULL);
+      // ASSERT that we have bottomed out of all Dart invocations.
+      ASSERT(new_isolate_->stack_base() == 0);
       Thread::ExitIsolate();
-      if (saved_isolate_ != NULL) {
-        Thread::EnterIsolate(saved_isolate_);
-      }
     }
   }
 
@@ -943,52 +940,12 @@
   DISALLOW_COPY_AND_ASSIGN(StartIsolateScope);
 };
 
-// When we need to temporarily become another isolate, we use the
-// SwitchIsolateScope.  It is not permitted to run dart code while in
-// a SwitchIsolateScope.
-class SwitchIsolateScope {
- public:
-  explicit SwitchIsolateScope(Isolate* new_isolate)
-      : new_isolate_(new_isolate),
-        saved_isolate_(Isolate::Current()),
-        saved_stack_limit_(saved_isolate_
-                           ? saved_isolate_->saved_stack_limit() : 0) {
-    // TODO(koda): Audit users; why would these two ever be equal?
-    if (saved_isolate_ != new_isolate_) {
-      if (new_isolate_ == NULL) {
-        Thread::ExitIsolate();
-      } else {
-        Thread::EnterIsolate(new_isolate_);
-        // Don't allow dart code to execute.
-        new_isolate_->SetStackLimit(~static_cast<uword>(0));
-      }
-    }
-  }
-
-  ~SwitchIsolateScope() {
-    if (saved_isolate_ != new_isolate_) {
-      if (new_isolate_ != NULL) {
-        Thread::ExitIsolate();
-      }
-      if (saved_isolate_ != NULL) {
-        Thread::EnterIsolate(saved_isolate_);
-        saved_isolate_->SetStackLimit(saved_stack_limit_);
-      }
-    }
-  }
-
- private:
-  Isolate* new_isolate_;
-  Isolate* saved_isolate_;
-  uword saved_stack_limit_;
-
-  DISALLOW_COPY_AND_ASSIGN(SwitchIsolateScope);
-};
-
 
 class IsolateSpawnState {
  public:
   IsolateSpawnState(Dart_Port parent_port,
+                    Dart_Port origin_id,
+                    void* init_data,
                     const Function& func,
                     const Instance& message,
                     bool paused,
@@ -996,6 +953,7 @@
                     Dart_Port onExit,
                     Dart_Port onError);
   IsolateSpawnState(Dart_Port parent_port,
+                    void* init_data,
                     const char* script_url,
                     const char* package_root,
                     const char** package_map,
@@ -1011,6 +969,8 @@
   void set_isolate(Isolate* value) { isolate_ = value; }
 
   Dart_Port parent_port() const { return parent_port_; }
+  Dart_Port origin_id() const { return origin_id_; }
+  void* init_data() const { return init_data_; }
   Dart_Port on_exit_port() const { return on_exit_port_; }
   Dart_Port on_error_port() const { return on_error_port_; }
   const char* script_url() const { return script_url_; }
@@ -1027,11 +987,12 @@
   RawObject* ResolveFunction();
   RawInstance* BuildArgs(Thread* thread);
   RawInstance* BuildMessage(Thread* thread);
-  void Cleanup();
 
  private:
   Isolate* isolate_;
   Dart_Port parent_port_;
+  Dart_Port origin_id_;
+  void* init_data_;
   Dart_Port on_exit_port_;
   Dart_Port on_error_port_;
   const char* script_url_;
diff --git a/runtime/vm/isolate_test.cc b/runtime/vm/isolate_test.cc
index 8dcc14e..d5d87cf 100644
--- a/runtime/vm/isolate_test.cc
+++ b/runtime/vm/isolate_test.cc
@@ -77,7 +77,8 @@
   EXPECT(!Dart_IsError(result));
   // Run until all ports to isolate are closed.
   result = Dart_RunLoop();
-  EXPECT_ERROR(result, "Null callback specified for isolate creation");
+  EXPECT_ERROR(result,
+               "Isolate spawn is not supported by this Dart implementation");
   EXPECT(Dart_ErrorHasException(result));
   Dart_Handle exception_result = Dart_ErrorGetException(result);
   EXPECT_VALID(exception_result);
diff --git a/runtime/vm/json_stream.cc b/runtime/vm/json_stream.cc
index 0f4f3a6..9f94205 100644
--- a/runtime/vm/json_stream.cc
+++ b/runtime/vm/json_stream.cc
@@ -30,7 +30,9 @@
       method_(""),
       param_keys_(NULL),
       param_values_(NULL),
-      num_params_(0) {
+      num_params_(0),
+      offset_(0),
+      count_(-1) {
   ObjectIdRing* ring = NULL;
   Isolate* isolate = Isolate::Current();
   if (isolate != NULL) {
@@ -245,6 +247,29 @@
 }
 
 
+void JSONStream::ComputeOffsetAndCount(intptr_t length,
+                                       intptr_t* offset,
+                                       intptr_t* count) {
+  // This function is written to avoid adding (count + offset) in case
+  // that triggers an integer overflow.
+  *offset = offset_;
+  if (*offset > length) {
+    *offset = length;
+  }
+  intptr_t remaining = length - *offset;
+  *count = count_;
+  if (*count < 0 || *count > remaining) {
+    *count = remaining;
+  }
+}
+
+
+void JSONStream::AppendSerializedObject(const char* serialized_object) {
+  PrintCommaIfNeeded();
+  buffer_.AddString(serialized_object);
+}
+
+
 void JSONStream::Clear() {
   buffer_.Clear();
   open_objects_ = 0;
@@ -285,6 +310,11 @@
 }
 
 
+void JSONStream::PrintValueNull() {
+  PrintCommaIfNeeded();
+  buffer_.Printf("null");
+}
+
 void JSONStream::PrintValueBool(bool b) {
   PrintCommaIfNeeded();
   buffer_.Printf("%s", b ? "true" : "false");
diff --git a/runtime/vm/json_stream.h b/runtime/vm/json_stream.h
index cd8fe62..318702c 100644
--- a/runtime/vm/json_stream.h
+++ b/runtime/vm/json_stream.h
@@ -109,6 +109,23 @@
   const char** param_keys() const { return param_keys_; }
   const char** param_values() const { return param_values_; }
 
+  void set_offset(intptr_t value) {
+    ASSERT(value > 0);
+    offset_ = value;
+  }
+
+  void set_count(intptr_t value) {
+    ASSERT(value > 0);
+    count_ = value;
+  }
+
+  void ComputeOffsetAndCount(intptr_t length,
+                             intptr_t* offset,
+                             intptr_t* count);
+
+  // Append |serialized_object| to the stream.
+  void AppendSerializedObject(const char* serialized_object);
+
  private:
   void Clear();
   void PostNullReply(Dart_Port port);
@@ -119,6 +136,7 @@
   void OpenArray(const char* property_name = NULL);
   void CloseArray();
 
+  void PrintValueNull();
   void PrintValueBool(bool b);
   void PrintValue(intptr_t i);
   void PrintValue64(int64_t i);
@@ -188,6 +206,8 @@
   const char** param_keys_;
   const char** param_values_;
   intptr_t num_params_;
+  intptr_t offset_;
+  intptr_t count_;
   int64_t setup_time_micros_;
 
   friend class JSONObject;
@@ -309,6 +329,7 @@
     stream_->CloseArray();
   }
 
+  void AddValueNull() const { stream_->PrintValueNull(); }
   void AddValue(bool b) const { stream_->PrintValueBool(b); }
   void AddValue(intptr_t i) const { stream_->PrintValue(i); }
   void AddValue64(int64_t i) const { stream_->PrintValue64(i); }
diff --git a/runtime/vm/longjump.cc b/runtime/vm/longjump.cc
index e2cf726..5820a47 100644
--- a/runtime/vm/longjump.cc
+++ b/runtime/vm/longjump.cc
@@ -26,14 +26,14 @@
   // We do not want to jump past Dart frames.  Note that this code
   // assumes the stack grows from high to low.
   Thread* thread = Thread::Current();
-  Isolate* isolate = thread->isolate();
   uword jumpbuf_addr = Isolate::GetCurrentStackPointer();
 #if defined(USING_SIMULATOR)
-  uword top_exit_frame_info = isolate->simulator()->top_exit_frame_info();
+  Simulator* sim = Simulator::Current();
+  uword top_exit_frame_info = sim->top_exit_frame_info();
 #else
   uword top_exit_frame_info = thread->top_exit_frame_info();
 #endif
-  if (!isolate->MutatorThreadIsCurrentThread()) {
+  if (!thread->IsMutatorThread()) {
     // A helper thread does not execute Dart code, so it's safe to jump.
     ASSERT(top_exit_frame_info == 0);
     return true;
diff --git a/runtime/vm/megamorphic_cache_table.cc b/runtime/vm/megamorphic_cache_table.cc
index 7f98d3b..7f4bbec 100644
--- a/runtime/vm/megamorphic_cache_table.cc
+++ b/runtime/vm/megamorphic_cache_table.cc
@@ -15,31 +15,30 @@
 RawMegamorphicCache* MegamorphicCacheTable::Lookup(Isolate* isolate,
                                                    const String& name,
                                                    const Array& descriptor) {
+  // Multiple compilation threads could access this lookup.
+  MutexLocker ml(isolate->mutex());
   ASSERT(name.IsSymbol());
   // TODO(rmacnak): ASSERT(descriptor.IsCanonical());
 
   // TODO(rmacnak): Make a proper hashtable a la symbol table.
   GrowableObjectArray& table = GrowableObjectArray::Handle(
       isolate->object_store()->megamorphic_cache_table());
+  MegamorphicCache& cache = MegamorphicCache::Handle();
   if (table.IsNull()) {
     table = GrowableObjectArray::New(Heap::kOld);
-    ASSERT((table.Length() % kEntrySize) == 0);
     isolate->object_store()->set_megamorphic_cache_table(table);
   } else {
-    for (intptr_t i = 0; i < table.Length(); i += kEntrySize) {
-      if ((table.At(i + kEntryNameOffset) == name.raw()) &&
-          (table.At(i + kEntryDescriptorOffset) == descriptor.raw())) {
-        return MegamorphicCache::RawCast(table.At(i + kEntryCacheOffset));
+    for (intptr_t i = 0; i < table.Length(); i++) {
+      cache ^= table.At(i);
+      if ((cache.target_name() == name.raw()) &&
+          (cache.arguments_descriptor() == descriptor.raw())) {
+        return cache.raw();
       }
     }
   }
 
-  const MegamorphicCache& cache =
-      MegamorphicCache::Handle(MegamorphicCache::New());
-  table.Add(name, Heap::kOld);
-  table.Add(descriptor, Heap::kOld);
+  cache = MegamorphicCache::New(name, descriptor);
   table.Add(cache, Heap::kOld);
-  ASSERT((table.Length() % kEntrySize) == 0);
   return cache.raw();
 }
 
@@ -89,14 +88,14 @@
   const GrowableObjectArray& table = GrowableObjectArray::Handle(
       isolate->object_store()->megamorphic_cache_table());
   if (table.IsNull()) return;
-  for (intptr_t i = 0; i < table.Length(); i += kEntrySize) {
-    cache ^= table.At(i + kEntryCacheOffset);
+  for (intptr_t i = 0; i < table.Length(); i++) {
+    cache ^= table.At(i);
     buckets = cache.buckets();
     size += MegamorphicCache::InstanceSize();
     size += Array::InstanceSize(buckets.Length());
   }
   OS::Print("%" Pd " megamorphic caches using %" Pd "KB.\n",
-            table.Length() / kEntrySize, size / 1024);
+            table.Length(), size / 1024);
 }
 
 }  // namespace dart
diff --git a/runtime/vm/megamorphic_cache_table.h b/runtime/vm/megamorphic_cache_table.h
index c47d4d8..4c7242a 100644
--- a/runtime/vm/megamorphic_cache_table.h
+++ b/runtime/vm/megamorphic_cache_table.h
@@ -30,14 +30,6 @@
                                      const Array& descriptor);
 
   static void PrintSizes(Isolate* isolate);
-
- private:
-  enum {
-    kEntryNameOffset = 0,
-    kEntryDescriptorOffset,
-    kEntryCacheOffset,
-    kEntrySize
-  };
 };
 
 }  // namespace dart
diff --git a/runtime/vm/message.cc b/runtime/vm/message.cc
index dc638b2..54f40b4 100644
--- a/runtime/vm/message.cc
+++ b/runtime/vm/message.cc
@@ -196,8 +196,8 @@
                          current->Id());
     message.AddProperty("size", current->len());
     message.AddProperty("index", depth++);
-    message.AddProperty("_destinationPort",
-        static_cast<intptr_t>(current->dest_port()));
+    message.AddPropertyF("_destinationPort", "%" Pd64 "",
+        static_cast<int64_t>(current->dest_port()));
     message.AddProperty("_priority",
         Message::PriorityAsString(current->priority()));
     // TODO(johnmccutchan): Move port -> handler map out of Dart and into the
diff --git a/runtime/vm/message_handler.cc b/runtime/vm/message_handler.cc
index 47ab4b9..30194cd 100644
--- a/runtime/vm/message_handler.cc
+++ b/runtime/vm/message_handler.cc
@@ -183,10 +183,6 @@
   // If isolate() returns NULL StartIsolateScope does nothing.
   StartIsolateScope start_isolate(isolate());
 
-  // ThreadInterrupter may have gone to sleep while waiting for
-  // an isolate to start handling messages.
-  ThreadInterrupter::WakeUp();
-
   MessageStatus max_status = kOK;
   Message::Priority min_priority = ((allow_normal_messages && !paused())
                                     ? Message::kNormalPriority
diff --git a/runtime/vm/method_recognizer.h b/runtime/vm/method_recognizer.h
index 5e8e576..ba0e438 100644
--- a/runtime/vm/method_recognizer.h
+++ b/runtime/vm/method_recognizer.h
@@ -188,6 +188,7 @@
   V(_StringBase, get:hashCode, String_getHashCode, 2103025405)                 \
   V(_StringBase, get:isEmpty, StringBaseIsEmpty, 780870414)                    \
   V(_StringBase, codeUnitAt, StringBaseCodeUnitAt, 397735324)                  \
+  V(_StringBase, _substringMatches, StringBaseSubstringMatches, 347814979)     \
   V(_StringBase, [], StringBaseCharAt, 408544820)                              \
   V(_OneByteString, get:hashCode, OneByteString_getHashCode, 1111957093)       \
   V(_OneByteString, _substringUncheckedNative,                                 \
@@ -301,6 +302,7 @@
   V(_GrowableList, [], GrowableArrayGetIndexed, 1962926024)                    \
   V(_GrowableList, []=, GrowableArraySetIndexed, 457344024)                    \
   V(_StringBase, get:length, StringBaseLength, 784518792)                      \
+  V(_Double, unary-, DoubleFlipSignBit, 2107492213)
 
 #define GRAPH_INTRINSICS_LIST(V)                                               \
   GRAPH_CORE_INTRINSICS_LIST(V)                                                \
@@ -422,6 +424,19 @@
   V(_HashVMBase, set:_hashMask, LinkedHashMap_setHashMask, 1781420082)         \
   V(_HashVMBase, get:_deletedKeys, LinkedHashMap_getDeletedKeys, 63633039)     \
   V(_HashVMBase, set:_deletedKeys, LinkedHashMap_setDeletedKeys, 2079107858)   \
+  V(Uint8List, ., Uint8ListFactory, 1844890525)                                \
+  V(Int8List, ., Int8ListFactory, 1802068996)                                  \
+  V(Uint16List, ., Uint16ListFactory, 1923962567)                              \
+  V(Int16List, ., Int16ListFactory, 2000007495)                                \
+  V(Uint32List, ., Uint32ListFactory, 1836019363)                              \
+  V(Int32List, ., Int32ListFactory, 442847136)                                 \
+  V(Uint64List, ., Uint64ListFactory, 196248223)                               \
+  V(Int64List, ., Int64ListFactory, 1668869084)                                \
+  V(Float32List, ., Float32ListFactory, 1367032554)                            \
+  V(Float64List, ., Float64ListFactory, 1886443347)                            \
+  V(Int32x4List, ., Int32x4ListFactory, 1409401969)                            \
+  V(Float32x4List, ., Float32x4ListFactory, 556438009)                         \
+  V(Float64x2List, ., Float64x2ListFactory, 1269752759)
 
 
 // A list of core function that should never be inlined.
@@ -495,6 +510,33 @@
 #endif  // defined(DART_NO_SNAPSHOT).
 
 
+// List of recognized list factories:
+// (factory-name-symbol, result-cid, fingerprint).
+#define RECOGNIZED_LIST_FACTORY_LIST(V)                                        \
+  V(_ListFactory, kArrayCid, 850375012)                                        \
+  V(_GrowableListWithData, kGrowableObjectArrayCid, 2094352700)                \
+  V(_GrowableListFactory, kGrowableObjectArrayCid, 1518848600)                 \
+  V(_Int8ArrayFactory, kTypedDataInt8ArrayCid, 439914696)                      \
+  V(_Uint8ArrayFactory, kTypedDataUint8ArrayCid, 1442599030)                   \
+  V(_Uint8ClampedArrayFactory, kTypedDataUint8ClampedArrayCid, 1320015159)     \
+  V(_Int16ArrayFactory, kTypedDataInt16ArrayCid, 2132591678)                   \
+  V(_Uint16ArrayFactory, kTypedDataUint16ArrayCid, 1704816032)                 \
+  V(_Int32ArrayFactory, kTypedDataInt32ArrayCid, 1115045147)                   \
+  V(_Uint32ArrayFactory, kTypedDataUint32ArrayCid, 1385852190)                 \
+  V(_Int64ArrayFactory, kTypedDataInt64ArrayCid, 1193438555)                   \
+  V(_Uint64ArrayFactory, kTypedDataUint64ArrayCid, 410766246)                  \
+  V(_Float64ArrayFactory, kTypedDataFloat64ArrayCid, 1430631000)               \
+  V(_Float32ArrayFactory, kTypedDataFloat32ArrayCid, 1194249144)               \
+  V(_Float32x4ArrayFactory, kTypedDataFloat32x4ArrayCid, 158753569)            \
+
+
+// Class that recognizes factories and returns corresponding result cid.
+class FactoryRecognizer : public AllStatic {
+ public:
+  // Return kDynamicCid if factory is not recognized.
+  static intptr_t ResultCid(const Function& factory);
+};
+
 }  // namespace dart
 
 #endif  // VM_METHOD_RECOGNIZER_H_
diff --git a/runtime/vm/native_api_impl.cc b/runtime/vm/native_api_impl.cc
index ce05529..9395bf3 100644
--- a/runtime/vm/native_api_impl.cc
+++ b/runtime/vm/native_api_impl.cc
@@ -69,14 +69,13 @@
 
 // --- Verification tools ---
 
-static void CompileAll(Isolate* isolate, Dart_Handle* result) {
-  ASSERT(isolate != NULL);
-  const Error& error =
-      Error::Handle(isolate->current_zone(), Library::CompileAll());
+static void CompileAll(Thread* thread, Dart_Handle* result) {
+  ASSERT(thread != NULL);
+  const Error& error = Error::Handle(thread->zone(), Library::CompileAll());
   if (error.IsNull()) {
     *result = Api::Success();
   } else {
-    *result = Api::NewHandle(isolate, error.raw());
+    *result = Api::NewHandle(thread->isolate(), error.raw());
   }
 }
 
@@ -88,7 +87,7 @@
     return result;
   }
   CHECK_CALLBACK_STATE(T);
-  CompileAll(I, &result);
+  CompileAll(T, &result);
   return result;
 }
 
diff --git a/runtime/vm/native_entry.cc b/runtime/vm/native_entry.cc
index 5d5a596..adedfb7 100644
--- a/runtime/vm/native_entry.cc
+++ b/runtime/vm/native_entry.cc
@@ -129,33 +129,17 @@
 }
 
 
-static bool IsNativeKeyword(const TokenStream::Iterator& it) {
-  return Token::IsIdentifier(it.CurrentTokenKind()) &&
-      (it.CurrentLiteral() == Symbols::Native().raw());
-}
-
-
 static NativeFunction ResolveNativeFunction(Zone* zone,
                                             const Function& func,
                                             bool* is_bootstrap_native) {
-  const Script& script = Script::Handle(zone, func.script());
   const Class& cls = Class::Handle(zone, func.Owner());
   const Library& library = Library::Handle(zone, cls.library());
 
   *is_bootstrap_native =
       Bootstrap::IsBootstapResolver(library.native_entry_resolver());
 
-  TokenStream::Iterator it(TokenStream::Handle(zone, script.tokens()),
-                           func.token_pos());
-
-  const intptr_t end_pos = func.end_token_pos();
-  while (!IsNativeKeyword(it) && it.CurrentPosition() <= end_pos) {
-    it.Advance();
-  }
-  ASSERT(IsNativeKeyword(it));
-  it.Advance();
-  ASSERT(it.CurrentTokenKind() == Token::kSTRING);
-  const String& native_name = String::Handle(it.CurrentLiteral());
+  const String& native_name = String::Handle(zone, func.native_name());
+  ASSERT(!native_name.IsNull());
 
   const int num_params = NativeArguments::ParameterCountForResolution(func);
   bool auto_setup_scope = true;
@@ -234,7 +218,7 @@
 
     const intptr_t argc_tag = NativeArguments::ComputeArgcTag(func);
     const bool is_leaf_call =
-      (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0;
+        (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0;
 
     call_through_wrapper = !is_bootstrap_native && !is_leaf_call;
 
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index e0247e6..2e4bf4a 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -11,9 +11,7 @@
 #include "vm/bit_vector.h"
 #include "vm/bootstrap.h"
 #include "vm/class_finalizer.h"
-#include "vm/code_generator.h"
 #include "vm/code_observers.h"
-#include "vm/code_patcher.h"
 #include "vm/compiler.h"
 #include "vm/compiler_stats.h"
 #include "vm/dart.h"
@@ -25,12 +23,9 @@
 #include "vm/disassembler.h"
 #include "vm/double_conversion.h"
 #include "vm/exceptions.h"
-#include "vm/flow_graph_builder.h"
-#include "vm/flow_graph_compiler.h"
 #include "vm/growable_array.h"
 #include "vm/hash_table.h"
 #include "vm/heap.h"
-#include "vm/intermediate_language.h"
 #include "vm/intrinsifier.h"
 #include "vm/object_store.h"
 #include "vm/parser.h"
@@ -42,6 +37,7 @@
 #include "vm/stack_frame.h"
 #include "vm/symbols.h"
 #include "vm/tags.h"
+#include "vm/thread_registry.h"
 #include "vm/timer.h"
 #include "vm/unicode.h"
 #include "vm/verified_memory.h"
@@ -83,6 +79,9 @@
 static const char* kSetterPrefix = "set:";
 static const intptr_t kSetterPrefixLength = strlen(kSetterPrefix);
 
+// A cache of VM heap allocated preinitialized empty ic data entry arrays.
+RawArray* ICData::cached_icdata_arrays_[kCachedICDataArrayCount];
+
 cpp_vtable Object::handle_vtable_ = 0;
 cpp_vtable Object::builtin_vtables_[kNumPredefinedCids] = { 0 };
 cpp_vtable Smi::handle_vtable_ = 0;
@@ -116,14 +115,15 @@
 Smi* Object::smi_illegal_cid_ = NULL;
 LanguageError* Object::snapshot_writer_error_ = NULL;
 LanguageError* Object::branch_offset_error_ = NULL;
+LanguageError* Object::speculative_inlining_error_ = NULL;
 Array* Object::vm_isolate_snapshot_object_table_ = NULL;
+Type* Object::dynamic_type_ = NULL;
+Type* Object::void_type_ = NULL;
 
 RawObject* Object::null_ = reinterpret_cast<RawObject*>(RAW_NULL);
 RawClass* Object::class_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
 RawClass* Object::dynamic_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
 RawClass* Object::void_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawType* Object::dynamic_type_ = reinterpret_cast<RawType*>(RAW_NULL);
-RawType* Object::void_type_ = reinterpret_cast<RawType*>(RAW_NULL);
 RawClass* Object::unresolved_class_class_ =
     reinterpret_cast<RawClass*>(RAW_NULL);
 RawClass* Object::type_arguments_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
@@ -489,7 +489,10 @@
   smi_illegal_cid_ = Smi::ReadOnlyHandle();
   snapshot_writer_error_ = LanguageError::ReadOnlyHandle();
   branch_offset_error_ = LanguageError::ReadOnlyHandle();
+  speculative_inlining_error_ = LanguageError::ReadOnlyHandle();
   vm_isolate_snapshot_object_table_ = Array::ReadOnlyHandle();
+  dynamic_type_ = Type::ReadOnlyHandle();
+  void_type_ = Type::ReadOnlyHandle();
 
   *null_object_ = Object::null();
   *null_array_ = Array::null();
@@ -661,6 +664,11 @@
   cls.set_type_arguments_field_offset(Array::type_arguments_offset());
   cls.set_num_type_arguments(1);
   cls.set_num_own_type_arguments(1);
+  cls = Class::New<GrowableObjectArray>();
+  isolate->object_store()->set_growable_object_array_class(cls);
+  cls.set_type_arguments_field_offset(
+      GrowableObjectArray::type_arguments_offset());
+  cls.set_num_type_arguments(1);
   cls = Class::NewStringClass(kOneByteStringCid);
   isolate->object_store()->set_one_byte_string_class(cls);
   cls = Class::NewStringClass(kTwoByteStringCid);
@@ -803,10 +811,10 @@
   cls.set_is_finalized();
 
   cls = dynamic_class_;
-  dynamic_type_ = Type::NewNonParameterizedType(cls);
+  *dynamic_type_ = Type::NewNonParameterizedType(cls);
 
   cls = void_class_;
-  void_type_ = Type::NewNonParameterizedType(cls);
+  *void_type_ = Type::NewNonParameterizedType(cls);
 
   // Allocate and initialize singleton true and false boolean objects.
   cls = Class::New<Bool>();
@@ -825,6 +833,10 @@
   *branch_offset_error_ = LanguageError::New(error_str,
                                              Report::kBailout,
                                              Heap::kOld);
+  error_str = String::New("Speculative inlining failed", Heap::kOld);
+  *speculative_inlining_error_ = LanguageError::New(error_str,
+                                                    Report::kBailout,
+                                                    Heap::kOld);
 
   ASSERT(!null_object_->IsSmi());
   ASSERT(!null_array_->IsSmi());
@@ -864,6 +876,8 @@
   ASSERT(snapshot_writer_error_->IsLanguageError());
   ASSERT(!branch_offset_error_->IsSmi());
   ASSERT(branch_offset_error_->IsLanguageError());
+  ASSERT(!speculative_inlining_error_->IsSmi());
+  ASSERT(speculative_inlining_error_->IsLanguageError());
   ASSERT(!vm_isolate_snapshot_object_table_->IsSmi());
   ASSERT(vm_isolate_snapshot_object_table_->IsArray());
 }
@@ -901,7 +915,7 @@
 
   // Allocate the parameter arrays for method extractor types and names.
   *extractor_parameter_types_ = Array::New(1, Heap::kOld);
-  extractor_parameter_types_->SetAt(0, Type::Handle(Type::DynamicType()));
+  extractor_parameter_types_->SetAt(0, Object::dynamic_type());
   *extractor_parameter_names_ = Array::New(1, Heap::kOld);
   extractor_parameter_names_->SetAt(0, Symbols::This());
 
@@ -955,7 +969,8 @@
 
   {
     ASSERT(isolate == Dart::vm_isolate());
-    WritableVMIsolateScope scope(Thread::Current());
+    bool include_code_pages = !Dart::IsRunningPrecompiledCode();
+    WritableVMIsolateScope scope(Thread::Current(), include_code_pages);
     PremarkingVisitor premarker(isolate);
     ASSERT(isolate->heap()->UsedInWords(Heap::kNew) == 0);
     isolate->heap()->IterateOldObjects(&premarker);
@@ -1560,10 +1575,10 @@
 
 #define ADD_SET_FIELD(clazz)                                                   \
   field_name = Symbols::New("cid"#clazz);                                      \
-  field = Field::New(field_name, true, false, true, false, cls, 0);            \
+  field = Field::New(field_name, true, false, true, false, cls,                \
+      Type::Handle(Type::IntType()), 0);                                       \
   value = Smi::New(k##clazz##Cid);                                             \
   field.SetStaticValue(value, true);                                           \
-  field.set_type(Type::Handle(Type::IntType()));                               \
   cls.AddField(field);                                                         \
 
   CLASS_LIST_WITH_NULL(ADD_SET_FIELD)
@@ -1765,22 +1780,10 @@
                               intptr_t class_id,
                               intptr_t size,
                               bool is_vm_object) {
-  const uword break_instruction_value = Assembler::GetBreakInstructionFiller();
-  const uword null_value = reinterpret_cast<uword>(null_);
-  const bool is_instructions = class_id == kInstructionsCid;
-  uword initial_value =
-      is_instructions ? break_instruction_value : null_value;
+  uword initial_value = (class_id == kInstructionsCid)
+      ? Assembler::GetBreakInstructionFiller() : reinterpret_cast<uword>(null_);
   uword cur = address;
   uword end = address + size;
-  if (is_instructions) {
-    // Fill the header with null. The remainder of the Instructions object will
-    // be filled with the break_instruction_value.
-    uword header_end = address + Instructions::HeaderSize();
-    while (cur < header_end) {
-      *reinterpret_cast<uword*>(cur) = null_value;
-      cur += kWordSize;
-    }
-  }
   while (cur < end) {
     *reinterpret_cast<uword*>(cur) = initial_value;
     cur += kWordSize;
@@ -1827,7 +1830,7 @@
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
   // New space allocation allowed only in mutator thread (Dart thread);
-  ASSERT(isolate->MutatorThreadIsCurrentThread() || (space != Heap::kNew));
+  ASSERT(thread->IsMutatorThread() || (space != Heap::kNew));
   ASSERT(thread->no_callback_scope_depth() == 0);
   Heap* heap = isolate->heap();
 
@@ -1848,7 +1851,7 @@
   }
   const Class& cls = Class::Handle(class_table->At(cls_id));
   if (cls.TraceAllocation(isolate)) {
-    Profiler::RecordAllocation(thread, cls_id);
+    Profiler::SampleAllocation(thread, cls_id);
   }
   NoSafepointScope no_safepoint;
   InitializeObject(address, cls_id, size, (isolate == Dart::vm_isolate()));
@@ -2168,8 +2171,8 @@
   ASSERT(!value.IsNull());
   StorePointer(&raw_ptr()->functions_, value.raw());
   const intptr_t len = value.Length();
-  ClassFunctionsSet set(HashTables::New<ClassFunctionsSet>(len, Heap::kOld));
   if (len >= kFunctionLookupHashTreshold) {
+    ClassFunctionsSet set(HashTables::New<ClassFunctionsSet>(len, Heap::kOld));
     Function& func = Function::Handle();
     for (intptr_t i = 0; i < len; ++i) {
       func ^= value.At(i);
@@ -2177,8 +2180,8 @@
       ASSERT(func.Owner() == raw());
       set.Insert(func);
     }
+    StorePointer(&raw_ptr()->functions_hash_table_, set.Release().raw());
   }
-  StorePointer(&raw_ptr()->functions_hash_table_, set.Release().raw());
 }
 
 
@@ -2204,6 +2207,7 @@
 void Class::RemoveFunction(const Function& function) const {
   const Array& arr = Array::Handle(functions());
   StorePointer(&raw_ptr()->functions_, Object::empty_array().raw());
+  StorePointer(&raw_ptr()->functions_hash_table_, Array::null());
   Function& entry = Function::Handle();
   for (intptr_t i = 0; i < arr.Length(); i++) {
     entry ^= arr.At(i);
@@ -2325,7 +2329,6 @@
 }
 
 
-
 RawFunction* Class::InvocationDispatcherFunctionFromIndex(intptr_t idx) const {
   Thread* thread = Thread::Current();
   REUSABLE_ARRAY_HANDLESCOPE(thread);
@@ -2341,86 +2344,6 @@
 }
 
 
-void Class::set_closures(const GrowableObjectArray& value) const {
-  StorePointer(&raw_ptr()->closure_functions_, value.raw());
-}
-
-
-void Class::AddClosureFunction(const Function& function) const {
-  GrowableObjectArray& closures =
-      GrowableObjectArray::Handle(raw_ptr()->closure_functions_);
-  if (closures.IsNull()) {
-    closures = GrowableObjectArray::New(4, Heap::kOld);
-    StorePointer(&raw_ptr()->closure_functions_, closures.raw());
-  }
-  ASSERT(function.IsNonImplicitClosureFunction());
-  ASSERT(function.Owner() == this->raw());
-  closures.Add(function, Heap::kOld);
-}
-
-
-// Lookup the innermost closure function that contains token at token_pos.
-RawFunction* Class::LookupClosureFunction(intptr_t token_pos) const {
-  if (raw_ptr()->closure_functions_ == GrowableObjectArray::null()) {
-    return Function::null();
-  }
-  const GrowableObjectArray& closures =
-      GrowableObjectArray::Handle(raw_ptr()->closure_functions_);
-  Function& closure = Function::Handle();
-  intptr_t num_closures = closures.Length();
-  intptr_t best_fit_token_pos = -1;
-  intptr_t best_fit_index = -1;
-  for (intptr_t i = 0; i < num_closures; i++) {
-    closure ^= closures.At(i);
-    ASSERT(!closure.IsNull());
-    if ((closure.token_pos() <= token_pos) &&
-        (token_pos <= closure.end_token_pos()) &&
-        (best_fit_token_pos < closure.token_pos())) {
-      best_fit_index = i;
-      best_fit_token_pos = closure.token_pos();
-    }
-  }
-  closure = Function::null();
-  if (best_fit_index >= 0) {
-    closure ^= closures.At(best_fit_index);
-  }
-  return closure.raw();
-}
-
-intptr_t Class::FindClosureIndex(const Function& needle) const {
-  if (closures() == GrowableObjectArray::null()) {
-    return -1;
-  }
-  Thread* thread = Thread::Current();
-  const GrowableObjectArray& closures_array =
-      GrowableObjectArray::Handle(thread->zone(), closures());
-  REUSABLE_FUNCTION_HANDLESCOPE(thread);
-  Function& closure = thread->FunctionHandle();
-  intptr_t num_closures = closures_array.Length();
-  for (intptr_t i = 0; i < num_closures; i++) {
-    closure ^= closures_array.At(i);
-    ASSERT(!closure.IsNull());
-    if (closure.raw() == needle.raw()) {
-      return i;
-    }
-  }
-  return -1;
-}
-
-
-RawFunction* Class::ClosureFunctionFromIndex(intptr_t idx) const {
-  const GrowableObjectArray& closures_array =
-      GrowableObjectArray::Handle(closures());
-  if ((idx < 0) || (idx >= closures_array.Length())) {
-    return Function::null();
-  }
-  Function& func = Function::Handle();
-  func ^= closures_array.At(idx);
-  ASSERT(!func.IsNull());
-  return func.raw();
-}
-
-
 void Class::set_signature_function(const Function& value) const {
   ASSERT(value.IsClosureFunction() || value.IsSignatureFunction());
   StorePointer(&raw_ptr()->signature_function_, value.raw());
@@ -2742,12 +2665,12 @@
   invocation.set_parameter_names(Array::Handle(Array::New(desc.Count(),
                                                           Heap::kOld)));
   // Receiver.
-  invocation.SetParameterTypeAt(0, Type::Handle(Type::DynamicType()));
+  invocation.SetParameterTypeAt(0, Object::dynamic_type());
   invocation.SetParameterNameAt(0, Symbols::This());
   // Remaining positional parameters.
   intptr_t i = 1;
   for (; i < desc.PositionalCount(); i++) {
-    invocation.SetParameterTypeAt(i, Type::Handle(Type::DynamicType()));
+    invocation.SetParameterTypeAt(i, Object::dynamic_type());
     char name[64];
     OS::SNPrint(name, 64, ":p%" Pd, i);
     invocation.SetParameterNameAt(i, String::Handle(Symbols::New(name)));
@@ -2755,11 +2678,11 @@
 
   // Named parameters.
   for (; i < desc.Count(); i++) {
-    invocation.SetParameterTypeAt(i, Type::Handle(Type::DynamicType()));
+    invocation.SetParameterTypeAt(i, Object::dynamic_type());
     intptr_t index = i - desc.PositionalCount();
     invocation.SetParameterNameAt(i, String::Handle(desc.NameAt(index)));
   }
-  invocation.set_result_type(Type::Handle(Type::DynamicType()));
+  invocation.set_result_type(Object::dynamic_type());
   invocation.set_is_debuggable(false);
   invocation.set_is_visible(false);
   invocation.set_is_reflectable(false);
@@ -2769,6 +2692,60 @@
 }
 
 
+// Method extractors are used to create implicit closures from methods.
+// When an expression obj.M is evaluated for the first time and receiver obj
+// does not have a getter called M but has a method called M then an extractor
+// is created and injected as a getter (under the name get:M) into the class
+// owning method M.
+RawFunction* Function::CreateMethodExtractor(const String& getter_name) const {
+  ASSERT(Field::IsGetterName(getter_name));
+  const Function& closure_function =
+      Function::Handle(ImplicitClosureFunction());
+
+  const Class& owner = Class::Handle(closure_function.Owner());
+  Function& extractor = Function::Handle(
+    Function::New(String::Handle(Symbols::New(getter_name)),
+                  RawFunction::kMethodExtractor,
+                  false,  // Not static.
+                  false,  // Not const.
+                  false,  // Not abstract.
+                  false,  // Not external.
+                  false,  // Not native.
+                  owner,
+                  0));  // No token position.
+
+  // Initialize signature: receiver is a single fixed parameter.
+  const intptr_t kNumParameters = 1;
+  extractor.set_num_fixed_parameters(kNumParameters);
+  extractor.SetNumOptionalParameters(0, 0);
+  extractor.set_parameter_types(Object::extractor_parameter_types());
+  extractor.set_parameter_names(Object::extractor_parameter_names());
+  extractor.set_result_type(Object::dynamic_type());
+
+  extractor.set_extracted_method_closure(closure_function);
+  extractor.set_is_debuggable(false);
+  extractor.set_is_visible(false);
+
+  owner.AddFunction(extractor);
+
+  return extractor.raw();
+}
+
+
+RawFunction* Function::GetMethodExtractor(const String& getter_name) const {
+  ASSERT(Field::IsGetterName(getter_name));
+  const Function& closure_function =
+      Function::Handle(ImplicitClosureFunction());
+  const Class& owner = Class::Handle(closure_function.Owner());
+  Function& result = Function::Handle(owner.LookupDynamicFunction(getter_name));
+  if (result.IsNull()) {
+    result ^= CreateMethodExtractor(getter_name);
+  }
+  ASSERT(result.kind() == RawFunction::kMethodExtractor);
+  return result.raw();
+}
+
+
 RawArray* Class::invocation_dispatcher_cache() const {
   return raw_ptr()->invocation_dispatcher_cache_;
 }
@@ -2780,6 +2757,10 @@
 
 
 void Class::Finalize() const {
+  ASSERT(Thread::Current()->IsMutatorThread());
+  // Even if all regular classes are prefinalized (precompilation), signature
+  // classes may be added later when we encounter local functions.
+  ASSERT(IsSignatureClass() || !Isolate::Current()->all_classes_finalized());
   ASSERT(!is_finalized());
   // Prefinalized classes have a VM internal representation and no Dart fields.
   // Their instance size  is precomputed and field offsets are known.
@@ -2821,17 +2802,30 @@
     }
   }
 
+  virtual void IncrementInvalidationGen() {
+    Isolate::Current()->IncrCHAInvalidationGen();
+  }
+
  private:
   const Class& cls_;
   DISALLOW_COPY_AND_ASSIGN(CHACodeArray);
 };
 
 
+#if defined(DEBUG)
+static bool IsMutatorOrAtSafepoint() {
+  Thread* thread = Thread::Current();
+  return thread->IsMutatorThread() ||
+         thread->isolate()->thread_registry()->AtSafepoint();
+}
+#endif
+
 void Class::RegisterCHACode(const Code& code) {
   if (FLAG_trace_cha) {
     THR_Print("RegisterCHACode %s class %s\n",
         Function::Handle(code.function()).ToQualifiedCString(), ToCString());
   }
+  DEBUG_ASSERT(IsMutatorOrAtSafepoint());
   ASSERT(code.is_optimized());
   CHACodeArray a(*this);
   a.Register(code);
@@ -2839,6 +2833,7 @@
 
 
 void Class::DisableCHAOptimizedCode() {
+  ASSERT(Thread::Current()->IsMutatorThread());
   CHACodeArray a(*this);
   a.DisableCode();
 }
@@ -3019,11 +3014,11 @@
   const Library& lib = Library::Handle(cls.library());
   ASSERT(!lib.IsNull());
   const String& lib_key = String::Handle(lib.private_key());
-  script.Tokenize(lib_key);
+  script.Tokenize(lib_key, false);
 
   const Function& func = Function::Handle(
        Function::NewEvalFunction(cls, script, is_static));
-  func.set_result_type(Type::Handle(Type::DynamicType()));
+  func.set_result_type(Object::dynamic_type());
   const intptr_t num_implicit_params = is_static ? 0 : 1;
   func.set_num_fixed_parameters(num_implicit_params + param_names.Length());
   func.SetNumOptionalParameters(0, true);
@@ -3044,12 +3039,12 @@
 
 
 // Ensure that top level parsing of the class has been done.
-// TODO(24109): Migrate interface to Thread*.
 RawError* Class::EnsureIsFinalized(Thread* thread) const {
   // Finalized classes have already been parsed.
   if (is_finalized()) {
     return Error::null();
   }
+  ASSERT(thread->IsMutatorThread());
   ASSERT(thread != NULL);
   const Error& error = Error::Handle(
       thread->zone(), Compiler::CompileClass(*this));
@@ -3593,8 +3588,8 @@
 }
 
 
-void Class::set_is_allocated() const {
-  set_state_bits(IsAllocatedBit::update(true, raw_ptr()->state_bits_));
+void Class::set_is_allocated(bool value) const {
+  set_state_bits(IsAllocatedBit::update(value, raw_ptr()->state_bits_));
 }
 
 
@@ -3639,9 +3634,25 @@
 }
 
 
-void Class::set_patch_class(const Class& cls) const {
-  ASSERT(patch_class() == Class::null());
-  StorePointer(&raw_ptr()->patch_class_, cls.raw());
+void Class::SetPatchClass(const Class& cls) const {
+  ASSERT(GetPatchClass() == Class::null());
+  const GrowableObjectArray& patch_classes =
+      GrowableObjectArray::Handle(Library::Handle(library()).patch_classes());
+  patch_classes.Add(cls);
+}
+
+
+RawClass* Class::GetPatchClass() const {
+  const GrowableObjectArray& patch_classes =
+      GrowableObjectArray::Handle(Library::Handle(library()).patch_classes());
+  Class& pc = Class::Handle();
+  for (intptr_t i = 0; i < patch_classes.Length(); i++) {
+    pc ^= patch_classes.At(i);
+    if (pc.Name() == this->Name()) {  // Names are canonicalized.
+      return pc.raw();
+    }
+  }
+  return Class::null();
 }
 
 
@@ -4223,33 +4234,6 @@
 }
 
 
-RawFunction* Class::LookupFunctionAtToken(intptr_t token_pos) const {
-  // TODO(hausner): we can shortcut the negative case if we knew the
-  // beginning and end token position of the class.
-  Thread* thread = Thread::Current();
-  Zone* zone = thread->zone();
-  if (EnsureIsFinalized(thread) != Error::null()) {
-    return Function::null();
-  }
-  Function& func = Function::Handle(zone);
-  func = LookupClosureFunction(token_pos);
-  if (!func.IsNull()) {
-    return func.raw();
-  }
-  Array& funcs = Array::Handle(zone, functions());
-  intptr_t len = funcs.Length();
-  for (intptr_t i = 0; i < len; i++) {
-    func ^= funcs.At(i);
-    if ((func.token_pos() <= token_pos) &&
-        (token_pos <= func.end_token_pos())) {
-      return func.raw();
-    }
-  }
-  // No function found.
-  return Function::null();
-}
-
-
 RawField* Class::LookupInstanceField(const String& name) const {
   return LookupField(name, kInstance);
 }
@@ -5302,20 +5286,40 @@
 
 
 bool Function::HasBreakpoint() const {
-  return Isolate::Current()->debugger()->HasBreakpoint(*this);
+  Thread* thread = Thread::Current();
+  return thread->isolate()->debugger()->HasBreakpoint(*this, thread->zone());
+}
+
+
+void Function::InstallOptimizedCode(const Code& code, bool is_osr) const {
+  DEBUG_ASSERT(IsMutatorOrAtSafepoint());
+  // We may not have previous code if 'always_optimize' is set.
+  if (!is_osr && HasCode()) {
+    Code::Handle(CurrentCode()).DisableDartCode();
+  }
+  AttachCode(code);
 }
 
 
 void Function::SetInstructions(const Code& value) const {
+  DEBUG_ASSERT(IsMutatorOrAtSafepoint());
+  SetInstructionsSafe(value);
+}
+
+
+void Function::SetInstructionsSafe(const Code& value) const {
   StorePointer(&raw_ptr()->code_, value.raw());
   StoreNonPointer(&raw_ptr()->entry_point_, value.EntryPoint());
 }
 
+
 void Function::AttachCode(const Code& value) const {
+  DEBUG_ASSERT(IsMutatorOrAtSafepoint());
+  // Finish setting up code before activating it.
+  value.set_owner(*this);
   SetInstructions(value);
   ASSERT(Function::Handle(value.function()).IsNull() ||
-    (value.function() == this->raw()));
-  value.set_owner(*this);
+      (value.function() == this->raw()));
 }
 
 
@@ -5326,6 +5330,7 @@
 
 
 void Function::ClearCode() const {
+  ASSERT(Thread::Current()->IsMutatorThread());
   ASSERT((usage_counter() != 0) || (ic_data_array() == Array::null()));
   StorePointer(&raw_ptr()->unoptimized_code_, Code::null());
   SetInstructions(Code::Handle(StubCode::LazyCompile_entry()->code()));
@@ -5337,6 +5342,7 @@
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
   Zone* zone = thread->zone();
+  ASSERT(thread->IsMutatorThread());
   const Code& current_code = Code::Handle(zone, CurrentCode());
 
   if (FLAG_trace_deoptimization_verbose) {
@@ -5358,6 +5364,7 @@
 
 
 void Function::set_unoptimized_code(const Code& value) const {
+  ASSERT(Thread::Current()->IsMutatorThread());
   ASSERT(value.IsNull() || !value.is_optimized());
   StorePointer(&raw_ptr()->unoptimized_code_, value.raw());
 }
@@ -5453,6 +5460,27 @@
 }
 
 
+RawField* Function::LookupImplicitGetterSetterField() const {
+  ASSERT((kind() == RawFunction::kImplicitGetter) ||
+         (kind() == RawFunction::kImplicitSetter) ||
+         (kind() == RawFunction::kImplicitStaticFinalGetter));
+  const Class& owner = Class::Handle(Owner());
+  ASSERT(!owner.IsNull());
+  const Array& fields = Array::Handle(owner.fields());
+  ASSERT(!fields.IsNull());
+  Field& field = Field::Handle();
+  for (intptr_t i = 0; i < fields.Length(); i++) {
+    field ^= fields.At(i);
+    ASSERT(!field.IsNull());
+    if (field.token_pos() == token_pos()) {
+      return field.raw();
+    }
+  }
+  return Field::null();
+}
+
+
+
 RawFunction* Function::parent_function() const {
   if (IsClosureFunction()) {
     const Object& obj = Object::Handle(raw_ptr()->data_);
@@ -5481,16 +5509,31 @@
     return Function::null();
   }
   const Object& obj = Object::Handle(raw_ptr()->data_);
-  ASSERT(obj.IsNull() || obj.IsScript() || obj.IsFunction());
-  return (obj.IsNull() || obj.IsScript()) ? Function::null()
-                                          : Function::Cast(obj).raw();
+  ASSERT(obj.IsNull() || obj.IsScript() || obj.IsFunction() || obj.IsArray());
+  if (obj.IsNull() || obj.IsScript()) {
+    return Function::null();
+  }
+  if (obj.IsFunction()) {
+    return Function::Cast(obj).raw();
+  }
+  ASSERT(is_native());
+  ASSERT(obj.IsArray());
+  const Object& res = Object::Handle(Array::Cast(obj).At(1));
+  return res.IsNull() ? Function::null() : Function::Cast(res).raw();
 }
 
 
 void Function::set_implicit_closure_function(const Function& value) const {
   ASSERT(!IsClosureFunction() && !IsSignatureFunction());
-  ASSERT(raw_ptr()->data_ == Object::null());
-  set_data(value);
+  if (is_native()) {
+    const Object& obj = Object::Handle(raw_ptr()->data_);
+    ASSERT(obj.IsArray());
+    ASSERT((Array::Cast(obj).At(1) == Object::null()) || value.IsNull());
+    Array::Cast(obj).SetAt(1, value);
+  } else {
+    ASSERT((raw_ptr()->data_ == Object::null()) || value.IsNull());
+    set_data(value);
+  }
 }
 
 
@@ -5525,7 +5568,7 @@
 
 
 bool Function::IsRedirectingFactory() const {
-  if (!IsFactory() || (raw_ptr()->data_ == Object::null())) {
+  if (!IsFactory() || !is_redirecting()) {
     return false;
   }
   ASSERT(!IsClosureFunction());  // A factory cannot also be a closure.
@@ -5535,6 +5578,7 @@
 
 RawType* Function::RedirectionType() const {
   ASSERT(IsRedirectingFactory());
+  ASSERT(!is_native());
   const Object& obj = Object::Handle(raw_ptr()->data_);
   ASSERT(!obj.IsNull());
   return RedirectionData::Cast(obj).type();
@@ -5638,6 +5682,19 @@
 }
 
 
+// This field is heavily overloaded:
+//   eval function:           Script expression source
+//   signature function:      Class signature class
+//   method extractor:        Function extracted closure function
+//   noSuchMethod dispatcher: Array arguments descriptor
+//   invoke-field dispatcher: Array arguments descriptor
+//   redirecting constructor: RedirectionData
+//   closure function:        ClosureData
+//   irregexp function:       Array[0] = JSRegExp
+//                            Array[1] = Smi string specialization cid
+//   native function:         Array[0] = String native name
+//                            Array[1] = Function implicit closure function
+//   regular function:        Function for implicit closure function
 void Function::set_data(const Object& value) const {
   StorePointer(&raw_ptr()->data_, value.raw());
 }
@@ -5693,6 +5750,24 @@
 }
 
 
+RawString* Function::native_name() const {
+  ASSERT(is_native());
+  const Object& obj = Object::Handle(raw_ptr()->data_);
+  ASSERT(obj.IsArray());
+  return String::RawCast(Array::Cast(obj).At(0));
+}
+
+
+void Function::set_native_name(const String& value) const {
+  ASSERT(is_native());
+  ASSERT(raw_ptr()->data_ == Object::null());
+  const Array& pair = Array::Handle(Array::New(2, Heap::kOld));
+  pair.SetAt(0, value);
+  // pair[1] will be the implicit closure function if needed.
+  set_data(pair);
+}
+
+
 void Function::set_result_type(const AbstractType& value) const {
   ASSERT(!value.IsNull());
   StorePointer(&raw_ptr()->result_type_, value.raw());
@@ -5832,10 +5907,10 @@
 
 
 bool Function::CanBeInlined() const {
+  Thread* thread = Thread::Current();
   return is_inlinable() &&
          !is_generated_body() &&
-         HasCode() &&
-         !Isolate::Current()->debugger()->HasBreakpoint(*this);
+         !thread->isolate()->debugger()->HasBreakpoint(*this, thread->zone());
 }
 
 
@@ -6416,7 +6491,8 @@
   result.set_is_inlinable(true);
   result.set_allows_hoisting_check_class(true);
   result.set_allows_bounds_check_generalization(true);
-  result.SetInstructions(Code::Handle(StubCode::LazyCompile_entry()->code()));
+  result.SetInstructionsSafe(
+      Code::Handle(StubCode::LazyCompile_entry()->code()));
   if (kind == RawFunction::kClosureFunction) {
     const ClosureData& data = ClosureData::Handle(ClosureData::New());
     result.set_data(data);
@@ -6593,6 +6669,16 @@
 }
 
 
+void Function::DropUncompiledImplicitClosureFunction() const {
+  if (implicit_closure_function() != Function::null()) {
+    const Function& func = Function::Handle(implicit_closure_function());
+    if (!func.HasCode()) {
+      set_implicit_closure_function(Function::Handle());
+    }
+  }
+}
+
+
 RawString* Function::UserVisibleFormalParameters() const {
   // Typically 3, 5,.. elements in 'pieces', e.g.:
   // '_LoadRequest', CommaSpace, '_LoadError'.
@@ -6985,7 +7071,8 @@
 
 
 void Function::RestoreICDataMap(
-    ZoneGrowableArray<const ICData*>* deopt_id_to_ic_data) const {
+    ZoneGrowableArray<const ICData*>* deopt_id_to_ic_data,
+    bool clone_descriptors) const {
   ASSERT(deopt_id_to_ic_data->is_empty());
   Zone* zone = Thread::Current()->zone();
   const Array& saved_ic_data = Array::Handle(zone, ic_data_array());
@@ -7004,6 +7091,9 @@
     for (intptr_t i = 1; i < saved_length; i++) {
       ICData& ic_data = ICData::ZoneHandle(zone);
       ic_data ^= saved_ic_data.At(i);
+      if (clone_descriptors) {
+        ic_data = ICData::CloneDescriptor(ic_data);
+      }
       (*deopt_id_to_ic_data)[ic_data.deopt_id()] = &ic_data;
     }
   }
@@ -7117,7 +7207,7 @@
   intptr_t id = -1;
   const char* selector = NULL;
   if (f.IsNonImplicitClosureFunction()) {
-    id = cls.FindClosureIndex(f);
+    id = Isolate::Current()->FindClosureIndex(f);
     selector = "closures";
   } else if (f.IsImplicitClosureFunction()) {
     id = cls.FindImplicitClosureFunctionIndex(f);
@@ -7173,6 +7263,8 @@
   jsobj.AddProperty("_kind", kind_string);
   jsobj.AddProperty("static", is_static());
   jsobj.AddProperty("const", is_const());
+  jsobj.AddProperty("_intrinsic", is_intrinsic());
+  jsobj.AddProperty("_native", is_native());
   if (ref) {
     return;
   }
@@ -7186,6 +7278,7 @@
   }
   jsobj.AddProperty("_optimizable", is_optimizable());
   jsobj.AddProperty("_inlinable", is_inlinable());
+  jsobj.AddProperty("_recognized", IsRecognized());
   code = unoptimized_code();
   if (!code.IsNull()) {
     jsobj.AddProperty("_unoptimizedCode", code);
@@ -7194,6 +7287,14 @@
   jsobj.AddProperty("_optimizedCallSiteCount", optimized_call_site_count());
   jsobj.AddProperty("_deoptimizations",
                     static_cast<intptr_t>(deoptimization_counter()));
+  if ((kind() == RawFunction::kImplicitGetter) ||
+      (kind() == RawFunction::kImplicitSetter) ||
+      (kind() == RawFunction::kImplicitStaticFinalGetter)) {
+    const Field& field = Field::Handle(LookupImplicitGetterSetterField());
+    if (!field.IsNull()) {
+      jsobj.AddProperty("_field", field);
+    }
+  }
 
   const Script& script = Script::Handle(this->script());
   if (!script.IsNull()) {
@@ -7356,9 +7457,13 @@
 }
 
 
-void Field::set_type(const AbstractType& value) const {
+// Called at finalization time
+void Field::SetFieldType(const AbstractType& value) const {
+  ASSERT(Thread::Current()->IsMutatorThread());
   ASSERT(!value.IsNull());
-  StorePointer(&raw_ptr()->type_, value.raw());
+  if (value.raw() != type()) {
+    StorePointer(&raw_ptr()->type_, value.raw());
+  }
 }
 
 
@@ -7377,6 +7482,7 @@
                      bool is_const,
                      bool is_reflectable,
                      const Class& owner,
+                     const AbstractType& type,
                      intptr_t token_pos) {
   ASSERT(!owner.IsNull());
   const Field& result = Field::Handle(Field::New());
@@ -7390,6 +7496,7 @@
   result.set_is_reflectable(is_reflectable);
   result.set_is_double_initialized(false);
   result.set_owner(owner);
+  result.SetFieldType(type);
   result.set_token_pos(token_pos);
   result.set_has_initializer(false);
   result.set_is_unboxing_candidate(true);
@@ -7421,7 +7528,7 @@
     // Adjust the field type to refer to type parameters of the new owner.
     AbstractType& type = AbstractType::Handle(clone.type());
     type ^= type.CloneUninstantiated(new_owner);
-    clone.set_type(type);
+    clone.SetFieldType(type);
   }
   return clone.raw();
 }
@@ -7444,6 +7551,7 @@
 
 
 void Field::set_guarded_list_length(intptr_t list_length) const {
+  ASSERT(Thread::Current()->IsMutatorThread());
   StoreSmi(&raw_ptr()->guarded_list_length_, Smi::New(list_length));
 }
 
@@ -7455,30 +7563,13 @@
 
 void Field::set_guarded_list_length_in_object_offset(
     intptr_t list_length_offset) const {
+  ASSERT(Thread::Current()->IsMutatorThread());
   StoreNonPointer(&raw_ptr()->guarded_list_length_in_object_offset_,
                   static_cast<int8_t>(list_length_offset - kHeapObjectTag));
   ASSERT(guarded_list_length_in_object_offset() == list_length_offset);
 }
 
 
-bool Field::IsUnboxedField() const {
-  bool valid_class = (FlowGraphCompiler::SupportsUnboxedDoubles() &&
-                      (guarded_cid() == kDoubleCid)) ||
-                     (FlowGraphCompiler::SupportsUnboxedSimd128() &&
-                      (guarded_cid() == kFloat32x4Cid)) ||
-                     (FlowGraphCompiler::SupportsUnboxedSimd128() &&
-                      (guarded_cid() == kFloat64x2Cid));
-  return is_unboxing_candidate() && !is_final() && !is_nullable() &&
-         valid_class;
-}
-
-
-bool Field::IsPotentialUnboxedField() const {
-  return is_unboxing_candidate() &&
-         (IsUnboxedField() || (!is_final() && (guarded_cid() == kIllegalCid)));
-}
-
-
 const char* Field::ToCString() const {
   if (IsNull()) {
     return "Field::null";
@@ -7600,9 +7691,9 @@
                              true,  // is_const
                              false,  // is_reflectable
                              field_owner,
+                             Object::dynamic_type(),
                              this->token_pos());
   closure_field.SetStaticValue(Instance::Cast(result), true);
-  closure_field.set_type(Type::Handle(Type::DynamicType()));
   field_owner.AddField(closure_field);
 
   return Instance::RawCast(result.raw());
@@ -7657,6 +7748,10 @@
     }
   }
 
+  virtual void IncrementInvalidationGen() {
+    Isolate::Current()->IncrFieldInvalidationGen();
+  }
+
  private:
   const Field& field_;
   DISALLOW_COPY_AND_ASSIGN(FieldDependentArray);
@@ -7664,6 +7759,7 @@
 
 
 void Field::RegisterDependentCode(const Code& code) const {
+  DEBUG_ASSERT(IsMutatorOrAtSafepoint());
   ASSERT(code.is_optimized());
   FieldDependentArray a(*this);
   a.Register(code);
@@ -7671,6 +7767,7 @@
 
 
 void Field::DeoptimizeDependentCode() const {
+  ASSERT(Thread::Current()->IsMutatorThread());
   FieldDependentArray a(*this);
   a.DisableCode();
 }
@@ -7950,12 +8047,12 @@
 }
 
 
-RawArray* TokenStream::TokenObjects() const {
+RawGrowableObjectArray* TokenStream::TokenObjects() const {
   return raw_ptr()->token_objects_;
 }
 
 
-void TokenStream::SetTokenObjects(const Array& value) const {
+void TokenStream::SetTokenObjects(const GrowableObjectArray& value) const {
   StorePointer(&raw_ptr()->token_objects_, value.raw());
 }
 
@@ -8237,10 +8334,6 @@
       return String::Cast(key).Hash();
     }
   }
-
-  static RawObject* NewKey(const Scanner::TokenDescriptor& descriptor) {
-    return LiteralToken::New(descriptor.kind, *descriptor.literal);
-  }
 };
 typedef UnorderedHashMap<CompressedTokenTraits> CompressedTokenMap;
 
@@ -8249,33 +8342,60 @@
 class CompressedTokenStreamData : public ValueObject {
  public:
   static const intptr_t kInitialBufferSize = 16 * KB;
-  CompressedTokenStreamData() :
+  static const bool kPrintTokenObjects = false;
+
+  CompressedTokenStreamData(const GrowableObjectArray& ta,
+                            CompressedTokenMap* map) :
       buffer_(NULL),
       stream_(&buffer_, Reallocate, kInitialBufferSize),
-      tokens_(HashTables::New<CompressedTokenMap>(kInitialTableSize)) {
-  }
-  ~CompressedTokenStreamData() {
-    // Safe to discard the hash table now.
-    tokens_.Release();
+      token_objects_(ta),
+      tokens_(map),
+      value_(Object::Handle()),
+      fresh_index_smi_(Smi::Handle()) {
   }
 
   // Add an IDENT token into the stream and the token hash map.
-  void AddIdentToken(const String* ident) {
-    ASSERT(ident->IsSymbol());
-    const intptr_t fresh_index = tokens_.NumOccupied();
+  void AddIdentToken(const String& ident) {
+    ASSERT(ident.IsSymbol());
+    const intptr_t fresh_index = token_objects_.Length();
+    fresh_index_smi_ = Smi::New(fresh_index);
     intptr_t index = Smi::Value(Smi::RawCast(
-        tokens_.InsertOrGetValue(*ident,
-                                 Smi::Handle(Smi::New(fresh_index)))));
+        tokens_->InsertOrGetValue(ident, fresh_index_smi_)));
+    if (index == fresh_index) {
+      token_objects_.Add(ident);
+      if (kPrintTokenObjects) {
+        int iid = Isolate::Current()->main_port() % 1024;
+        OS::Print("ident  %03x  %p <%s>\n",
+                  iid, ident.raw(), ident.ToCString());
+      }
+    }
     WriteIndex(index);
   }
 
   // Add a LITERAL token into the stream and the token hash map.
   void AddLiteralToken(const Scanner::TokenDescriptor& descriptor) {
     ASSERT(descriptor.literal->IsSymbol());
-    const intptr_t fresh_index = tokens_.NumOccupied();
-    intptr_t index = Smi::Value(Smi::RawCast(
-        tokens_.InsertNewOrGetValue(descriptor,
-                                    Smi::Handle(Smi::New(fresh_index)))));
+    bool is_present = false;
+    value_ = tokens_->GetOrNull(descriptor, &is_present);
+    intptr_t index = -1;
+    if (is_present) {
+      ASSERT(value_.IsSmi());
+      index = Smi::Cast(value_).Value();
+    } else {
+      const intptr_t fresh_index = token_objects_.Length();
+      fresh_index_smi_ = Smi::New(fresh_index);
+      const LiteralToken& lit = LiteralToken::Handle(
+          LiteralToken::New(descriptor.kind, *descriptor.literal));
+      index = Smi::Value(Smi::RawCast(
+          tokens_->InsertOrGetValue(lit, fresh_index_smi_)));
+      token_objects_.Add(lit);
+      if (kPrintTokenObjects) {
+        int iid = Isolate::Current()->main_port() % 1024;
+        printf("lit    %03x  %p  %p  %p  <%s>\n",
+               iid, token_objects_.raw(), lit.literal(), lit.value(),
+               String::Handle(lit.literal()).ToCString());
+      }
+    }
     WriteIndex(index);
   }
 
@@ -8290,20 +8410,6 @@
   // Return the compressed token stream length.
   intptr_t Length() const { return stream_.bytes_written(); }
 
-  // Generate and return the token objects array.
-  RawArray* MakeTokenObjectsArray() const {
-    Array& result = Array::Handle(
-        Array::New(tokens_.NumOccupied(), Heap::kOld));
-    CompressedTokenMap::Iterator it(&tokens_);
-    Object& key = Object::Handle();
-    while (it.MoveNext()) {
-      intptr_t entry = it.Current();
-      key = tokens_.GetKey(entry);
-      result.SetAt(Smi::Value(Smi::RawCast(tokens_.GetPayload(entry, 0))), key);
-    }
-    return result.raw();
-  }
-
  private:
   void WriteIndex(intptr_t value) {
     stream_.WriteUnsigned(value + Token::kNumTokens);
@@ -8316,27 +8422,53 @@
     return reinterpret_cast<uint8_t*>(new_ptr);
   }
 
-  static const intptr_t kInitialTableSize = 32;
-
   uint8_t* buffer_;
   WriteStream stream_;
-  CompressedTokenMap tokens_;
+  const GrowableObjectArray& token_objects_;
+  CompressedTokenMap* tokens_;
+  Object& value_;
+  Smi& fresh_index_smi_;
 
   DISALLOW_COPY_AND_ASSIGN(CompressedTokenStreamData);
 };
 
 
 RawTokenStream* TokenStream::New(const Scanner::GrowableTokenStream& tokens,
-                                 const String& private_key) {
-  Zone* zone = Thread::Current()->zone();
+                                 const String& private_key,
+                                 bool use_shared_tokens) {
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
   // Copy the relevant data out of the scanner into a compressed stream of
   // tokens.
-  CompressedTokenStreamData data;
+
+  GrowableObjectArray& token_objects = GrowableObjectArray::Handle(zone);
+  Array& token_objects_map = Array::Handle(zone);
+  if (use_shared_tokens) {
+    // Use the shared token objects array in the object store. Allocate
+    // a new array if necessary.
+    ObjectStore* store = thread->isolate()->object_store();
+    if (store->token_objects() == GrowableObjectArray::null()) {
+      OpenSharedTokenList(thread->isolate());
+    }
+    token_objects = store->token_objects();
+    token_objects_map = store->token_objects_map();
+  } else {
+    // Use new, non-shared token array.
+    const int kInitialPrivateCapacity = 256;
+    token_objects =
+        GrowableObjectArray::New(kInitialPrivateCapacity, Heap::kOld);
+    token_objects_map =
+        HashTables::New<CompressedTokenMap>(kInitialPrivateCapacity,
+                                            Heap::kOld);
+  }
+  CompressedTokenMap map(token_objects_map.raw());
+  CompressedTokenStreamData data(token_objects, &map);
+
   intptr_t len = tokens.length();
   for (intptr_t i = 0; i < len; i++) {
     Scanner::TokenDescriptor token = tokens[i];
     if (token.kind == Token::kIDENT) {  // Identifier token.
-      data.AddIdentToken(token.literal);
+      data.AddIdentToken(*token.literal);
     } else if (Token::NeedsLiteralToken(token.kind)) {  // Literal token.
       data.AddLiteralToken(token);
     } else {  // Keyword, pseudo keyword etc.
@@ -8354,17 +8486,40 @@
   stream.AddFinalizer(data.GetStream(), DataFinalizer);
   const TokenStream& result = TokenStream::Handle(zone, New());
   result.SetPrivateKey(private_key);
-  const Array& token_objects =
-      Array::Handle(zone, data.MakeTokenObjectsArray());
   {
     NoSafepointScope no_safepoint;
     result.SetStream(stream);
     result.SetTokenObjects(token_objects);
   }
+
+  token_objects_map = map.Release().raw();
+  if (use_shared_tokens) {
+    thread->isolate()->object_store()->set_token_objects_map(token_objects_map);
+  }
   return result.raw();
 }
 
 
+void TokenStream::OpenSharedTokenList(Isolate* isolate) {
+  const int kInitialSharedCapacity = 5*1024;
+  ObjectStore* store = isolate->object_store();
+  ASSERT(store->token_objects() == GrowableObjectArray::null());
+  const GrowableObjectArray& token_objects = GrowableObjectArray::Handle(
+      GrowableObjectArray::New(kInitialSharedCapacity, Heap::kOld));
+  store->set_token_objects(token_objects);
+  const Array& token_objects_map = Array::Handle(
+      HashTables::New<CompressedTokenMap>(kInitialSharedCapacity,
+                                          Heap::kOld));
+  store->set_token_objects_map(token_objects_map);
+}
+
+
+void TokenStream::CloseSharedTokenList(Isolate* isolate) {
+  isolate->object_store()->set_token_objects(GrowableObjectArray::Handle());
+  isolate->object_store()->set_token_objects_map(Array::null_array());
+}
+
+
 const char* TokenStream::ToCString() const {
   return "TokenStream";
 }
@@ -8393,7 +8548,8 @@
     : tokens_(TokenStream::Handle(tokens.raw())),
       data_(ExternalTypedData::Handle(tokens.GetStream())),
       stream_(reinterpret_cast<uint8_t*>(data_.DataAddr(0)), data_.Length()),
-      token_objects_(Array::Handle(tokens.TokenObjects())),
+      token_objects_(Array::Handle(
+          GrowableObjectArray::Handle(tokens.TokenObjects()).data())),
       obj_(Object::Handle()),
       cur_token_pos_(token_pos),
       cur_token_kind_(Token::kILLEGAL),
@@ -8409,7 +8565,7 @@
   data_ = tokens.GetStream();
   stream_.SetStream(reinterpret_cast<uint8_t*>(data_.DataAddr(0)),
                     data_.Length());
-  token_objects_ = tokens.TokenObjects();
+  token_objects_ = GrowableObjectArray::Handle(tokens.TokenObjects()).data();
   obj_ = Object::null();
   cur_token_pos_ = token_pos;
   cur_token_kind_ = Token::kILLEGAL;
@@ -8538,6 +8694,10 @@
 
 RawString* Script::GenerateSource() const {
   const TokenStream& token_stream = TokenStream::Handle(tokens());
+  if (token_stream.IsNull()) {
+    ASSERT(Dart::IsRunningPrecompiledCode());
+    return String::null();
+  }
   return token_stream.GenerateSource();
 }
 
@@ -8664,7 +8824,8 @@
 }
 
 
-void Script::Tokenize(const String& private_key) const {
+void Script::Tokenize(const String& private_key,
+                      bool use_shared_tokens) const {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   const TokenStream& tkns = TokenStream::Handle(zone, tokens());
@@ -8679,7 +8840,8 @@
   Scanner scanner(src, private_key);
   const Scanner::GrowableTokenStream& ts = scanner.GetStream();
   INC_STAT(thread, num_tokens_scanned, ts.length());
-  set_tokens(TokenStream::Handle(zone, TokenStream::New(ts, private_key)));
+  set_tokens(TokenStream::Handle(zone,
+      TokenStream::New(ts, private_key, use_shared_tokens)));
   INC_STAT(thread, src_length, src.Length());
 }
 
@@ -8699,6 +8861,17 @@
                               intptr_t* token_len) const {
   ASSERT(line != NULL);
   const TokenStream& tkns = TokenStream::Handle(tokens());
+  if (tkns.IsNull()) {
+    ASSERT(Dart::IsRunningPrecompiledCode());
+    *line = -1;
+    if (column != NULL) {
+      *column = -1;
+    }
+    if (token_len != NULL) {
+      *token_len = 1;
+    }
+    return;
+  }
   if (column == NULL) {
     TokenStream::Iterator tkit(tkns, 0, TokenStream::Iterator::kAllTokens);
     intptr_t cur_line = line_offset() + 1;
@@ -8941,10 +9114,12 @@
   const String& source = String::Handle(Source());
   jsobj.AddProperty("lineOffset", line_offset());
   jsobj.AddProperty("columnOffset", col_offset());
-  jsobj.AddPropertyStr("source", source);
+  if (!source.IsNull()) {
+    jsobj.AddPropertyStr("source", source);
+  }
 
   // Print the line number table
-  {
+  if (!source.IsNull()) {
     JSONArray tokenPosTable(&jsobj, "tokenPosTable");
 
     const GrowableObjectArray& lineNumberArray =
@@ -9218,8 +9393,8 @@
                                           false,  // is_const
                                           false,  // is_reflectable
                                           cls,
+                                          Object::dynamic_type(),
                                           token_pos));
-  field.set_type(Type::Handle(Type::DynamicType()));
   field.SetStaticValue(Array::empty_array(), true);
   GrowableObjectArray& metadata =
       GrowableObjectArray::Handle(this->metadata());
@@ -9586,19 +9761,12 @@
         GrowableObjectArray::Handle(GrowableObjectArray::New(8));
     Object& entry = Object::Handle();
     Class& cls = Class::Handle();
-    Class& patch_cls = Class::Handle();
     Script& owner_script = Script::Handle();
-    Script& patch_script = Script::Handle();
     DictionaryIterator it(*this);
     while (it.HasNext()) {
       entry = it.GetNext();
       if (entry.IsClass()) {
         owner_script = Class::Cast(entry).script();
-        patch_cls = Class::Cast(entry).patch_class();
-        if (!patch_cls.IsNull()) {
-          patch_script = patch_cls.script();
-          AddScriptIfUnique(scripts, patch_script);
-        }
       } else if (entry.IsFunction()) {
         owner_script = Function::Cast(entry).script();
       } else if (entry.IsField()) {
@@ -9610,6 +9778,14 @@
       AddScriptIfUnique(scripts, owner_script);
     }
 
+    // Add all scripts from patch classes.
+    GrowableObjectArray& patches = GrowableObjectArray::Handle(patch_classes());
+    for (intptr_t i = 0; i < patches.Length(); i++) {
+      cls ^= patches.At(i);
+      owner_script = cls.script();
+      AddScriptIfUnique(scripts, owner_script);
+    }
+
     // Special case: Scripts that only contain external top-level functions are
     // not included above, but can be referenced through a library's anonymous
     // classes. Example: dart-core:identical.dart.
@@ -9668,24 +9844,6 @@
 }
 
 
-RawFunction* Library::LookupFunctionInScript(const Script& script,
-                                             intptr_t token_pos) const {
-  Class& cls = Class::Handle();
-  Function& func = Function::Handle();
-  ClassDictionaryIterator it(*this, ClassDictionaryIterator::kIteratePrivate);
-  while (it.HasNext()) {
-    cls = it.GetNextClass();
-    if (script.raw() == cls.script()) {
-      func = cls.LookupFunctionAtToken(token_pos);
-      if (!func.IsNull()) {
-        return func.raw();
-      }
-    }
-  }
-  return Function::null();
-}
-
-
 RawObject* Library::LookupLocalObject(const String& name) const {
   intptr_t index;
   return LookupEntry(name, &index);
@@ -10003,6 +10161,9 @@
                       GrowableObjectArray::New(4, Heap::kOld));
   result.StorePointer(&result.raw_ptr()->anonymous_classes_,
                       Object::empty_array().raw());
+  result.StorePointer(&result.raw_ptr()->patch_classes_,
+                      GrowableObjectArray::New(Object::empty_array(),
+                                               Heap::kOld));
   result.StoreNonPointer(&result.raw_ptr()->num_anonymous_, 0);
   result.StorePointer(&result.raw_ptr()->imports_, Object::empty_array().raw());
   result.StorePointer(&result.raw_ptr()->exports_, Object::empty_array().raw());
@@ -10058,7 +10219,7 @@
 RawObject* Library::Evaluate(const String& expr,
                              const Array& param_names,
                              const Array& param_values) const {
-  // Take or make a fake top-level class and evaluate the expression
+  // Take a top-level class and evaluate the expression
   // as a static function of the class.
   Class& top_level_class = Class::Handle();
   Array& top_level_classes = Array::Handle(anonymous_classes());
@@ -10580,7 +10741,7 @@
   } else if (deferred_lib.LoadNotStarted()) {
     Thread* thread = Thread::Current();
     Isolate* isolate = thread->isolate();
-    Api::Scope api_scope(isolate);
+    Api::Scope api_scope(thread);
     Zone* zone = thread->zone();
     deferred_lib.SetLoadRequested();
     const GrowableObjectArray& pending_deferred_loads =
@@ -10638,6 +10799,10 @@
     }
   }
 
+  virtual void IncrementInvalidationGen() {
+    Isolate::Current()->IncrPrefixInvalidationGen();
+  }
+
  private:
   const LibraryPrefix& prefix_;
   DISALLOW_COPY_AND_ASSIGN(PrefixDependentArray);
@@ -10732,8 +10897,8 @@
                                           false,  // is_const
                                           false,  // is_reflectable
                                           owner_class,
+                                          Object::dynamic_type(),
                                           token_pos));
-  field.set_type(Type::Handle(Type::DynamicType()));
   field.SetStaticValue(Array::empty_array(), true);
   set_metadata_field(field);
   owner_class.AddField(field);
@@ -11333,18 +11498,22 @@
 // finally blocks).
 void PcDescriptors::Verify(const Function& function) const {
 #if defined(DEBUG)
-  // TODO(srdjan): Implement a more efficient way to check, currently drop
-  // the check for too large number of descriptors.
-  if (Length() > 3000) {
-    if (FLAG_trace_compiler) {
-      OS::Print("Not checking pc decriptors, length %" Pd "\n", Length());
-    }
-    return;
-  }
   // Only check ids for unoptimized code that is optimizable.
   if (!function.IsOptimizable()) {
     return;
   }
+  intptr_t max_deopt_id = 0;
+  Iterator max_iter(*this,
+                    RawPcDescriptors::kDeopt | RawPcDescriptors::kIcCall);
+  while (max_iter.MoveNext()) {
+    if (max_iter.DeoptId() > max_deopt_id) {
+      max_deopt_id = max_iter.DeoptId();
+    }
+  }
+
+  Zone* zone = Thread::Current()->zone();
+  BitVector* deopt_ids = new(zone) BitVector(zone, max_deopt_id + 1);
+  BitVector* iccall_ids = new(zone) BitVector(zone, max_deopt_id + 1);
   Iterator iter(*this, RawPcDescriptors::kDeopt | RawPcDescriptors::kIcCall);
   while (iter.MoveNext()) {
     // 'deopt_id' is set for kDeopt and kIcCall and must be unique for one kind.
@@ -11354,12 +11523,12 @@
       // lead to issues in the future. Fix that and enable verification.
       continue;
     }
-
-    Iterator nested(iter);
-    while (nested.MoveNext()) {
-      if (iter.Kind() == nested.Kind()) {
-        ASSERT(nested.DeoptId() != iter.DeoptId());
-      }
+    if (iter.Kind() == RawPcDescriptors::kDeopt) {
+      ASSERT(!deopt_ids->Contains(iter.DeoptId()));
+      deopt_ids->Add(iter.DeoptId());
+    } else {
+      ASSERT(!iccall_ids->Contains(iter.DeoptId()));
+      iccall_ids->Add(iter.DeoptId());
     }
   }
 #endif  // DEBUG
@@ -11995,7 +12164,7 @@
 }
 
 
-void ICData::set_ic_data(const Array& value) const {
+void ICData::set_ic_data_array(const Array& value) const {
   ASSERT(!value.IsNull());
   StorePointer(&raw_ptr()->ic_data_, value.raw());
 }
@@ -12103,9 +12272,9 @@
 }
 
 
-void ICData::WriteSentinel(const Array& data) const {
+void ICData::WriteSentinel(const Array& data, intptr_t test_entry_length) {
   ASSERT(!data.IsNull());
-  for (intptr_t i = 1; i <= TestEntryLength(); i++) {
+  for (intptr_t i = 1; i <= test_entry_length; i++) {
     data.SetAt(data.Length() - i, smi_illegal_cid());
   }
 }
@@ -12158,8 +12327,7 @@
   Array& data = Array::Handle(ic_data());
   const intptr_t new_len = data.Length() + TestEntryLength();
   data = Array::Grow(data, new_len, Heap::kOld);
-  set_ic_data(data);
-  WriteSentinel(data);
+  WriteSentinel(data, TestEntryLength());
   intptr_t data_pos = old_num * TestEntryLength();
   ASSERT(!target.IsNull());
   data.SetAt(data_pos++, target);
@@ -12167,6 +12335,9 @@
   // call has been executed.
   const Smi& value = Smi::Handle(Smi::New(0));
   data.SetAt(data_pos, value);
+  // Multithreaded access to ICData requires setting of array to be the last
+  // operation.
+  set_ic_data_array(data);
 }
 
 
@@ -12204,8 +12375,7 @@
   }
   const intptr_t new_len = data.Length() + TestEntryLength();
   data = Array::Grow(data, new_len, Heap::kOld);
-  set_ic_data(data);
-  WriteSentinel(data);
+  WriteSentinel(data, TestEntryLength());
   intptr_t data_pos = old_num * TestEntryLength();
   Smi& value = Smi::Handle();
   for (intptr_t i = 0; i < class_ids.length(); i++) {
@@ -12218,6 +12388,9 @@
   data.SetAt(data_pos++, target);
   value = Smi::New(1);
   data.SetAt(data_pos, value);
+  // Multithreaded access to ICData requires setting of array to be the last
+  // operation.
+  set_ic_data_array(data);
 }
 
 
@@ -12237,8 +12410,7 @@
   Array& data = Array::Handle(ic_data());
   const intptr_t new_len = data.Length() + TestEntryLength();
   data = Array::Grow(data, new_len, Heap::kOld);
-  set_ic_data(data);
-  WriteSentinel(data);
+  WriteSentinel(data, TestEntryLength());
   intptr_t data_pos = old_num * TestEntryLength();
   if ((receiver_class_id == kSmiCid) && (data_pos > 0)) {
     ASSERT(GetReceiverClassIdAt(0) != kSmiCid);
@@ -12252,6 +12424,9 @@
   data.SetAt(data_pos, Smi::Handle(Smi::New(receiver_class_id)));
   data.SetAt(data_pos + 1, target);
   data.SetAt(data_pos + 2, Smi::Handle(Smi::New(count)));
+  // Multithreaded access to ICData requires setting of array to be the last
+  // operation.
+  set_ic_data_array(data);
 }
 
 
@@ -12502,6 +12677,64 @@
 }
 
 
+void ICData::InitOnce() {
+  for (int i = 0; i < kCachedICDataArrayCount; i++) {
+    cached_icdata_arrays_[i] = ICData::NewNonCachedEmptyICDataArray(i);
+  }
+}
+
+
+RawArray* ICData::NewNonCachedEmptyICDataArray(intptr_t num_args_tested) {
+  // IC data array must be null terminated (sentinel entry).
+  const intptr_t len = TestEntryLengthFor(num_args_tested);
+  const Array& array = Array::Handle(Array::New(len, Heap::kOld));
+  WriteSentinel(array, len);
+  array.MakeImmutable();
+  return array.raw();
+}
+
+
+RawArray* ICData::NewEmptyICDataArray(intptr_t num_args_tested) {
+  ASSERT(num_args_tested >= 0);
+  if (num_args_tested < kCachedICDataArrayCount) {
+    return cached_icdata_arrays_[num_args_tested];
+  }
+  return NewNonCachedEmptyICDataArray(num_args_tested);
+}
+
+
+
+// Does not initialize ICData array.
+RawICData* ICData::NewDescriptor(Zone* zone,
+                                 const Function& owner,
+                                 const String& target_name,
+                                 const Array& arguments_descriptor,
+                                 intptr_t deopt_id,
+                                 intptr_t num_args_tested) {
+  ASSERT(!owner.IsNull());
+  ASSERT(!target_name.IsNull());
+  ASSERT(!arguments_descriptor.IsNull());
+  ASSERT(Object::icdata_class() != Class::null());
+  ASSERT(num_args_tested >= 0);
+  ICData& result = ICData::Handle(zone);
+  {
+    // IC data objects are long living objects, allocate them in old generation.
+    RawObject* raw = Object::Allocate(ICData::kClassId,
+                                      ICData::InstanceSize(),
+                                      Heap::kOld);
+    NoSafepointScope no_safepoint;
+    result ^= raw;
+  }
+  result.set_owner(owner);
+  result.set_target_name(target_name);
+  result.set_arguments_descriptor(arguments_descriptor);
+  result.set_deopt_id(deopt_id);
+  result.set_state_bits(0);
+  result.SetNumArgsTested(num_args_tested);
+  return result.raw();
+}
+
+
 RawICData* ICData::New() {
   ICData& result = ICData::Handle();
   {
@@ -12523,32 +12756,16 @@
                        const Array& arguments_descriptor,
                        intptr_t deopt_id,
                        intptr_t num_args_tested) {
-  ASSERT(!owner.IsNull());
-  ASSERT(!target_name.IsNull());
-  ASSERT(!arguments_descriptor.IsNull());
-  ASSERT(Object::icdata_class() != Class::null());
-  ASSERT(num_args_tested >= 0);
-  ICData& result = ICData::Handle();
-  {
-    // IC data objects are long living objects, allocate them in old generation.
-    RawObject* raw = Object::Allocate(ICData::kClassId,
-                                      ICData::InstanceSize(),
-                                      Heap::kOld);
-    NoSafepointScope no_safepoint;
-    result ^= raw;
-  }
-  result.set_owner(owner);
-  result.set_target_name(target_name);
-  result.set_arguments_descriptor(arguments_descriptor);
-  result.set_deopt_id(deopt_id);
-  result.set_state_bits(0);
-  result.SetNumArgsTested(num_args_tested);
-  // Number of array elements in one test entry.
-  intptr_t len = result.TestEntryLength();
-  // IC data array must be null terminated (sentinel entry).
-  const Array& ic_data = Array::Handle(Array::New(len, Heap::kOld));
-  result.set_ic_data(ic_data);
-  result.WriteSentinel(ic_data);
+  Zone* zone = Thread::Current()->zone();
+  const ICData& result = ICData::Handle(zone,
+                                        NewDescriptor(zone,
+                                                      owner,
+                                                      target_name,
+                                                      arguments_descriptor,
+                                                      deopt_id,
+                                                      num_args_tested));
+  result.set_ic_data_array(
+      Array::Handle(zone, NewEmptyICDataArray(num_args_tested)));
   return result.raw();
 }
 
@@ -12566,6 +12783,23 @@
 }
 
 
+RawICData* ICData::CloneDescriptor(const ICData& from) {
+  Zone* zone = Thread::Current()->zone();
+  const ICData& result = ICData::Handle(ICData::NewDescriptor(
+      zone,
+      Function::Handle(zone, from.owner()),
+      String::Handle(zone, from.target_name()),
+      Array::Handle(zone, from.arguments_descriptor()),
+      from.deopt_id(),
+      from.NumArgsTested()));
+  // Preserve entry array.
+  result.set_ic_data_array(Array::Handle(zone, from.ic_data()));
+  // Copy deoptimization reasons.
+  result.SetDeoptReasons(from.DeoptReasons());
+  return result.raw();
+}
+
+
 void ICData::PrintJSONImpl(JSONStream* stream, bool ref) const {
   JSONObject jsobj(stream);
   AddCommonObjectProperties(&jsobj, "Object", ref);
@@ -12831,7 +13065,10 @@
   const Instructions& instrs = Instructions::Handle(instructions());
   uword code_entry = instrs.EntryPoint();
   const Array& table = Array::Handle(deopt_info_array());
-  ASSERT(!table.IsNull());
+  if (table.IsNull()) {
+    ASSERT(Dart::IsRunningPrecompiledCode());
+    return TypedData::null();
+  }
   // Linear search for the PC offset matching the target PC.
   intptr_t length = DeoptTable::GetLength(table);
   Smi& offset = Smi::Handle();
@@ -13088,7 +13325,6 @@
   INC_STAT(Thread::Current(), total_instr_size, assembler->CodeSize());
   INC_STAT(Thread::Current(), total_code_size, assembler->CodeSize());
 
-  instrs.set_code(code.raw());
   // Copy the instructions into the instruction area and apply all fixups.
   // Embedded pointers are still in handles at this point.
   MemoryRegion region(reinterpret_cast<void*>(instrs.EntryPoint()),
@@ -13122,7 +13358,7 @@
     }
 
     // Hook up Code and Instructions objects.
-    code.set_active_instructions(instrs.raw());
+    code.SetActiveInstructions(instrs.raw());
     code.set_instructions(instrs.raw());
     code.set_is_alive(true);
 
@@ -13164,38 +13400,26 @@
                         assembler,
                         optimized);
   } else {
-    return FinalizeCode("", assembler);
+    return FinalizeCode("", assembler, optimized);
   }
 }
 
 
-// Check if object matches find condition.
-bool Code::FindRawCodeVisitor::FindObject(RawObject* raw_obj) const {
-  uword tags = raw_obj->ptr()->tags_;
-  if (RawObject::ClassIdTag::decode(tags) == kInstructionsCid) {
-    RawInstructions* raw_insts = reinterpret_cast<RawInstructions*>(raw_obj);
-    return RawInstructions::ContainsPC(raw_insts, pc_);
-  }
-  return false;
+bool Code::SlowFindRawCodeVisitor::FindObject(RawObject* raw_obj) const {
+  return RawCode::ContainsPC(raw_obj, pc_);
 }
 
 
 RawCode* Code::LookupCodeInIsolate(Isolate* isolate, uword pc) {
   ASSERT((isolate == Isolate::Current()) || (isolate == Dart::vm_isolate()));
-  NoSafepointScope no_safepoint;
-  FindRawCodeVisitor visitor(pc);
-  RawInstructions* instr;
-  if (Dart::IsRunningPrecompiledCode()) {
-    // TODO(johnmccutchan): Make code lookup work when running precompiled.
-    UNIMPLEMENTED();
-    return Code::null();
-  }
   if (isolate->heap() == NULL) {
     return Code::null();
   }
-  instr = isolate->heap()->FindObjectInCodeSpace(&visitor);
-  if (instr != Instructions::null()) {
-    return Instructions::Handle(instr).code();
+  NoSafepointScope no_safepoint;
+  SlowFindRawCodeVisitor visitor(pc);
+  RawObject* needle = isolate->heap()->FindOldObject(&visitor);
+  if (needle != Code::null()) {
+    return static_cast<RawCode*>(needle);
   }
   return Code::null();
 }
@@ -13282,20 +13506,21 @@
 }
 
 
+// Called by disassembler.
 RawString* Code::Name() const {
   const Object& obj = Object::Handle(owner());
   if (obj.IsNull()) {
     // Regular stub.
     const char* name = StubCode::NameOfStub(EntryPoint());
     ASSERT(name != NULL);
-    const String& stub_name = String::Handle(String::New(name));
-    return String::Concat(Symbols::StubPrefix(), stub_name);
+    const String& stub_name = String::Handle(Symbols::New(name));
+    return Symbols::FromConcat(Symbols::StubPrefix(), stub_name);
   } else if (obj.IsClass()) {
     // Allocation stub.
     const Class& cls = Class::Cast(obj);
     String& cls_name = String::Handle(cls.Name());
     ASSERT(!cls_name.IsNull());
-    return String::Concat(Symbols::AllocationStubFor(), cls_name);
+    return Symbols::FromConcat(Symbols::AllocationStubFor(), cls_name);
   } else {
     ASSERT(obj.IsFunction());
     // Dart function.
@@ -13345,20 +13570,33 @@
 
 
 void Code::DisableDartCode() const {
+  DEBUG_ASSERT(IsMutatorOrAtSafepoint());
   ASSERT(IsFunctionCode());
   ASSERT(instructions() == active_instructions());
   const Code& new_code =
       Code::Handle(StubCode::FixCallersTarget_entry()->code());
-  set_active_instructions(new_code.instructions());
+  SetActiveInstructions(new_code.instructions());
 }
 
 
 void Code::DisableStubCode() const {
-ASSERT(IsAllocationStubCode());
+  ASSERT(Thread::Current()->IsMutatorThread());
+  ASSERT(IsAllocationStubCode());
   ASSERT(instructions() == active_instructions());
   const Code& new_code =
       Code::Handle(StubCode::FixAllocationStubTarget_entry()->code());
-  set_active_instructions(new_code.instructions());
+  SetActiveInstructions(new_code.instructions());
+}
+
+
+void Code::SetActiveInstructions(RawInstructions* instructions) const {
+  DEBUG_ASSERT(IsMutatorOrAtSafepoint() || !is_alive());
+  // RawInstructions are never allocated in New space and hence a
+  // store buffer update is not needed here.
+  StorePointer(&raw_ptr()->active_instructions_, instructions);
+  StoreNonPointer(&raw_ptr()->entry_point_,
+                  reinterpret_cast<uword>(instructions->ptr()) +
+                  Instructions::HeaderSize());
 }
 
 
@@ -13378,10 +13616,18 @@
     jsobj.AddProperty("kind", "Dart");
   }
   jsobj.AddProperty("_optimized", is_optimized());
+  const Object& obj = Object::Handle(owner());
+  if (obj.IsFunction()) {
+    const Function& func = Function::Cast(obj);
+    jsobj.AddProperty("_intrinsic", func.is_intrinsic());
+    jsobj.AddProperty("_native", func.is_native());
+  } else {
+    jsobj.AddProperty("_intrinsic", false);
+    jsobj.AddProperty("_native", false);
+  }
   if (ref) {
     return;
   }
-  const Object& obj = Object::Handle(owner());
   if (obj.IsFunction()) {
     jsobj.AddProperty("function", obj);
   } else {
@@ -13621,13 +13867,13 @@
   Zone* zone = Thread::Current()->zone();
   const Context& parent_ctx = Context::Handle(parent());
   if (parent_ctx.IsNull()) {
-    return zone->PrintToString("Context@%p num_variables:% " Pd "",
-                               this->raw(), num_variables());
+    return zone->PrintToString("Context num_variables: %" Pd "",
+                               num_variables());
   } else {
     const char* parent_str = parent_ctx.ToCString();
     return zone->PrintToString(
-        "Context@%p num_variables:% " Pd " parent:{ %s }",
-        this->raw(), num_variables(), parent_str);
+        "Context num_variables: %" Pd " parent:{ %s }",
+        num_variables(), parent_str);
   }
 }
 
@@ -13863,6 +14109,16 @@
 }
 
 
+void MegamorphicCache::set_target_name(const String& value) const {
+  StorePointer(&raw_ptr()->target_name_, value.raw());
+}
+
+
+void MegamorphicCache::set_arguments_descriptor(const Array& value) const {
+  StorePointer(&raw_ptr()->args_descriptor_, value.raw());
+}
+
+
 RawMegamorphicCache* MegamorphicCache::New() {
   MegamorphicCache& result = MegamorphicCache::Handle();
   { RawObject* raw = Object::Allocate(MegamorphicCache::kClassId,
@@ -13871,6 +14127,20 @@
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
+  result.set_filled_entry_count(0);
+  return result.raw();
+}
+
+
+RawMegamorphicCache* MegamorphicCache::New(const String& target_name,
+                                           const Array& arguments_descriptor) {
+  MegamorphicCache& result = MegamorphicCache::Handle();
+  { RawObject* raw = Object::Allocate(MegamorphicCache::kClassId,
+                                      MegamorphicCache::InstanceSize(),
+                                      Heap::kOld);
+    NoSafepointScope no_safepoint;
+    result ^= raw;
+  }
   const intptr_t capacity = kInitialCapacity;
   const Array& buckets = Array::Handle(
       Array::New(kEntryLength * capacity, Heap::kOld));
@@ -13881,6 +14151,8 @@
   }
   result.set_buckets(buckets);
   result.set_mask(capacity - 1);
+  result.set_target_name(target_name);
+  result.set_arguments_descriptor(arguments_descriptor);
   result.set_filled_entry_count(0);
   return result.raw();
 }
@@ -13938,7 +14210,9 @@
 
 
 const char* MegamorphicCache::ToCString() const {
-  return "MegamorphicCache";
+  const String& name = String::Handle(target_name());
+  return OS::SCreate(Thread::Current()->zone(),
+                     "MegamorphicCache(%s)", name.ToCString());
 }
 
 
@@ -13946,11 +14220,14 @@
   JSONObject jsobj(stream);
   AddCommonObjectProperties(&jsobj, "Object", ref);
   jsobj.AddServiceId(*this);
+  jsobj.AddProperty("_selector", String::Handle(target_name()).ToCString());
   if (ref) {
     return;
   }
   jsobj.AddProperty("_buckets", Object::Handle(buckets()));
   jsobj.AddProperty("_mask", mask());
+  jsobj.AddProperty("_argumentsDescriptor",
+                    Object::Handle(arguments_descriptor()));
 }
 
 
@@ -14711,7 +14988,8 @@
 
 
 bool Instance::IsClosure() const {
-  return Class::IsSignatureClass(clazz());
+  const Class& cls = Class::Handle(clazz());
+  return cls.IsSignatureClass();
 }
 
 
@@ -15404,12 +15682,12 @@
 
 
 RawType* Type::DynamicType() {
-  return Object::dynamic_type();
+  return Object::dynamic_type().raw();
 }
 
 
 RawType* Type::VoidType() {
-  return Object::void_type();
+  return Object::void_type().raw();
 }
 
 
@@ -15480,15 +15758,6 @@
 
 RawType* Type::NewNonParameterizedType(const Class& type_class) {
   ASSERT(type_class.NumTypeArguments() == 0);
-  if (type_class.raw() == Object::dynamic_class()) {
-    // If the dynamic type has not been setup in the VM isolate, then we need
-    // to allocate it here.
-    if (Object::dynamic_type() != reinterpret_cast<RawType*>(RAW_NULL)) {
-      ASSERT(Type::Handle(Object::dynamic_type()).IsFinalized());
-      return Object::dynamic_type();
-    }
-    ASSERT(Isolate::Current() == Dart::vm_isolate());
-  }
   Type& type = Type::Handle(type_class.CanonicalType());
   if (type.IsNull()) {
     const TypeArguments& no_type_arguments = TypeArguments::Handle();
@@ -15828,7 +16097,7 @@
   Type& type = Type::Handle(zone);
   const Class& cls = Class::Handle(zone, type_class());
   if (cls.raw() == Object::dynamic_class() && (isolate != Dart::vm_isolate())) {
-    return Object::dynamic_type();
+    return Object::dynamic_type().raw();
   }
   // Fast canonical lookup/registry for simple types.
   if (cls.NumTypeArguments() == 0) {
@@ -16771,9 +17040,9 @@
 
 
 const char* Integer::ToCString() const {
-  // Integer is an interface. No instances of Integer should exist.
-  UNREACHABLE();
-  return "Integer";
+  // Integer is an interface. No instances of Integer should exist except null.
+  ASSERT(IsNull());
+  return "NULL Integer";
 }
 
 
@@ -17030,8 +17299,12 @@
         break;
       }
       case Token::kSUB: {
-        if (((left_value < 0) == (right_value < 0)) ||
-            ((left_value - right_value) < 0) == (left_value < 0)) {
+        // TODO(srdjan): Investigate why XCode 7 produces wrong code
+        // if the comparison is inlined as in above (Token::kADD).
+        const bool both_same_sign = (left_value < 0) == (right_value < 0);
+        const bool result_same_sign_as_left =
+            ((left_value - right_value) < 0) == (left_value < 0);
+        if (both_same_sign || result_same_sign_as_left) {
           return Integer::New(left_value - right_value, space);
         }
         break;
@@ -17565,7 +17838,7 @@
     ASSERT(!digits_.IsNull());
     set_digits(digits_);
   } else {
-    ASSERT(digits() == TypedData::EmptyUint32Array(Isolate::Current()));
+    ASSERT(digits() == TypedData::EmptyUint32Array(Thread::Current()));
   }
   return true;
 }
@@ -17587,7 +17860,7 @@
   result.SetNeg(false);
   result.SetUsed(0);
   result.set_digits(
-      TypedData::Handle(zone, TypedData::EmptyUint32Array(isolate)));
+      TypedData::Handle(zone, TypedData::EmptyUint32Array(thread)));
   return result.raw();
 }
 
@@ -17621,7 +17894,7 @@
   } else {
     neg = false;
     result.set_digits(
-        TypedData::Handle(zone, TypedData::EmptyUint32Array(isolate)));
+        TypedData::Handle(zone, TypedData::EmptyUint32Array(thread)));
   }
   result.SetNeg(neg);
   result.SetUsed(used);
@@ -20092,10 +20365,21 @@
   if (ref) {
     return;
   }
+  intptr_t offset;
+  intptr_t count;
+  stream->ComputeOffsetAndCount(Length(), &offset, &count);
+  if (offset > 0) {
+    jsobj.AddProperty("offset", offset);
+  }
+  if (count < Length()) {
+    jsobj.AddProperty("count", count);
+  }
+  intptr_t limit = offset + count;
+  ASSERT(limit <= Length());
   {
     JSONArray jsarr(&jsobj, "elements");
     Object& element = Object::Handle();
-    for (intptr_t index = 0; index < Length(); index++) {
+    for (intptr_t index = offset; index < limit; index++) {
       element = At(index);
       jsarr.AddValue(element);
     }
@@ -20330,10 +20614,21 @@
   if (ref) {
     return;
   }
+  intptr_t offset;
+  intptr_t count;
+  stream->ComputeOffsetAndCount(Length(), &offset, &count);
+  if (offset > 0) {
+    jsobj.AddProperty("offset", offset);
+  }
+  if (count < Length()) {
+    jsobj.AddProperty("count", count);
+  }
+  intptr_t limit = offset + count;
+  ASSERT(limit <= Length());
   {
     JSONArray jsarr(&jsobj, "elements");
     Object& element = Object::Handle();
-    for (intptr_t index = 0; index < Length(); index++) {
+    for (intptr_t index = offset; index < limit; index++) {
       element = At(index);
       jsarr.AddValue(element);
     }
@@ -20436,16 +20731,31 @@
   if (ref) {
     return;
   }
+  intptr_t offset;
+  intptr_t count;
+  stream->ComputeOffsetAndCount(Length(), &offset, &count);
+  if (offset > 0) {
+    jsobj.AddProperty("offset", offset);
+  }
+  if (count < Length()) {
+    jsobj.AddProperty("count", count);
+  }
+  intptr_t limit = offset + count;
+  ASSERT(limit <= Length());
   {
     JSONArray jsarr(&jsobj, "associations");
     Object& object = Object::Handle();
     LinkedHashMap::Iterator iterator(*this);
-    while (iterator.MoveNext()) {
-      JSONObject jsassoc(&jsarr);
-      object = iterator.CurrentKey();
-      jsassoc.AddProperty("key", object);
-      object = iterator.CurrentValue();
-      jsassoc.AddProperty("value", object);
+    int i = 0;
+    while (iterator.MoveNext() && i < limit) {
+      if (i >= offset) {
+        JSONObject jsassoc(&jsarr);
+        object = iterator.CurrentKey();
+        jsassoc.AddProperty("key", object);
+        object = iterator.CurrentValue();
+        jsassoc.AddProperty("value", object);
+      }
+      i++;
     }
   }
 }
@@ -20807,14 +21117,16 @@
 }
 
 
-RawTypedData* TypedData::EmptyUint32Array(Isolate* isolate) {
+RawTypedData* TypedData::EmptyUint32Array(Thread* thread) {
+  ASSERT(thread != NULL);
+  Isolate* isolate = thread->isolate();
   ASSERT(isolate != NULL);
   ASSERT(isolate->object_store() != NULL);
   if (isolate->object_store()->empty_uint32_array() != TypedData::null()) {
     // Already created.
     return isolate->object_store()->empty_uint32_array();
   }
-  const TypedData& array = TypedData::Handle(isolate->current_zone(),
+  const TypedData& array = TypedData::Handle(thread->zone(),
       TypedData::New(kTypedDataUint32ArrayCid, 0, Heap::kOld));
   isolate->object_store()->set_empty_uint32_array(array);
   return array.raw();
@@ -20837,12 +21149,23 @@
   if (ref) {
     return;
   }
-
-  {
+  intptr_t offset;
+  intptr_t count;
+  stream->ComputeOffsetAndCount(Length(), &offset, &count);
+  if (offset > 0) {
+    jsobj.AddProperty("offset", offset);
+  }
+  if (count < Length()) {
+    jsobj.AddProperty("count", count);
+  }
+  if (count == 0) {
+    jsobj.AddProperty("bytes", "");
+  } else {
     NoSafepointScope no_safepoint;
     jsobj.AddPropertyBase64("bytes",
-                            reinterpret_cast<const uint8_t*>(DataAddr(0)),
-                            LengthInBytes());
+                            reinterpret_cast<const uint8_t*>(
+                                DataAddr(offset * ElementSizeInBytes())),
+                            count * ElementSizeInBytes());
   }
 }
 
@@ -20888,12 +21211,23 @@
   if (ref) {
     return;
   }
-
-  {
+  intptr_t offset;
+  intptr_t count;
+  stream->ComputeOffsetAndCount(Length(), &offset, &count);
+  if (offset > 0) {
+    jsobj.AddProperty("offset", offset);
+  }
+  if (count < Length()) {
+    jsobj.AddProperty("count", count);
+  }
+  if (count == 0) {
+    jsobj.AddProperty("bytes", "");
+  } else {
     NoSafepointScope no_safepoint;
     jsobj.AddPropertyBase64("bytes",
-                            reinterpret_cast<const uint8_t*>(DataAddr(0)),
-                            LengthInBytes());
+                            reinterpret_cast<const uint8_t*>(
+                                DataAddr(offset * ElementSizeInBytes())),
+                            count * ElementSizeInBytes());
   }
 }
 
@@ -21455,15 +21789,16 @@
 
 
 RawUserTag* UserTag::New(const String& label, Heap::Space space) {
-  Isolate* isolate = Isolate::Current();
+  Thread* thread = Thread::Current();
+  Isolate* isolate = thread->isolate();
   ASSERT(isolate->tag_table() != GrowableObjectArray::null());
   // Canonicalize by name.
-  UserTag& result = UserTag::Handle(FindTagInIsolate(isolate, label));
+  UserTag& result = UserTag::Handle(FindTagInIsolate(thread, label));
   if (!result.IsNull()) {
     // Tag already exists, return existing instance.
     return result.raw();
   }
-  if (TagTableIsFull(isolate)) {
+  if (TagTableIsFull(thread)) {
     const String& error = String::Handle(
         String::NewFormatted("UserTag instance limit (%" Pd ") reached.",
                              UserTags::kMaxUserTags));
@@ -21480,7 +21815,7 @@
     result ^= raw;
   }
   result.set_label(label);
-  AddTagToIsolate(isolate, result);
+  AddTagToIsolate(thread, result);
   return result.raw();
 }
 
@@ -21503,12 +21838,14 @@
 }
 
 
-RawUserTag* UserTag::FindTagInIsolate(Isolate* isolate, const String& label) {
+RawUserTag* UserTag::FindTagInIsolate(Thread* thread, const String& label) {
+  Isolate* isolate = thread->isolate();
+  Zone* zone = thread->zone();
   ASSERT(isolate->tag_table() != GrowableObjectArray::null());
   const GrowableObjectArray& tag_table = GrowableObjectArray::Handle(
-      isolate->current_zone(), isolate->tag_table());
-  UserTag& other = UserTag::Handle(isolate->current_zone());
-  String& tag_label = String::Handle(isolate->current_zone());
+      zone, isolate->tag_table());
+  UserTag& other = UserTag::Handle(zone);
+  String& tag_label = String::Handle(zone);
   for (intptr_t i = 0; i < tag_table.Length(); i++) {
     other ^= tag_table.At(i);
     ASSERT(!other.IsNull());
@@ -21522,14 +21859,16 @@
 }
 
 
-void UserTag::AddTagToIsolate(Isolate* isolate, const UserTag& tag) {
+void UserTag::AddTagToIsolate(Thread* thread, const UserTag& tag) {
+  Isolate* isolate = thread->isolate();
+  Zone* zone = thread->zone();
   ASSERT(isolate->tag_table() != GrowableObjectArray::null());
   const GrowableObjectArray& tag_table = GrowableObjectArray::Handle(
-      isolate->current_zone(), isolate->tag_table());
-  ASSERT(!TagTableIsFull(isolate));
+      zone, isolate->tag_table());
+  ASSERT(!TagTableIsFull(thread));
 #if defined(DEBUG)
   // Verify that no existing tag has the same tag id.
-  UserTag& other = UserTag::Handle(isolate->current_zone());
+  UserTag& other = UserTag::Handle(thread->zone());
   for (intptr_t i = 0; i < tag_table.Length(); i++) {
     other ^= tag_table.At(i);
     ASSERT(!other.IsNull());
@@ -21546,10 +21885,11 @@
 }
 
 
-bool UserTag::TagTableIsFull(Isolate* isolate) {
+bool UserTag::TagTableIsFull(Thread* thread) {
+  Isolate* isolate = thread->isolate();
   ASSERT(isolate->tag_table() != GrowableObjectArray::null());
   const GrowableObjectArray& tag_table = GrowableObjectArray::Handle(
-      isolate->current_zone(), isolate->tag_table());
+      thread->zone(), isolate->tag_table());
   ASSERT(tag_table.Length() <= UserTags::kMaxUserTags);
   return tag_table.Length() == UserTags::kMaxUserTags;
 }
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 1193686..7c40e63 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -468,17 +468,29 @@
     return *branch_offset_error_;
   }
 
+  static const LanguageError& speculative_inlining_error() {
+    ASSERT(speculative_inlining_error_ != NULL);
+    return *speculative_inlining_error_;
+  }
+
   static const Array& vm_isolate_snapshot_object_table() {
     ASSERT(vm_isolate_snapshot_object_table_ != NULL);
     return *vm_isolate_snapshot_object_table_;
   }
+  static const Type& dynamic_type() {
+    ASSERT(dynamic_type_ != NULL);
+    return *dynamic_type_;
+  }
+  static const Type& void_type() {
+    ASSERT(void_type_ != NULL);
+    return *void_type_;
+  }
+
   static void InitVmIsolateSnapshotObjectTable(intptr_t len);
 
   static RawClass* class_class() { return class_class_; }
   static RawClass* dynamic_class() { return dynamic_class_; }
   static RawClass* void_class() { return void_class_; }
-  static RawType* dynamic_type() { return dynamic_type_; }
-  static RawType* void_type() { return void_type_; }
   static RawClass* unresolved_class_class() { return unresolved_class_class_; }
   static RawClass* type_arguments_class() { return type_arguments_class_; }
   static RawClass* patch_class_class() { return patch_class_class_; }
@@ -740,8 +752,6 @@
   static RawClass* class_class_;  // Class of the Class vm object.
   static RawClass* dynamic_class_;  // Class of the 'dynamic' type.
   static RawClass* void_class_;  // Class of the 'void' type.
-  static RawType* dynamic_type_;  // Class of the 'dynamic' type.
-  static RawType* void_type_;  // Class of the 'void' type.
   static RawClass* unresolved_class_class_;  // Class of UnresolvedClass.
   static RawClass* type_arguments_class_;  // Class of TypeArguments vm object.
   static RawClass* patch_class_class_;  // Class of the PatchClass vm object.
@@ -797,7 +807,10 @@
   static Smi* smi_illegal_cid_;
   static LanguageError* snapshot_writer_error_;
   static LanguageError* branch_offset_error_;
+  static LanguageError* speculative_inlining_error_;
   static Array* vm_isolate_snapshot_object_table_;
+  static Type* dynamic_type_;
+  static Type* void_type_;
 
   friend void ClassTable::Register(const Class& cls);
   friend void RawObject::Validate(Isolate* isolate) const;
@@ -1051,10 +1064,8 @@
   // Note this returns false for mixin application aliases.
   bool IsMixinApplication() const;
 
-  RawClass* patch_class() const {
-    return raw_ptr()->patch_class_;
-  }
-  void set_patch_class(const Class& patch_class) const;
+  RawClass* GetPatchClass() const;
+  void SetPatchClass(const Class& patch_class) const;
 
   // Interfaces is an array of Types.
   RawArray* interfaces() const { return raw_ptr()->interfaces_; }
@@ -1157,15 +1168,6 @@
   intptr_t FindImplicitClosureFunctionIndex(const Function& needle) const;
   RawFunction* ImplicitClosureFunctionFromIndex(intptr_t idx) const;
 
-  RawGrowableObjectArray* closures() const {
-    return raw_ptr()->closure_functions_;
-  }
-  void set_closures(const GrowableObjectArray& value) const;
-  void AddClosureFunction(const Function& function) const;
-  RawFunction* LookupClosureFunction(intptr_t token_pos) const;
-  intptr_t FindClosureIndex(const Function& function) const;
-  RawFunction* ClosureFunctionFromIndex(intptr_t idx) const;
-
   RawFunction* LookupDynamicFunction(const String& name) const;
   RawFunction* LookupDynamicFunctionAllowPrivate(const String& name) const;
   RawFunction* LookupStaticFunction(const String& name) const;
@@ -1178,7 +1180,6 @@
   RawFunction* LookupFunctionAllowPrivate(const String& name) const;
   RawFunction* LookupGetterFunction(const String& name) const;
   RawFunction* LookupSetterFunction(const String& name) const;
-  RawFunction* LookupFunctionAtToken(intptr_t token_pos) const;
   RawField* LookupInstanceField(const String& name) const;
   RawField* LookupStaticField(const String& name) const;
   RawField* LookupField(const String& name) const;
@@ -1269,7 +1270,7 @@
   bool is_allocated() const {
     return IsAllocatedBit::decode(raw_ptr()->state_bits_);
   }
-  void set_is_allocated() const;
+  void set_is_allocated(bool value) const;
 
   uint16_t num_native_fields() const {
     return raw_ptr()->num_native_fields_;
@@ -1916,6 +1917,12 @@
                         intptr_t num_args_tested);
   static RawICData* NewFrom(const ICData& from, intptr_t num_args_tested);
 
+  // Generates a new ICData with descriptor data copied (shallow clone).
+  // Entry array of the result is the same as in 'from'. Once entry array is
+  // created, it can only change the 'count', all other properties are invariant
+  // (target, cids, number of checks).
+  static RawICData* CloneDescriptor(const ICData& from);
+
   static intptr_t TestEntryLengthFor(intptr_t num_args);
 
   static intptr_t TargetIndexFor(intptr_t num_args) {
@@ -2007,6 +2014,13 @@
                         intptr_t token_pos,
                         bool is_static_call) const;
 
+  // Initialize the preallocated empty ICData entry arrays.
+  static void InitOnce();
+
+  enum {
+    kCachedICDataArrayCount = 4
+  };
+
  private:
   static RawICData* New();
 
@@ -2019,7 +2033,7 @@
   void set_arguments_descriptor(const Array& value) const;
   void set_deopt_id(intptr_t value) const;
   void SetNumArgsTested(intptr_t value) const;
-  void set_ic_data(const Array& value) const;
+  void set_ic_data_array(const Array& value) const;
   void set_state_bits(uint32_t bits) const;
 
   enum {
@@ -2046,10 +2060,23 @@
 #endif  // DEBUG
 
   intptr_t TestEntryLength() const;
-  void WriteSentinel(const Array& data) const;
+  static RawArray* NewNonCachedEmptyICDataArray(intptr_t num_args_tested);
+  static RawArray* NewEmptyICDataArray(intptr_t num_args_tested);
+  static RawICData* NewDescriptor(Zone* zone,
+                                  const Function& owner,
+                                  const String& target_name,
+                                  const Array& arguments_descriptor,
+                                  intptr_t deopt_id,
+                                  intptr_t num_args_tested);
+
+  static void WriteSentinel(const Array& data, intptr_t test_entry_length);
+
+  // A cache of VM heap allocated preinitialized empty ic data entry arrays.
+  static RawArray* cached_icdata_arrays_[kCachedICDataArrayCount];
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(ICData, Object);
   friend class Class;
+  friend class SnapshotWriter;
 };
 
 
@@ -2117,6 +2144,9 @@
   void SetRegExpData(const JSRegExp& regexp,
                      intptr_t string_specialization_cid) const;
 
+  RawString* native_name() const;
+  void set_native_name(const String& name) const;
+
   RawAbstractType* result_type() const { return raw_ptr()->result_type_; }
   void set_result_type(const AbstractType& value) const;
 
@@ -2132,7 +2162,9 @@
   RawArray* parameter_names() const { return raw_ptr()->parameter_names_; }
   void set_parameter_names(const Array& value) const;
 
+  // Not thread-safe; must be called in the main thread.
   // Sets function's code and code's function.
+  void InstallOptimizedCode(const Code& code, bool is_osr) const;
   void AttachCode(const Code& value) const;
   void SetInstructions(const Code& value) const;
   void ClearCode() const;
@@ -2165,6 +2197,8 @@
   RawContextScope* context_scope() const;
   void set_context_scope(const ContextScope& value) const;
 
+  RawField* LookupImplicitGetterSetterField() const;
+
   // Enclosing function of this local function.
   RawFunction* parent_function() const;
 
@@ -2199,6 +2233,7 @@
   // Return the closure function implicitly created for this function.
   // If none exists yet, create one and remember it.
   RawFunction* ImplicitClosureFunction() const;
+  void DropUncompiledImplicitClosureFunction() const;
 
   // Return the closure implicitly created for this function.
   // If none exists yet, create one and remember it.
@@ -2328,6 +2363,8 @@
     return raw_ptr()->usage_counter_;
   }
   void set_usage_counter(intptr_t value) const {
+    // TODO(Srdjan): Assert that this is thread-safe, i.e., only
+    // set from mutator-thread or while at a safepoint (e.g., during marking).
     StoreNonPointer(&raw_ptr()->usage_counter_, value);
   }
 
@@ -2570,6 +2607,9 @@
                                       const Script& script,
                                       bool is_static);
 
+  RawFunction* CreateMethodExtractor(const String& getter_name) const;
+  RawFunction* GetMethodExtractor(const String& getter_name) const;
+
   // Allocate new function object, clone values from this function. The
   // owner of the clone is new_owner.
   RawFunction* Clone(const Class& new_owner) const;
@@ -2585,8 +2625,11 @@
   void SaveICDataMap(
       const ZoneGrowableArray<const ICData*>& deopt_id_to_ic_data,
       const Array& edge_counters_array) const;
+  // Uses saved ICData to populate the table 'deopt_id_to_ic_data'. Clone
+  // descriptors if 'clone_descriptors' true.
   void RestoreICDataMap(
-      ZoneGrowableArray<const ICData*>* deopt_id_to_ic_data) const;
+      ZoneGrowableArray<const ICData*>* deopt_id_to_ic_data,
+      bool clone_descriptors) const;
 
   RawArray* ic_data_array() const;
   void ClearICDataArray() const;
@@ -2655,6 +2698,7 @@
 
  private:
   void set_ic_data_array(const Array& value) const;
+  void SetInstructionsSafe(const Code& value) const;
 
   enum KindTagBits {
     kKindTagPos = 0,
@@ -2824,11 +2868,15 @@
   bool is_double_initialized() const {
     return DoubleInitializedBit::decode(raw_ptr()->kind_bits_);
   }
+  // Called in parser after allocating field, immutable property otherwise.
+  // Marks fields that are initialized with a simple double constant.
   void set_is_double_initialized(bool value) const {
+    ASSERT(Thread::Current()->IsMutatorThread());
     set_kind_bits(DoubleInitializedBit::update(value, raw_ptr()->kind_bits_));
   }
 
   inline intptr_t Offset() const;
+  // Called during class finalization.
   inline void SetOffset(intptr_t offset_in_bytes) const;
 
   inline RawInstance* StaticValue() const;
@@ -2839,7 +2887,8 @@
   RawClass* origin() const;  // Either mixin class, or same as owner().
 
   RawAbstractType* type() const  { return raw_ptr()->type_; }
-  void set_type(const AbstractType& value) const;
+  // Used by class finalizer, otherwise initialized in constructor.
+  void SetFieldType(const AbstractType& value) const;
 
   static intptr_t InstanceSize() {
     return RoundedAllocationSize(sizeof(RawField));
@@ -2851,6 +2900,7 @@
                        bool is_const,
                        bool is_reflectable,
                        const Class& owner,
+                       const AbstractType& type,
                        intptr_t token_pos);
 
   // Allocate new field object, clone values from this field. The
@@ -2871,7 +2921,9 @@
   bool has_initializer() const {
     return HasInitializerBit::decode(raw_ptr()->kind_bits_);
   }
+  // Called by parser after allocating field.
   void set_has_initializer(bool has_initializer) const {
+    ASSERT(Thread::Current()->IsMutatorThread());
     set_kind_bits(HasInitializerBit::update(has_initializer,
                                             raw_ptr()->kind_bits_));
   }
@@ -2882,6 +2934,7 @@
   intptr_t guarded_cid() const { return raw_ptr()->guarded_cid_; }
 
   void set_guarded_cid(intptr_t cid) const {
+    ASSERT(Thread::Current()->IsMutatorThread());
     StoreNonPointer(&raw_ptr()->guarded_cid_, cid);
   }
   static intptr_t guarded_cid_offset() {
@@ -2911,17 +2964,14 @@
   const char* GuardedPropertiesAsCString() const;
 
   intptr_t UnboxedFieldCid() const {
-    ASSERT(IsUnboxedField());
     return guarded_cid();
   }
 
-  bool IsUnboxedField() const;
-
-  bool IsPotentialUnboxedField() const;
-
   bool is_unboxing_candidate() const {
     return UnboxingCandidateBit::decode(raw_ptr()->kind_bits_);
   }
+  // Default 'true', set to false once optimizing compiler determines it should
+  // be boxed.
   void set_is_unboxing_candidate(bool b) const {
     set_kind_bits(UnboxingCandidateBit::update(b, raw_ptr()->kind_bits_));
   }
@@ -2944,6 +2994,7 @@
     return raw_ptr()->is_nullable_ == kNullCid;
   }
   void set_is_nullable(bool val) const {
+    ASSERT(Thread::Current()->IsMutatorThread());
     StoreNonPointer(&raw_ptr()->is_nullable_, val ? kNullCid : kIllegalCid);
   }
   static intptr_t is_nullable_offset() {
@@ -3089,8 +3140,8 @@
 
 class TokenStream : public Object {
  public:
-  RawArray* TokenObjects() const;
-  void SetTokenObjects(const Array& value) const;
+  RawGrowableObjectArray* TokenObjects() const;
+  void SetTokenObjects(const GrowableObjectArray& value) const;
 
   RawExternalTypedData* GetStream() const;
   void SetStream(const ExternalTypedData& stream) const;
@@ -3110,7 +3161,11 @@
 
   static RawTokenStream* New(intptr_t length);
   static RawTokenStream* New(const Scanner::GrowableTokenStream& tokens,
-                             const String& private_key);
+                             const String& private_key,
+                             bool use_shared_tokens);
+
+  static void OpenSharedTokenList(Isolate* isolate);
+  static void CloseSharedTokenList(Isolate* isolate);
 
   // The class Iterator encapsulates iteration over the tokens
   // in a TokenStream object.
@@ -3192,7 +3247,8 @@
 
   RawTokenStream* tokens() const { return raw_ptr()->tokens_; }
 
-  void Tokenize(const String& private_key) const;
+  void Tokenize(const String& private_key,
+                bool use_shared_tokens = true) const;
 
   RawLibrary* FindLibrary() const;
   RawString* GetLine(intptr_t line_number,
@@ -3388,6 +3444,10 @@
   intptr_t num_anonymous_classes() const { return raw_ptr()->num_anonymous_; }
   RawArray* anonymous_classes() const { return raw_ptr()->anonymous_classes_; }
 
+  RawGrowableObjectArray* patch_classes() const {
+    return raw_ptr()->patch_classes_;
+  }
+
   // Library imports.
   RawArray* imports() const { return raw_ptr()->imports_; }
   RawArray* exports() const { return raw_ptr()->exports_; }
@@ -3397,9 +3457,6 @@
   RawLibrary* ImportLibraryAt(intptr_t index) const;
   bool ImportsCorelib() const;
 
-  RawFunction* LookupFunctionInScript(const Script& script,
-                                      intptr_t token_pos) const;
-
   // Resolving native methods for script loaded in the library.
   Dart_NativeEntryResolver native_entry_resolver() const {
     return raw_ptr()->native_entry_resolver_;
@@ -3694,13 +3751,6 @@
  public:
   intptr_t size() const { return raw_ptr()->size_; }  // Excludes HeaderSize().
 
-  RawCode* code() const {
-    // This should only be accessed when jitting.
-    // TODO(johnmccutchan): Remove code back pointer.
-    ASSERT(!Dart::IsRunningPrecompiledCode());
-    return raw_ptr()->code_;
-  }
-
   uword EntryPoint() const {
     return reinterpret_cast<uword>(raw_ptr()) + HeaderSize();
   }
@@ -3739,10 +3789,6 @@
     StoreNonPointer(&raw_ptr()->size_, size);
   }
 
-  void set_code(RawCode* code) const {
-    StorePointer(&raw_ptr()->code_, code);
-  }
-
   // New is a private method as RawInstruction and RawCode objects should
   // only be created using the Code::FinalizeCode method. This method creates
   // the RawInstruction and RawCode objects, sets up the pointer offsets
@@ -4302,7 +4348,7 @@
                                bool optimized = false);
   static RawCode* FinalizeCode(const char* name,
                                Assembler* assembler,
-                               bool optimized = false);
+                               bool optimized);
   static RawCode* LookupCode(uword pc);
   static RawCode* LookupCodeInVmIsolate(uword pc);
   static RawCode* FindCode(uword pc, int64_t timestamp);
@@ -4347,8 +4393,9 @@
 
   void Enable() const {
     if (!IsDisabled()) return;
+    ASSERT(Thread::Current()->IsMutatorThread());
     ASSERT(instructions() != active_instructions());
-    set_active_instructions(instructions());
+    SetActiveInstructions(instructions());
   }
 
   bool IsDisabled() const {
@@ -4375,12 +4422,11 @@
   class AliveBit : public BitField<bool, kAliveBit, 1> {};
   class PtrOffBits : public BitField<intptr_t, kPtrOffBit, kPtrOffSize> {};
 
-  // An object finder visitor interface.
-  class FindRawCodeVisitor : public FindObjectVisitor {
+  class SlowFindRawCodeVisitor : public FindObjectVisitor {
    public:
-    explicit FindRawCodeVisitor(uword pc)
+    explicit SlowFindRawCodeVisitor(uword pc)
         : FindObjectVisitor(Isolate::Current()), pc_(pc) { }
-    virtual ~FindRawCodeVisitor() { }
+    virtual ~SlowFindRawCodeVisitor() { }
 
     // Check if object matches find condition.
     virtual bool FindObject(RawObject* obj) const;
@@ -4388,7 +4434,7 @@
    private:
     const uword pc_;
 
-    DISALLOW_COPY_AND_ASSIGN(FindRawCodeVisitor);
+    DISALLOW_COPY_AND_ASSIGN(SlowFindRawCodeVisitor);
   };
 
   static bool IsOptimized(RawCode* code) {
@@ -4401,16 +4447,10 @@
     StoreNonPointer(&raw_ptr()->compile_timestamp_, timestamp);
   }
 
-  void set_active_instructions(RawInstructions* instructions) const {
-    // RawInstructions are never allocated in New space and hence a
-    // store buffer update is not needed here.
-    StorePointer(&raw_ptr()->active_instructions_, instructions);
-    StoreNonPointer(&raw_ptr()->entry_point_,
-                    reinterpret_cast<uword>(instructions->ptr()) +
-                    Instructions::HeaderSize());
-  }
+  void SetActiveInstructions(RawInstructions* instructions) const;
 
   void set_instructions(RawInstructions* instructions) const {
+    ASSERT(Thread::Current()->IsMutatorThread() || !is_alive());
     StorePointer(&raw_ptr()->instructions_, instructions);
   }
 
@@ -4595,6 +4635,14 @@
   intptr_t mask() const;
   void set_mask(intptr_t mask) const;
 
+  RawString* target_name() const {
+    return raw_ptr()->target_name_;
+  }
+
+  RawArray* arguments_descriptor() const {
+    return raw_ptr()->args_descriptor_;
+  }
+
   intptr_t filled_entry_count() const;
   void set_filled_entry_count(intptr_t num) const;
 
@@ -4604,8 +4652,12 @@
   static intptr_t mask_offset() {
     return OFFSET_OF(RawMegamorphicCache, mask_);
   }
+  static intptr_t arguments_descriptor_offset() {
+    return OFFSET_OF(RawMegamorphicCache, args_descriptor_);
+  }
 
-  static RawMegamorphicCache* New();
+  static RawMegamorphicCache* New(const String& target_name,
+                                  const Array& arguments_descriptor);
 
   void EnsureCapacity() const;
 
@@ -4618,6 +4670,11 @@
  private:
   friend class Class;
 
+  static RawMegamorphicCache* New();
+
+  void set_target_name(const String& value) const;
+  void set_arguments_descriptor(const Array& value) const;
+
   enum {
     kClassIdIndex,
     kTargetFunctionIndex,
@@ -7204,7 +7261,7 @@
     return RawObject::IsTypedDataClassId(cid);
   }
 
-  static RawTypedData* EmptyUint32Array(Isolate* isolate);
+  static RawTypedData* EmptyUint32Array(Thread* thread);
 
  protected:
   void SetLength(intptr_t value) const {
@@ -7970,12 +8027,12 @@
                          Heap::Space space = Heap::kOld);
   static RawUserTag* DefaultTag();
 
-  static bool TagTableIsFull(Isolate* isolate);
+  static bool TagTableIsFull(Thread* thread);
   static RawUserTag* FindTagById(uword tag_id);
 
  private:
-  static RawUserTag* FindTagInIsolate(Isolate* isolate, const String& label);
-  static void AddTagToIsolate(Isolate* isolate, const UserTag& tag);
+  static RawUserTag* FindTagInIsolate(Thread* thread, const String& label);
+  static void AddTagToIsolate(Thread* thread, const UserTag& tag);
 
   void set_label(const String& tag_label) const {
     StorePointer(&raw_ptr()->label_, tag_label.raw());
@@ -8047,6 +8104,7 @@
 
 void Field::SetStaticValue(const Instance& value,
                            bool save_initial_value) const {
+  ASSERT(Thread::Current()->IsMutatorThread());
   ASSERT(is_static());  // Valid only for static dart fields.
   StorePointer(&raw_ptr()->value_.static_value_, value.raw());
   if (save_initial_value) {
diff --git a/runtime/vm/object_graph.cc b/runtime/vm/object_graph.cc
index 3a56dc9..2bc0d66 100644
--- a/runtime/vm/object_graph.cc
+++ b/runtime/vm/object_graph.cc
@@ -156,12 +156,12 @@
 };
 
 
-ObjectGraph::ObjectGraph(Isolate* isolate)
-    : StackResource(isolate) {
+ObjectGraph::ObjectGraph(Thread* thread)
+    : StackResource(thread) {
   // The VM isolate has all its objects pre-marked, so iterating over it
   // would be a no-op.
-  ASSERT(isolate != Dart::vm_isolate());
-  isolate->heap()->WriteProtectCode(false);
+  ASSERT(thread->isolate() != Dart::vm_isolate());
+  thread->isolate()->heap()->WriteProtectCode(false);
 }
 
 
diff --git a/runtime/vm/object_graph.h b/runtime/vm/object_graph.h
index 3163597..0a65bae 100644
--- a/runtime/vm/object_graph.h
+++ b/runtime/vm/object_graph.h
@@ -53,7 +53,7 @@
     virtual Direction VisitObject(StackIterator* it) = 0;
   };
 
-  explicit ObjectGraph(Isolate* isolate);
+  explicit ObjectGraph(Thread* thread);
   ~ObjectGraph();
 
   // Visits all strongly reachable objects in the isolate's heap, in a
diff --git a/runtime/vm/object_graph_test.cc b/runtime/vm/object_graph_test.cc
index 3e0259a..1afcc44 100644
--- a/runtime/vm/object_graph_test.cc
+++ b/runtime/vm/object_graph_test.cc
@@ -65,7 +65,7 @@
     b = Array::null();
     c = Array::null();
     d = Array::null();
-    ObjectGraph graph(isolate);
+    ObjectGraph graph(thread);
     {
       // Compare count and size when 'b' is/isn't skipped.
       CounterVisitor with(Object::null(), Object::null());
@@ -96,7 +96,7 @@
     b ^= a.At(10);
     c ^= b.At(0);
     b = Array::null();
-    ObjectGraph graph(isolate);
+    ObjectGraph graph(thread);
     // A retaining path should end like this: c <- b <- a <- ...
     {
       HANDLESCOPE(thread);
diff --git a/runtime/vm/object_store.cc b/runtime/vm/object_store.cc
index d8f2f6c..90a346e 100644
--- a/runtime/vm/object_store.cc
+++ b/runtime/vm/object_store.cc
@@ -73,8 +73,8 @@
     typed_data_library_(Library::null()),
     vmservice_library_(Library::null()),
     libraries_(GrowableObjectArray::null()),
+    closure_functions_(GrowableObjectArray::null()),
     pending_classes_(GrowableObjectArray::null()),
-    pending_functions_(GrowableObjectArray::null()),
     pending_deferred_loads_(GrowableObjectArray::null()),
     resume_capabilities_(GrowableObjectArray::null()),
     exit_listeners_(GrowableObjectArray::null()),
@@ -90,6 +90,8 @@
     handle_message_function_(Function::null()),
     library_load_error_table_(Array::null()),
     compile_time_constants_(Array::null()),
+    token_objects_(GrowableObjectArray::null()),
+    token_objects_map_(Array::null()),
     megamorphic_cache_table_(GrowableObjectArray::null()),
     megamorphic_miss_code_(Code::null()),
     megamorphic_miss_function_(Function::null()) {
@@ -130,10 +132,9 @@
   ASSERT(this->out_of_memory() == Instance::null());
   ASSERT(this->preallocated_stack_trace() == Stacktrace::null());
 
-  ASSERT(this->pending_functions() == GrowableObjectArray::null());
-  this->pending_functions_ = GrowableObjectArray::New();
   this->pending_deferred_loads_ = GrowableObjectArray::New();
 
+  this->closure_functions_ = GrowableObjectArray::New();
   this->resume_capabilities_ = GrowableObjectArray::New();
   this->exit_listeners_ = GrowableObjectArray::New();
   this->error_listeners_ = GrowableObjectArray::New();
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 805b9b1..193c847 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -332,16 +332,20 @@
     libraries_ = value.raw();
   }
 
+  RawGrowableObjectArray* closure_functions() const {
+    return closure_functions_;
+  }
+  void set_closure_functions(const GrowableObjectArray& value) {
+    ASSERT(!value.IsNull());
+    closure_functions_ = value.raw();
+  }
+
   RawGrowableObjectArray* pending_classes() const { return pending_classes_; }
   void set_pending_classes(const GrowableObjectArray& value) {
     ASSERT(!value.IsNull());
     pending_classes_ = value.raw();
   }
 
-  RawGrowableObjectArray* pending_functions() const {
-    return pending_functions_;
-  }
-
   RawGrowableObjectArray* pending_deferred_loads() const {
     return pending_deferred_loads_;
   }
@@ -363,6 +367,8 @@
 
   RawError* sticky_error() const { return sticky_error_; }
   void set_sticky_error(const Error& value) {
+    // TODO(asiva): Move sticky_error_ into thread specific area.
+    ASSERT(Thread::Current()->IsMutatorThread());
     ASSERT(!value.IsNull());
     sticky_error_ = value.raw();
   }
@@ -438,12 +444,29 @@
     compile_time_constants_ = value.raw();
   }
 
+  RawGrowableObjectArray* token_objects() const {
+    return token_objects_;
+  }
+  void set_token_objects(const GrowableObjectArray& value) {
+    token_objects_ = value.raw();
+  }
+
+  RawArray* token_objects_map() const {
+    return token_objects_map_;
+  }
+  void set_token_objects_map(const Array& value) {
+    token_objects_map_ = value.raw();
+  }
+
   RawGrowableObjectArray* megamorphic_cache_table() const {
     return megamorphic_cache_table_;
   }
   void set_megamorphic_cache_table(const GrowableObjectArray& value) {
     megamorphic_cache_table_ = value.raw();
   }
+  RawCode* megamorphic_miss_code() const {
+    return megamorphic_miss_code_;
+  }
   RawFunction* megamorphic_miss_function() const {
     return megamorphic_miss_function_;
   }
@@ -527,8 +550,8 @@
   RawLibrary* typed_data_library_;
   RawLibrary* vmservice_library_;
   RawGrowableObjectArray* libraries_;
+  RawGrowableObjectArray* closure_functions_;
   RawGrowableObjectArray* pending_classes_;
-  RawGrowableObjectArray* pending_functions_;
   RawGrowableObjectArray* pending_deferred_loads_;
   RawGrowableObjectArray* resume_capabilities_;
   RawGrowableObjectArray* exit_listeners_;
@@ -547,6 +570,8 @@
   RawObject** to_snapshot() {
     return reinterpret_cast<RawObject**>(&compile_time_constants_);
   }
+  RawGrowableObjectArray* token_objects_;
+  RawArray* token_objects_map_;
   RawGrowableObjectArray* megamorphic_cache_table_;
   RawCode* megamorphic_miss_code_;
   RawFunction* megamorphic_miss_function_;
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index e186ea0..a4b2215 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -173,7 +173,7 @@
   EXPECT_EQ(6, ts.length());
   EXPECT_EQ(Token::kLPAREN, ts[1].kind);
   const TokenStream& token_stream = TokenStream::Handle(
-      TokenStream::New(ts, private_key));
+      TokenStream::New(ts, private_key, false));
   TokenStream::Iterator iterator(token_stream, 0);
   // EXPECT_EQ(6, token_stream.Length());
   iterator.Advance();  // Advance to '(' token.
@@ -281,7 +281,8 @@
   const Array& one_fields = Array::Handle(Array::New(1));
   const String& field_name = String::Handle(Symbols::New("the_field"));
   const Field& field = Field::Handle(
-      Field::New(field_name, false, false, false, true, one_field_class, 0));
+      Field::New(field_name, false, false, false, true, one_field_class,
+                 Object::dynamic_type(), 0));
   one_fields.SetAt(0, field);
   one_field_class.SetFields(one_fields);
   one_field_class.Finalize();
@@ -2783,7 +2784,7 @@
 // Test for Embedded Smi object in the instructions.
 TEST_CASE(EmbedSmiIn64BitCode) {
   extern void GenerateEmbedSmiInCode(Assembler* assembler, intptr_t value);
-  const intptr_t kSmiTestValue = 5L << 32;
+  const intptr_t kSmiTestValue = DART_INT64_C(5) << 32;
   Assembler _assembler_;
   GenerateEmbedSmiInCode(&_assembler_, kSmiTestValue);
   const Function& function =
@@ -2961,7 +2962,8 @@
   const Class& cls = Class::Handle(CreateTestClass("global:"));
   const String& field_name = String::Handle(Symbols::New(name));
   const Field& field =
-      Field::Handle(Field::New(field_name, true, false, false, true, cls, 0));
+      Field::Handle(Field::New(field_name, true, false, false, true, cls,
+          Object::dynamic_type(), 0));
   return field.raw();
 }
 
@@ -3881,6 +3883,7 @@
   const Script& script = Script::Handle();
   const Class& cls = Class::Handle(CreateDummyClass(class_name, script));
   const Array& functions = Array::Handle(Array::New(1));
+  const Isolate* iso = Isolate::Current();
 
   Function& parent = Function::Handle();
   const String& parent_name = String::Handle(Symbols::New("foo_papa"));
@@ -3893,18 +3896,18 @@
   const String& function_name = String::Handle(Symbols::New("foo"));
   function = Function::NewClosureFunction(function_name, parent, 0);
   // Add closure function to class.
-  cls.AddClosureFunction(function);
+  iso->AddClosureFunction(function);
 
   // The closure should return a valid index.
-  intptr_t good_closure_index = cls.FindClosureIndex(function);
+  intptr_t good_closure_index = iso->FindClosureIndex(function);
   EXPECT_GE(good_closure_index, 0);
   // The parent function should return an invalid index.
-  intptr_t bad_closure_index = cls.FindClosureIndex(parent);
+  intptr_t bad_closure_index = iso->FindClosureIndex(parent);
   EXPECT_EQ(bad_closure_index, -1);
 
   // Retrieve closure function via index.
   Function& func_from_index = Function::Handle();
-  func_from_index ^= cls.ClosureFunctionFromIndex(good_closure_index);
+  func_from_index ^= iso->ClosureFunctionFromIndex(good_closure_index);
   // Same closure function.
   EXPECT_EQ(func_from_index.raw(), function.raw());
 }
@@ -4259,7 +4262,8 @@
         "\"owner\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
         "\"name\":\"bool\"},"
         "\"_kind\":\"RegularFunction\","
-        "\"static\":false,\"const\":false}",
+        "\"static\":false,\"const\":false,"
+        "\"_intrinsic\":false,\"_native\":false}",
         buffer);
   }
   // Library reference
diff --git a/runtime/vm/os_macos.cc b/runtime/vm/os_macos.cc
index aed5d33..1a338f4 100644
--- a/runtime/vm/os_macos.cc
+++ b/runtime/vm/os_macos.cc
@@ -16,7 +16,8 @@
 #include <sys/resource.h>  // NOLINT
 #include <unistd.h>  // NOLINT
 #if TARGET_OS_IOS
-#include <sys/sysctl.h>
+#include <sys/sysctl.h>  // NOLINT
+#include <syslog.h>  // NOLINT
 #endif
 
 #include "platform/utils.h"
@@ -26,7 +27,11 @@
 namespace dart {
 
 const char* OS::Name() {
+#if TARGET_OS_IOS
+  return "ios";
+#else
   return "macos";
+#endif
 }
 
 
@@ -141,9 +146,25 @@
 
 
 intptr_t OS::ActivationFrameAlignment() {
+#if TARGET_OS_IOS
+#if TARGET_ARCH_ARM
+  // Even if we generate code that maintains a stronger alignment, we cannot
+  // assert the stronger stack alignment because C++ code will not maintain it.
+  return 8;
+#elif TARGET_ARCH_ARM64
+  return 16;
+#elif TARGET_ARCH_IA32
+  return 16;  // iOS simulator
+#elif TARGET_ARCH_X64
+  return 16;  // iOS simulator
+#else
+#error Unimplemented
+#endif
+#else  // TARGET_OS_IOS
   // OS X activation frames must be 16 byte-aligned; see "Mac OS X ABI
   // Function Call Guide".
   return 16;
+#endif  // TARGET_OS_IOS
 }
 
 
@@ -224,10 +245,17 @@
 
 
 void OS::Print(const char* format, ...) {
+#if TARGET_OS_IOS
+  va_list args;
+  va_start(args, format);
+  vsyslog(LOG_INFO, format, args);
+  va_end(args);
+#else
   va_list args;
   va_start(args, format);
   VFPrint(stdout, format, args);
   va_end(args);
+#endif
 }
 
 
@@ -312,10 +340,17 @@
 
 
 void OS::PrintErr(const char* format, ...) {
+#if TARGET_OS_IOS
+  va_list args;
+  va_start(args, format);
+  vsyslog(LOG_ERR, format, args);
+  va_end(args);
+#else
   va_list args;
   va_start(args, format);
   VFPrint(stderr, format, args);
   va_end(args);
+#endif
 }
 
 
diff --git a/runtime/vm/os_thread.h b/runtime/vm/os_thread.h
index d6ae2b5..5929ef4 100644
--- a/runtime/vm/os_thread.h
+++ b/runtime/vm/os_thread.h
@@ -39,7 +39,6 @@
   // the thread failed to start.
   static int Start(ThreadStartFunction function, uword parameters);
 
-  // NOTE: Destructor currently ignored on Windows (issue 23474).
   static ThreadLocalKey CreateThreadLocal(ThreadDestructor destructor = NULL);
   static void DeleteThreadLocal(ThreadLocalKey key);
   static uword GetThreadLocal(ThreadLocalKey key) {
@@ -114,8 +113,22 @@
   void Notify();
   void NotifyAll();
 
+#if defined(DEBUG)
+  bool IsOwnedByCurrentThread() const {
+    return owner_ == OSThread::GetCurrentThreadId();
+  }
+#else
+  bool IsOwnedByCurrentThread() const {
+    UNREACHABLE();
+    return false;
+  }
+#endif
+
  private:
   MonitorData data_;  // OS-specific data.
+#if defined(DEBUG)
+  ThreadId owner_;
+#endif  // defined(DEBUG)
 
   DISALLOW_COPY_AND_ASSIGN(Monitor);
 };
diff --git a/runtime/vm/os_thread_android.cc b/runtime/vm/os_thread_android.cc
index fa87896..f1c3a44 100644
--- a/runtime/vm/os_thread_android.cc
+++ b/runtime/vm/os_thread_android.cc
@@ -216,8 +216,8 @@
   result = pthread_mutexattr_destroy(&attr);
   VALIDATE_PTHREAD_RESULT(result);
 
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we do track the owner.
   owner_ = OSThread::kInvalidThreadId;
 #endif  // defined(DEBUG)
 }
@@ -228,8 +228,8 @@
   // Verify that the pthread_mutex was destroyed.
   VALIDATE_PTHREAD_RESULT(result);
 
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we do track the owner.
   ASSERT(owner_ == OSThread::kInvalidThreadId);
 #endif  // defined(DEBUG)
 }
@@ -240,8 +240,8 @@
   // Specifically check for dead lock to help debugging.
   ASSERT(result != EDEADLK);
   ASSERT_PTHREAD_SUCCESS(result);  // Verify no other errors.
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we do track the owner.
   owner_ = OSThread::GetCurrentThreadId();
 #endif  // defined(DEBUG)
 }
@@ -254,8 +254,8 @@
     return false;
   }
   ASSERT_PTHREAD_SUCCESS(result);  // Verify no other errors.
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we do track the owner.
   owner_ = OSThread::GetCurrentThreadId();
 #endif  // defined(DEBUG)
   return true;
@@ -263,8 +263,8 @@
 
 
 void Mutex::Unlock() {
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we do track the owner.
   ASSERT(IsOwnedByCurrentThread());
   owner_ = OSThread::kInvalidThreadId;
 #endif  // defined(DEBUG)
@@ -300,10 +300,20 @@
 
   result = pthread_condattr_destroy(&cond_attr);
   VALIDATE_PTHREAD_RESULT(result);
+
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  owner_ = OSThread::kInvalidThreadId;
+#endif  // defined(DEBUG)
 }
 
 
 Monitor::~Monitor() {
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(owner_ == OSThread::kInvalidThreadId);
+#endif  // defined(DEBUG)
+
   int result = pthread_mutex_destroy(data_.mutex());
   VALIDATE_PTHREAD_RESULT(result);
 
@@ -315,12 +325,22 @@
 void Monitor::Enter() {
   int result = pthread_mutex_lock(data_.mutex());
   VALIDATE_PTHREAD_RESULT(result);
-  // TODO(iposva): Do we need to track lock owners?
+
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(owner_ == OSThread::kInvalidThreadId);
+  owner_ = OSThread::GetCurrentThreadId();
+#endif  // defined(DEBUG)
 }
 
 
 void Monitor::Exit() {
-  // TODO(iposva): Do we need to track lock owners?
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
+  owner_ = OSThread::kInvalidThreadId;
+#endif  // defined(DEBUG)
+
   int result = pthread_mutex_unlock(data_.mutex());
   VALIDATE_PTHREAD_RESULT(result);
 }
@@ -332,7 +352,13 @@
 
 
 Monitor::WaitResult Monitor::WaitMicros(int64_t micros) {
-  // TODO(iposva): Do we need to track lock owners?
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
+  ThreadId saved_owner = owner_;
+  owner_ = OSThread::kInvalidThreadId;
+#endif  // defined(DEBUG)
+
   Monitor::WaitResult retval = kNotified;
   if (micros == kNoTimeout) {
     // Wait forever.
@@ -347,19 +373,28 @@
       retval = kTimedOut;
     }
   }
+
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(owner_ == OSThread::kInvalidThreadId);
+  owner_ = OSThread::GetCurrentThreadId();
+  ASSERT(owner_ == saved_owner);
+#endif  // defined(DEBUG)
   return retval;
 }
 
 
 void Monitor::Notify() {
-  // TODO(iposva): Do we need to track lock owners?
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
   int result = pthread_cond_signal(data_.cond());
   VALIDATE_PTHREAD_RESULT(result);
 }
 
 
 void Monitor::NotifyAll() {
-  // TODO(iposva): Do we need to track lock owners?
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
   int result = pthread_cond_broadcast(data_.cond());
   VALIDATE_PTHREAD_RESULT(result);
 }
diff --git a/runtime/vm/os_thread_linux.cc b/runtime/vm/os_thread_linux.cc
index 9fb0b23..f48b6b0 100644
--- a/runtime/vm/os_thread_linux.cc
+++ b/runtime/vm/os_thread_linux.cc
@@ -16,12 +16,24 @@
 
 namespace dart {
 
+static char* strerror_helper(int err, char* buffer, size_t bufsize) {
+#if !defined(__GLIBC__) || \
+    ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE)
+  // Use the standard version
+  return strerror_r(err, buffer, bufsize) == 0 ?
+    buffer : const_cast<char*>("strerror_r failed");
+#else
+  // Use the gnu specific version
+  return strerror_r(err, buffer, bufsize);
+#endif
+}
+
 #define VALIDATE_PTHREAD_RESULT(result) \
   if (result != 0) { \
     const int kBufferSize = 1024; \
     char error_buf[kBufferSize]; \
     FATAL2("pthread error: %d (%s)", result, \
-           strerror_r(result, error_buf, kBufferSize)); \
+           strerror_helper(result, error_buf, kBufferSize)); \
   }
 
 
@@ -40,7 +52,7 @@
     char error_buf[kBufferSize]; \
     fprintf(stderr, "%s:%d: pthread error: %d (%s)\n", \
             __FILE__, __LINE__, result, \
-            strerror_r(result, error_buf, kBufferSize)); \
+            strerror_helper(result, error_buf, kBufferSize)); \
     return result; \
   }
 #else
@@ -218,8 +230,8 @@
   result = pthread_mutexattr_destroy(&attr);
   VALIDATE_PTHREAD_RESULT(result);
 
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
   owner_ = OSThread::kInvalidThreadId;
 #endif  // defined(DEBUG)
 }
@@ -230,8 +242,8 @@
   // Verify that the pthread_mutex was destroyed.
   VALIDATE_PTHREAD_RESULT(result);
 
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
   ASSERT(owner_ == OSThread::kInvalidThreadId);
 #endif  // defined(DEBUG)
 }
@@ -242,8 +254,8 @@
   // Specifically check for dead lock to help debugging.
   ASSERT(result != EDEADLK);
   ASSERT_PTHREAD_SUCCESS(result);  // Verify no other errors.
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
   owner_ = OSThread::GetCurrentThreadId();
 #endif  // defined(DEBUG)
 }
@@ -256,8 +268,8 @@
     return false;
   }
   ASSERT_PTHREAD_SUCCESS(result);  // Verify no other errors.
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
   owner_ = OSThread::GetCurrentThreadId();
 #endif  // defined(DEBUG)
   return true;
@@ -265,8 +277,8 @@
 
 
 void Mutex::Unlock() {
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
   ASSERT(IsOwnedByCurrentThread());
   owner_ = OSThread::kInvalidThreadId;
 #endif  // defined(DEBUG)
@@ -305,10 +317,20 @@
 
   result = pthread_condattr_destroy(&cond_attr);
   VALIDATE_PTHREAD_RESULT(result);
+
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  owner_ = OSThread::kInvalidThreadId;
+#endif  // defined(DEBUG)
 }
 
 
 Monitor::~Monitor() {
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(owner_ == OSThread::kInvalidThreadId);
+#endif  // defined(DEBUG)
+
   int result = pthread_mutex_destroy(data_.mutex());
   VALIDATE_PTHREAD_RESULT(result);
 
@@ -320,24 +342,41 @@
 void Monitor::Enter() {
   int result = pthread_mutex_lock(data_.mutex());
   VALIDATE_PTHREAD_RESULT(result);
-  // TODO(iposva): Do we need to track lock owners?
+
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(owner_ == OSThread::kInvalidThreadId);
+  owner_ = OSThread::GetCurrentThreadId();
+#endif  // defined(DEBUG)
 }
 
 
 void Monitor::Exit() {
-  // TODO(iposva): Do we need to track lock owners?
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
+  owner_ = OSThread::kInvalidThreadId;
+#endif  // defined(DEBUG)
+
   int result = pthread_mutex_unlock(data_.mutex());
   VALIDATE_PTHREAD_RESULT(result);
 }
 
 
 Monitor::WaitResult Monitor::Wait(int64_t millis) {
-  return WaitMicros(millis * kMicrosecondsPerMillisecond);
+  Monitor::WaitResult retval = WaitMicros(millis * kMicrosecondsPerMillisecond);
+  return retval;
 }
 
 
 Monitor::WaitResult Monitor::WaitMicros(int64_t micros) {
-  // TODO(iposva): Do we need to track lock owners?
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
+  ThreadId saved_owner = owner_;
+  owner_ = OSThread::kInvalidThreadId;
+#endif  // defined(DEBUG)
+
   Monitor::WaitResult retval = kNotified;
   if (micros == kNoTimeout) {
     // Wait forever.
@@ -352,19 +391,28 @@
       retval = kTimedOut;
     }
   }
+
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(owner_ == OSThread::kInvalidThreadId);
+  owner_ = OSThread::GetCurrentThreadId();
+  ASSERT(owner_ == saved_owner);
+#endif  // defined(DEBUG)
   return retval;
 }
 
 
 void Monitor::Notify() {
-  // TODO(iposva): Do we need to track lock owners?
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
   int result = pthread_cond_signal(data_.cond());
   VALIDATE_PTHREAD_RESULT(result);
 }
 
 
 void Monitor::NotifyAll() {
-  // TODO(iposva): Do we need to track lock owners?
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
   int result = pthread_cond_broadcast(data_.cond());
   VALIDATE_PTHREAD_RESULT(result);
 }
diff --git a/runtime/vm/os_thread_macos.cc b/runtime/vm/os_thread_macos.cc
index e7c7c90..851a467 100644
--- a/runtime/vm/os_thread_macos.cc
+++ b/runtime/vm/os_thread_macos.cc
@@ -223,8 +223,8 @@
   result = pthread_mutexattr_destroy(&attr);
   VALIDATE_PTHREAD_RESULT(result);
 
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we do track the owner.
   owner_ = OSThread::kInvalidThreadId;
 #endif  // defined(DEBUG)
 }
@@ -235,8 +235,8 @@
   // Verify that the pthread_mutex was destroyed.
   VALIDATE_PTHREAD_RESULT(result);
 
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we do track the owner.
   ASSERT(owner_ == OSThread::kInvalidThreadId);
 #endif  // defined(DEBUG)
 }
@@ -247,8 +247,8 @@
   // Specifically check for dead lock to help debugging.
   ASSERT(result != EDEADLK);
   ASSERT_PTHREAD_SUCCESS(result);  // Verify no other errors.
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we do track the owner.
   owner_ = OSThread::GetCurrentThreadId();
 #endif  // defined(DEBUG)
 }
@@ -261,8 +261,8 @@
     return false;
   }
   ASSERT_PTHREAD_SUCCESS(result);  // Verify no other errors.
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we do track the owner.
   owner_ = OSThread::GetCurrentThreadId();
 #endif  // defined(DEBUG)
   return true;
@@ -270,8 +270,8 @@
 
 
 void Mutex::Unlock() {
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we do track the owner.
   ASSERT(IsOwnedByCurrentThread());
   owner_ = OSThread::kInvalidThreadId;
 #endif  // defined(DEBUG)
@@ -300,10 +300,20 @@
 
   result = pthread_cond_init(data_.cond(), NULL);
   VALIDATE_PTHREAD_RESULT(result);
+
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  owner_ = OSThread::kInvalidThreadId;
+#endif  // defined(DEBUG)
 }
 
 
 Monitor::~Monitor() {
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(owner_ == OSThread::kInvalidThreadId);
+#endif  // defined(DEBUG)
+
   int result = pthread_mutex_destroy(data_.mutex());
   VALIDATE_PTHREAD_RESULT(result);
 
@@ -315,12 +325,22 @@
 void Monitor::Enter() {
   int result = pthread_mutex_lock(data_.mutex());
   VALIDATE_PTHREAD_RESULT(result);
-  // TODO(iposva): Do we need to track lock owners?
+
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(owner_ == OSThread::kInvalidThreadId);
+  owner_ = OSThread::GetCurrentThreadId();
+#endif  // defined(DEBUG)
 }
 
 
 void Monitor::Exit() {
-  // TODO(iposva): Do we need to track lock owners?
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
+  owner_ = OSThread::kInvalidThreadId;
+#endif  // defined(DEBUG)
+
   int result = pthread_mutex_unlock(data_.mutex());
   VALIDATE_PTHREAD_RESULT(result);
 }
@@ -332,7 +352,13 @@
 
 
 Monitor::WaitResult Monitor::WaitMicros(int64_t micros) {
-  // TODO(iposva): Do we need to track lock owners?
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
+  ThreadId saved_owner = owner_;
+  owner_ = OSThread::kInvalidThreadId;
+#endif  // defined(DEBUG)
+
   Monitor::WaitResult retval = kNotified;
   if (micros == kNoTimeout) {
     // Wait forever.
@@ -357,19 +383,28 @@
       retval = kTimedOut;
     }
   }
+
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(owner_ == OSThread::kInvalidThreadId);
+  owner_ = OSThread::GetCurrentThreadId();
+  ASSERT(owner_ == saved_owner);
+#endif  // defined(DEBUG)
   return retval;
 }
 
 
 void Monitor::Notify() {
-  // TODO(iposva): Do we need to track lock owners?
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
   int result = pthread_cond_signal(data_.cond());
   VALIDATE_PTHREAD_RESULT(result);
 }
 
 
 void Monitor::NotifyAll() {
-  // TODO(iposva): Do we need to track lock owners?
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
   int result = pthread_cond_broadcast(data_.cond());
   VALIDATE_PTHREAD_RESULT(result);
 }
diff --git a/runtime/vm/os_thread_win.cc b/runtime/vm/os_thread_win.cc
index a71d4b6..fd8de38 100644
--- a/runtime/vm/os_thread_win.cc
+++ b/runtime/vm/os_thread_win.cc
@@ -5,6 +5,7 @@
 #include "platform/globals.h"  // NOLINT
 #if defined(TARGET_OS_WINDOWS)
 
+#include "vm/growable_array.h"
 #include "vm/os_thread.h"
 
 #include <process.h>  // NOLINT
@@ -13,6 +14,10 @@
 
 namespace dart {
 
+// This flag is flipped by platform_win.cc when the process is exiting.
+// TODO(zra): Remove once VM shuts down cleanly.
+bool private_flag_windows_run_tls_destructors = true;
+
 class ThreadStartData {
  public:
   ThreadStartData(OSThread::ThreadStartFunction function, uword parameter)
@@ -73,11 +78,12 @@
 ThreadId OSThread::kInvalidThreadId = 0;
 ThreadJoinId OSThread::kInvalidThreadJoinId = 0;
 
-ThreadLocalKey OSThread::CreateThreadLocal(ThreadDestructor unused) {
+ThreadLocalKey OSThread::CreateThreadLocal(ThreadDestructor destructor) {
   ThreadLocalKey key = TlsAlloc();
   if (key == kUnsetThreadLocalKey) {
     FATAL1("TlsAlloc failed %d", GetLastError());
   }
+  ThreadLocalData::AddThreadLocal(key, destructor);
   return key;
 }
 
@@ -88,6 +94,7 @@
   if (!result) {
     FATAL1("TlsFree failed %d", GetLastError());
   }
+  ThreadLocalData::RemoveThreadLocal(key);
 }
 
 
@@ -195,8 +202,8 @@
   if (data_.semaphore_ == NULL) {
     FATAL1("Mutex allocation failed %d", GetLastError());
   }
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we do track the owner.
   owner_ = OSThread::kInvalidThreadId;
 #endif  // defined(DEBUG)
 }
@@ -204,8 +211,8 @@
 
 Mutex::~Mutex() {
   CloseHandle(data_.semaphore_);
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we do track the owner.
   ASSERT(owner_ == OSThread::kInvalidThreadId);
 #endif  // defined(DEBUG)
 }
@@ -216,8 +223,8 @@
   if (result != WAIT_OBJECT_0) {
     FATAL1("Mutex lock failed %d", GetLastError());
   }
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we do track the owner.
   owner_ = OSThread::GetCurrentThreadId();
 #endif  // defined(DEBUG)
 }
@@ -227,8 +234,8 @@
   // Attempt to pass the semaphore but return immediately.
   DWORD result = WaitForSingleObject(data_.semaphore_, 0);
   if (result == WAIT_OBJECT_0) {
-    // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+    // When running with assertions enabled we do track the owner.
     owner_ = OSThread::GetCurrentThreadId();
 #endif  // defined(DEBUG)
     return true;
@@ -242,8 +249,8 @@
 
 
 void Mutex::Unlock() {
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we do track the owner.
   ASSERT(IsOwnedByCurrentThread());
   owner_ = OSThread::kInvalidThreadId;
 #endif  // defined(DEBUG)
@@ -263,10 +270,20 @@
   InitializeCriticalSection(&data_.waiters_cs_);
   data_.waiters_head_ = NULL;
   data_.waiters_tail_ = NULL;
+
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  owner_ = OSThread::kInvalidThreadId;
+#endif  // defined(DEBUG)
 }
 
 
 Monitor::~Monitor() {
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(owner_ == OSThread::kInvalidThreadId);
+#endif  // defined(DEBUG)
+
   DeleteCriticalSection(&data_.cs_);
   DeleteCriticalSection(&data_.waiters_cs_);
 }
@@ -274,10 +291,22 @@
 
 void Monitor::Enter() {
   EnterCriticalSection(&data_.cs_);
+
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(owner_ == OSThread::kInvalidThreadId);
+  owner_ = OSThread::GetCurrentThreadId();
+#endif  // defined(DEBUG)
 }
 
 
 void Monitor::Exit() {
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
+  owner_ = OSThread::kInvalidThreadId;
+#endif  // defined(DEBUG)
+
   LeaveCriticalSection(&data_.cs_);
 }
 
@@ -287,6 +316,8 @@
       OSThread::kUnsetThreadLocalKey) {
     uword raw_wait_data =
       OSThread::GetThreadLocal(MonitorWaitData::monitor_wait_data_key_);
+    // Clear in case this is called a second time.
+    OSThread::SetThreadLocal(MonitorWaitData::monitor_wait_data_key_, 0);
     if (raw_wait_data != 0) {
       MonitorWaitData* wait_data =
           reinterpret_cast<MonitorWaitData*>(raw_wait_data);
@@ -402,7 +433,7 @@
     HANDLE event = CreateEvent(NULL, FALSE, FALSE, NULL);
     wait_data = new MonitorWaitData(event);
     OSThread::SetThreadLocal(MonitorWaitData::monitor_wait_data_key_,
-                           reinterpret_cast<uword>(wait_data));
+                             reinterpret_cast<uword>(wait_data));
   } else {
     wait_data = reinterpret_cast<MonitorWaitData*>(raw_wait_data);
     wait_data->next_ = NULL;
@@ -412,6 +443,13 @@
 
 
 Monitor::WaitResult Monitor::Wait(int64_t millis) {
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
+  ThreadId saved_owner = owner_;
+  owner_ = OSThread::kInvalidThreadId;
+#endif  // defined(DEBUG)
+
   Monitor::WaitResult retval = kNotified;
 
   // Get the wait data object containing the event to wait for.
@@ -449,6 +487,12 @@
   // Reacquire the monitor critical section before continuing.
   EnterCriticalSection(&data_.cs_);
 
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(owner_ == OSThread::kInvalidThreadId);
+  owner_ = OSThread::GetCurrentThreadId();
+  ASSERT(owner_ == saved_owner);
+#endif  // defined(DEBUG)
   return retval;
 }
 
@@ -467,11 +511,15 @@
 
 
 void Monitor::Notify() {
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
   data_.SignalAndRemoveFirstWaiter();
 }
 
 
 void Monitor::NotifyAll() {
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
   // If one of the objects in the list of waiters wakes because of a
   // timeout before we signal it, that object will get an extra
   // signal. This will be treated as a spurious wake-up and is OK
@@ -480,6 +528,166 @@
   data_.SignalAndRemoveAllWaiters();
 }
 
+
+void ThreadLocalData::AddThreadLocal(ThreadLocalKey key,
+                                     ThreadDestructor destructor) {
+  ASSERT(thread_locals_ != NULL);
+  if (destructor == NULL) {
+    // We only care about thread locals with destructors.
+    return;
+  }
+  mutex_->Lock();
+#if defined(DEBUG)
+  // Verify that we aren't added twice.
+  for (intptr_t i = 0; i < thread_locals_->length(); i++) {
+    const ThreadLocalEntry& entry = thread_locals_->At(i);
+    ASSERT(entry.key() != key);
+  }
+#endif
+  // Add to list.
+  thread_locals_->Add(ThreadLocalEntry(key, destructor));
+  mutex_->Unlock();
+}
+
+
+void ThreadLocalData::RemoveThreadLocal(ThreadLocalKey key) {
+  ASSERT(thread_locals_ != NULL);  mutex_->Lock();
+  intptr_t i = 0;
+  for (; i < thread_locals_->length(); i++) {
+    const ThreadLocalEntry& entry = thread_locals_->At(i);
+    if (entry.key() == key) {
+      break;
+    }
+  }
+  if (i == thread_locals_->length()) {
+    // Not found.
+    mutex_->Unlock();
+    return;
+  }
+  thread_locals_->RemoveAt(i);
+  mutex_->Unlock();
+}
+
+
+// This function is executed on the thread that is exiting. It is invoked
+// by |OnDartThreadExit| (see below for notes on TLS destructors on Windows).
+void ThreadLocalData::RunDestructors() {
+  ASSERT(thread_locals_ != NULL);
+  ASSERT(mutex_ != NULL);
+  mutex_->Lock();
+  for (intptr_t i = 0; i < thread_locals_->length(); i++) {
+    const ThreadLocalEntry& entry = thread_locals_->At(i);
+    // We access the exiting thread's TLS variable here.
+    void* p = reinterpret_cast<void*>(OSThread::GetThreadLocal(entry.key()));
+    // We invoke the constructor here.
+    entry.destructor()(p);
+  }
+  mutex_->Unlock();
+}
+
+
+Mutex* ThreadLocalData::mutex_ = NULL;
+MallocGrowableArray<ThreadLocalEntry>* ThreadLocalData::thread_locals_ = NULL;
+
+
+void ThreadLocalData::InitOnce() {
+  mutex_ = new Mutex();
+  thread_locals_ = new MallocGrowableArray<ThreadLocalEntry>();
+}
+
+
+void ThreadLocalData::Shutdown() {
+  if (mutex_ != NULL) {
+    delete mutex_;
+    mutex_ = NULL;
+  }
+  if (thread_locals_ != NULL) {
+    delete thread_locals_;
+    thread_locals_ = NULL;
+  }
+}
+
+
 }  // namespace dart
 
+// The following was adapted from Chromium:
+// src/base/threading/thread_local_storage_win.cc
+
+// Thread Termination Callbacks.
+// Windows doesn't support a per-thread destructor with its
+// TLS primitives.  So, we build it manually by inserting a
+// function to be called on each thread's exit.
+// This magic is from http://www.codeproject.com/threads/tls.asp
+// and it works for VC++ 7.0 and later.
+
+// Force a reference to _tls_used to make the linker create the TLS directory
+// if it's not already there.  (e.g. if __declspec(thread) is not used).
+// Force a reference to p_thread_callback_dart to prevent whole program
+// optimization from discarding the variable.
+#ifdef _WIN64
+
+#pragma comment(linker, "/INCLUDE:_tls_used")
+#pragma comment(linker, "/INCLUDE:p_thread_callback_dart")
+
+#else  // _WIN64
+
+#pragma comment(linker, "/INCLUDE:__tls_used")
+#pragma comment(linker, "/INCLUDE:_p_thread_callback_dart")
+
+#endif  // _WIN64
+
+// Static callback function to call with each thread termination.
+void NTAPI OnDartThreadExit(PVOID module, DWORD reason, PVOID reserved) {
+  if (!dart::private_flag_windows_run_tls_destructors) {
+    return;
+  }
+  // On XP SP0 & SP1, the DLL_PROCESS_ATTACH is never seen. It is sent on SP2+
+  // and on W2K and W2K3. So don't assume it is sent.
+  if (DLL_THREAD_DETACH == reason || DLL_PROCESS_DETACH == reason) {
+    dart::ThreadLocalData::RunDestructors();
+    dart::MonitorWaitData::ThreadExit();
+  }
+}
+
+// .CRT$XLA to .CRT$XLZ is an array of PIMAGE_TLS_CALLBACK pointers that are
+// called automatically by the OS loader code (not the CRT) when the module is
+// loaded and on thread creation. They are NOT called if the module has been
+// loaded by a LoadLibrary() call. It must have implicitly been loaded at
+// process startup.
+// By implicitly loaded, I mean that it is directly referenced by the main EXE
+// or by one of its dependent DLLs. Delay-loaded DLL doesn't count as being
+// implicitly loaded.
+//
+// See VC\crt\src\tlssup.c for reference.
+
+// extern "C" suppresses C++ name mangling so we know the symbol name for the
+// linker /INCLUDE:symbol pragma above.
+extern "C" {
+// The linker must not discard p_thread_callback_dart.  (We force a reference
+// to this variable with a linker /INCLUDE:symbol pragma to ensure that.) If
+// this variable is discarded, the OnDartThreadExit function will never be
+// called.
+#ifdef _WIN64
+
+// .CRT section is merged with .rdata on x64 so it must be constant data.
+#pragma const_seg(".CRT$XLB")
+// When defining a const variable, it must have external linkage to be sure the
+// linker doesn't discard it.
+extern const PIMAGE_TLS_CALLBACK p_thread_callback_dart;
+const PIMAGE_TLS_CALLBACK p_thread_callback_dart = OnDartThreadExit;
+
+// Reset the default section.
+#pragma const_seg()
+
+#else  // _WIN64
+
+#pragma data_seg(".CRT$XLB")
+PIMAGE_TLS_CALLBACK p_thread_callback_dart = OnDartThreadExit;
+
+// Reset the default section.
+#pragma data_seg()
+
+#endif  // _WIN64
+}  // extern "C"
+
 #endif  // defined(TARGET_OS_WINDOWS)
diff --git a/runtime/vm/os_thread_win.h b/runtime/vm/os_thread_win.h
index 5dc9b18..5398182 100644
--- a/runtime/vm/os_thread_win.h
+++ b/runtime/vm/os_thread_win.h
@@ -12,6 +12,8 @@
 #include "platform/assert.h"
 #include "platform/globals.h"
 
+#include "vm/allocation.h"
+
 namespace dart {
 
 typedef DWORD ThreadLocalKey;
@@ -116,6 +118,56 @@
   DISALLOW_COPY_AND_ASSIGN(MonitorData);
 };
 
+
+typedef void (*ThreadDestructor) (void* parameter);
+
+
+class ThreadLocalEntry {
+ public:
+  ThreadLocalEntry(ThreadLocalKey key, ThreadDestructor destructor)
+      : key_(key),
+        destructor_(destructor) {
+  }
+
+  ThreadLocalKey key() const {
+    return key_;
+  }
+
+
+  ThreadDestructor destructor() const {
+    return destructor_;
+  }
+
+ private:
+  ThreadLocalKey key_;
+  ThreadDestructor destructor_;
+
+  DISALLOW_ALLOCATION();
+};
+
+
+template<typename T>
+class MallocGrowableArray;
+
+
+class ThreadLocalData : public AllStatic {
+ public:
+  static void RunDestructors();
+
+ private:
+  static void AddThreadLocal(ThreadLocalKey key, ThreadDestructor destructor);
+  static void RemoveThreadLocal(ThreadLocalKey key);
+
+  static Mutex* mutex_;
+  static MallocGrowableArray<ThreadLocalEntry>* thread_locals_;
+
+  static void InitOnce();
+  static void Shutdown();
+
+  friend class OS;
+  friend class OSThread;
+};
+
 }  // namespace dart
 
 #endif  // VM_OS_THREAD_WIN_H_
diff --git a/runtime/vm/os_win.cc b/runtime/vm/os_win.cc
index 0e07cdf..5af6c71 100644
--- a/runtime/vm/os_win.cc
+++ b/runtime/vm/os_win.cc
@@ -368,6 +368,7 @@
   init_once_called = true;
   // Do not pop up a message box when abort is called.
   _set_abort_behavior(0, _WRITE_ABORT_MSG);
+  ThreadLocalData::InitOnce();
   MonitorWaitData::monitor_wait_data_key_ = OSThread::CreateThreadLocal();
   MonitorData::GetMonitorWaitDataForThread();
   LARGE_INTEGER ticks_per_sec;
@@ -380,6 +381,8 @@
 
 
 void OS::Shutdown() {
+  // TODO(zra): Enable once VM can shutdown cleanly.
+  // ThreadLocalData::Shutdown();
 }
 
 
diff --git a/runtime/vm/pages.cc b/runtime/vm/pages.cc
index da7ec80..6dc7e93 100644
--- a/runtime/vm/pages.cc
+++ b/runtime/vm/pages.cc
@@ -657,13 +657,15 @@
 }
 
 
-void PageSpace::WriteProtect(bool read_only) {
+void PageSpace::WriteProtect(bool read_only, bool include_code_pages) {
   if (read_only) {
     // Avoid MakeIterable trying to write to the heap.
     AbandonBumpAllocation();
   }
   for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) {
-    it.page()->WriteProtect(read_only);
+    if ((it.page()->type() != HeapPage::kExecutable) || include_code_pages) {
+      it.page()->WriteProtect(read_only);
+    }
   }
 }
 
diff --git a/runtime/vm/pages.h b/runtime/vm/pages.h
index 39ef84e..17d1674 100644
--- a/runtime/vm/pages.h
+++ b/runtime/vm/pages.h
@@ -284,7 +284,7 @@
 
   // Note: Code pages are made executable/non-executable when 'read_only' is
   // true/false, respectively.
-  void WriteProtect(bool read_only);
+  void WriteProtect(bool read_only, bool include_code_pages);
   void WriteProtectCode(bool read_only);
 
   void AddGCTime(int64_t micros) {
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index ec199ea..c3fb3fe 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -384,7 +384,7 @@
 Parser::~Parser() {
   if (unregister_pending_function_) {
     const GrowableObjectArray& pending_functions =
-        GrowableObjectArray::Handle(I->object_store()->pending_functions());
+        GrowableObjectArray::Handle(T->pending_functions());
     ASSERT(pending_functions.Length() > 0);
     ASSERT(pending_functions.At(pending_functions.Length()-1) ==
         current_function().raw());
@@ -558,10 +558,9 @@
   }
 
   void EraseParameterTypes() {
-    const Type& dynamic_type = Type::ZoneHandle(Type::DynamicType());
     const int num_parameters = parameters->length();
     for (int i = 0; i < num_parameters; i++) {
-      (*parameters)[i].type = &dynamic_type;
+      (*parameters)[i].type = &Object::dynamic_type();
     }
   }
 
@@ -1430,8 +1429,10 @@
   }
 
   if (func.HasOptionalNamedParameters()) {
+    // TODO(srdjan): Must allocate array in old space, since it
+    // runs in background compiler. Find a better way.
     const Array& arg_names =
-        Array::ZoneHandle(Array::New(func.NumOptionalParameters()));
+        Array::ZoneHandle(Array::New(func.NumOptionalParameters(), Heap::kOld));
     for (intptr_t i = 0; i < arg_names.Length(); ++i) {
       intptr_t index = func.num_fixed_parameters() + i;
       arg_names.SetAt(i, String::Handle(func.ParameterNameAt(index)));
@@ -1447,7 +1448,6 @@
 
 SequenceNode* Parser::ParseMethodExtractor(const Function& func) {
   TRACE_PARSER("ParseMethodExtractor");
-  ASSERT(FLAG_lazy_dispatchers);
 
   ParamList params;
 
@@ -2932,8 +2932,7 @@
 
 void Parser::CheckRecursiveInvocation() {
   const GrowableObjectArray& pending_functions =
-      GrowableObjectArray::Handle(Z,
-          I->object_store()->pending_functions());
+      GrowableObjectArray::Handle(Z, T->pending_functions());
   for (int i = 0; i < pending_functions.Length(); i++) {
     if (pending_functions.At(i) == current_function().raw()) {
       const String& fname =
@@ -3826,6 +3825,7 @@
   }
 
   intptr_t method_end_pos = TokenPos();
+  String* native_name = NULL;
   if ((CurrentToken() == Token::kLBRACE) ||
       (CurrentToken() == Token::kARROW)) {
     if (method->has_abstract) {
@@ -3881,7 +3881,7 @@
       ReportError(method->name_pos,
                   "Constructor with redirection may not have a function body");
     }
-    ParseNativeDeclaration();
+    native_name = &ParseNativeDeclaration();
     method_end_pos = TokenPos();
     ExpectSemicolon();
     method->has_native = true;
@@ -3959,6 +3959,9 @@
   if (method->metadata_pos > 0) {
     library_.AddFunctionMetadata(func, method->metadata_pos);
   }
+  if (method->has_native) {
+    func.set_native_name(*native_name);
+  }
 
   // If this method is a redirecting factory, set the redirection information.
   if (!redirection_type.IsNull()) {
@@ -4048,8 +4051,8 @@
                              field->has_const,
                              is_reflectable,
                              current_class(),
+                             *field->type,
                              field->name_pos);
-    class_field.set_type(*field->type);
     class_field.set_has_initializer(has_initializer);
     members->AddField(class_field);
     field->field_ = &class_field;
@@ -4635,7 +4638,7 @@
     // The patched class must not be finalized yet.
     const Class& orig_class = Class::Cast(obj);
     ASSERT(!orig_class.is_finalized());
-    orig_class.set_patch_class(cls);
+    orig_class.SetPatchClass(cls);
     cls.set_is_patch();
   }
   pending_classes.Add(cls, Heap::kOld);
@@ -4717,21 +4720,20 @@
   SkipMetadata();
   ExpectToken(Token::kENUM);
 
-  const String& enum_name = String::Handle(Z, cls.Name());
+  const String& enum_name = String::Handle(Z, cls.PrettyName());
   ClassDesc enum_members(Z, cls, enum_name, false, cls.token_pos());
 
   // Add instance field 'final int index'.
   Field& index_field = Field::ZoneHandle(Z);
   const Type& int_type = Type::Handle(Z, Type::IntType());
-  const Type& dynamic_type = Type::Handle(Type::DynamicType());
   index_field = Field::New(Symbols::Index(),
                            false,  // Not static.
                            true,  // Field is final.
                            false,  // Not const.
                            true,  // Is reflectable.
                            cls,
+                           int_type,
                            cls.token_pos());
-  index_field.set_type(int_type);
   enum_members.AddField(index_field);
 
   // Add implicit getter for index field.
@@ -4750,7 +4752,7 @@
   getter.set_result_type(int_type);
   getter.set_is_debuggable(false);
   ParamList params;
-  params.AddReceiver(&dynamic_type, cls.token_pos());
+  params.AddReceiver(&Object::dynamic_type(), cls.token_pos());
   AddFormalParamsToFunction(&params, getter);
   enum_members.AddFunction(getter);
 
@@ -4802,8 +4804,8 @@
                             /* is_const = */ true,
                             /* is_reflectable = */ true,
                             cls,
+                            Object::dynamic_type(),
                             cls.token_pos());
-    enum_value.set_type(dynamic_type);
     enum_value.set_has_initializer(false);
     enum_members.AddField(enum_value);
     // Initialize the field with the ordinal value. It will be patched
@@ -4840,8 +4842,8 @@
                             /* is_const = */ true,
                             /* is_reflectable = */ true,
                             cls,
+                            Type::Handle(Z, Type::ArrayType()),
                             cls.token_pos());
-  values_field.set_type(Type::Handle(Z, Type::ArrayType()));
   enum_members.AddField(values_field);
 
   // Allocate the immutable array containing the enumeration values.
@@ -5449,8 +5451,7 @@
     const bool is_reflectable =
         !(library_.is_dart_scheme() && library_.IsPrivate(var_name));
     field = Field::New(var_name, is_static, is_final, is_const, is_reflectable,
-                       current_class(), name_pos);
-    field.set_type(type);
+                       current_class(), type, name_pos);
     field.SetStaticValue(Object::null_instance(), true);
     top_level->AddField(field);
     library_.AddObject(field, var_name);
@@ -5587,6 +5588,7 @@
 
   intptr_t function_end_pos = function_pos;
   bool is_native = false;
+  String* native_name = NULL;
   if (is_external) {
     function_end_pos = TokenPos();
     ExpectSemicolon();
@@ -5606,7 +5608,7 @@
     function_end_pos = TokenPos();
     ExpectSemicolon();
   } else if (IsSymbol(Symbols::Native())) {
-    ParseNativeDeclaration();
+    native_name = &ParseNativeDeclaration();
     function_end_pos = TokenPos();
     ExpectSemicolon();
     is_native = true;
@@ -5629,6 +5631,9 @@
   if (library_.is_dart_scheme() && library_.IsPrivate(func_name)) {
     func.set_is_reflectable(false);
   }
+  if (is_native) {
+    func.set_native_name(*native_name);
+  }
   AddFormalParamsToFunction(&params, func);
   top_level->AddFunction(func);
   if (!is_patch) {
@@ -5737,6 +5742,7 @@
 
   intptr_t accessor_end_pos = accessor_pos;
   bool is_native = false;
+  String* native_name = NULL;
   if (is_external) {
     accessor_end_pos = TokenPos();
     ExpectSemicolon();
@@ -5756,7 +5762,7 @@
     accessor_end_pos = TokenPos();
     ExpectSemicolon();
   } else if (IsSymbol(Symbols::Native())) {
-    ParseNativeDeclaration();
+    native_name = &ParseNativeDeclaration();
     accessor_end_pos = TokenPos();
     ExpectSemicolon();
     is_native = true;
@@ -5779,6 +5785,7 @@
   func.set_modifier(func_modifier);
   if (is_native) {
     func.set_is_debuggable(false);
+    func.set_native_name(*native_name);
   }
   if (library_.is_dart_scheme() && library_.IsPrivate(accessor_name)) {
     func.set_is_reflectable(false);
@@ -5812,7 +5819,7 @@
   // Block class finalization attempts when calling into the library
   // tag handler.
   I->BlockClassFinalization();
-  Api::Scope api_scope(I);
+  Api::Scope api_scope(T);
   Dart_Handle result = handler(tag,
                                Api::NewHandle(I, library_.raw()),
                                Api::NewHandle(I, url.raw()));
@@ -6239,15 +6246,13 @@
   OpenBlock();  // Catch block.
 
   // Add the exception and stack trace parameters to the scope.
-  const AbstractType& dynamic_type =
-      AbstractType::ZoneHandle(Z, Type::DynamicType());
   CatchParamDesc exception_param;
   CatchParamDesc stack_trace_param;
   exception_param.token_pos = Scanner::kNoSourcePos;
-  exception_param.type = &dynamic_type;
+  exception_param.type = &Object::dynamic_type();
   exception_param.name = &Symbols::ExceptionParameter();
   stack_trace_param.token_pos = Scanner::kNoSourcePos;
-  stack_trace_param.type = &dynamic_type;
+  stack_trace_param.type = &Object::dynamic_type();
   stack_trace_param.name = &Symbols::StackTraceParameter();
 
   AddCatchParamsToScope(
@@ -6369,7 +6374,8 @@
 
   const GrowableObjectArray& handler_types =
       GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld));
-  handler_types.Add(dynamic_type);  // Catch block handles all exceptions.
+  // Catch block handles all exceptions.
+  handler_types.Add(Object::dynamic_type());
 
   CatchClauseNode* catch_clause = new(Z) CatchClauseNode(
       Scanner::kNoSourcePos,
@@ -6408,15 +6414,13 @@
 
   OpenBlock();  // Catch handler list.
   OpenBlock();  // Catch block.
-  const AbstractType& dynamic_type =
-      AbstractType::ZoneHandle(Z, Type::DynamicType());
   CatchParamDesc exception_param;
   CatchParamDesc stack_trace_param;
   exception_param.token_pos = Scanner::kNoSourcePos;
-  exception_param.type = &dynamic_type;
+  exception_param.type = &Object::dynamic_type();
   exception_param.name = &Symbols::ExceptionParameter();
   stack_trace_param.token_pos = Scanner::kNoSourcePos;
-  stack_trace_param.type = &dynamic_type;
+  stack_trace_param.type = &Object::dynamic_type();
   stack_trace_param.name = &Symbols::StackTraceParameter();
 
   AddCatchParamsToScope(
@@ -6546,14 +6550,14 @@
   // Create the parameter list for the body closure of a sync generator:
   // 1) Implicit closure parameter;
   // 2) Iterator
-  const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
   // Add implicit closure parameter if not already present.
   if (params->parameters->length() == 0) {
-    params->AddFinalParameter(0, &Symbols::ClosureParameter(), &dynamic_type);
+    params->AddFinalParameter(
+        0, &Symbols::ClosureParameter(), &Object::dynamic_type());
   }
   ParamDesc iterator_param;
   iterator_param.name = &Symbols::IteratorParameter();
-  iterator_param.type = &dynamic_type;
+  iterator_param.type = &Object::dynamic_type();
   params->parameters->Add(iterator_param);
   params->num_fixed_parameters++;
 }
@@ -6577,11 +6581,8 @@
   // function has already been created by a previous
   // compilation.
   const Function& found_func = Function::Handle(
-      Z, current_class().LookupClosureFunction(func_pos));
-  if (!found_func.IsNull() &&
-      (found_func.token_pos() == func_pos) &&
-      (found_func.script() == innermost_function().script()) &&
-      (found_func.parent_function() == innermost_function().raw())) {
+      Z, I->LookupClosureFunction(innermost_function(), func_pos));
+  if (!found_func.IsNull()) {
     ASSERT(found_func.IsSyncGenClosure());
     body = found_func.raw();
     body_closure_name = body.name();
@@ -6589,7 +6590,7 @@
     // Create the closure containing the body of this generator function.
     String& generator_name = String::Handle(Z, innermost_function().name());
     body_closure_name =
-        String::NewFormatted("<%s_sync_body>", generator_name.ToCString());
+        Symbols::NewFormatted("<%s_sync_body>", generator_name.ToCString());
     body_closure_name = Symbols::New(body_closure_name);
     body = Function::NewClosureFunction(body_closure_name,
                                         innermost_function(),
@@ -6681,26 +6682,26 @@
   // * A continuation result.
   // * A continuation error.
   // * A continuation stack trace.
-  const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
   ASSERT(params->parameters->length() <= 1);
   // Add implicit closure parameter if not yet present.
   if (params->parameters->length() == 0) {
-    params->AddFinalParameter(0, &Symbols::ClosureParameter(), &dynamic_type);
+    params->AddFinalParameter(
+        0, &Symbols::ClosureParameter(), &Object::dynamic_type());
   }
   ParamDesc result_param;
   result_param.name = &Symbols::AsyncOperationParam();
   result_param.default_value = &Object::null_instance();
-  result_param.type = &dynamic_type;
+  result_param.type = &Object::dynamic_type();
   params->parameters->Add(result_param);
   ParamDesc error_param;
   error_param.name = &Symbols::AsyncOperationErrorParam();
   error_param.default_value = &Object::null_instance();
-  error_param.type = &dynamic_type;
+  error_param.type = &Object::dynamic_type();
   params->parameters->Add(error_param);
   ParamDesc stack_trace_param;
   stack_trace_param.name = &Symbols::AsyncOperationStackTraceParam();
   stack_trace_param.default_value = &Object::null_instance();
-  stack_trace_param.type = &dynamic_type;
+  stack_trace_param.type = &Object::dynamic_type();
   params->parameters->Add(stack_trace_param);
   params->has_optional_positional_parameters = true;
   params->num_optional_parameters += 3;
@@ -6718,11 +6719,8 @@
   // this async function has already been created by a previous
   // compilation of this function.
   const Function& found_func = Function::Handle(
-      Z, current_class().LookupClosureFunction(async_func_pos));
-  if (!found_func.IsNull() &&
-      (found_func.token_pos() == async_func_pos) &&
-      (found_func.script() == innermost_function().script()) &&
-      (found_func.parent_function() == innermost_function().raw())) {
+      Z, I->LookupClosureFunction(innermost_function(), async_func_pos));
+  if (!found_func.IsNull()) {
     ASSERT(found_func.IsAsyncClosure());
     closure = found_func.raw();
   } else {
@@ -6774,12 +6772,13 @@
   // Add to current block's scope:
   //   var :await_jump_var;
   //   var :await_ctx_var;
-  const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
   LocalVariable* await_jump_var = new (Z) LocalVariable(
-      Scanner::kNoSourcePos, Symbols::AwaitJumpVar(), dynamic_type);
+      Scanner::kNoSourcePos, Symbols::AwaitJumpVar(), Object::dynamic_type());
   current_block_->scope->AddVariable(await_jump_var);
   LocalVariable* await_ctx_var = new (Z) LocalVariable(
-      Scanner::kNoSourcePos, Symbols::AwaitContextVar(), dynamic_type);
+      Scanner::kNoSourcePos,
+      Symbols::AwaitContextVar(),
+      Object::dynamic_type());
   current_block_->scope->AddVariable(await_ctx_var);
 }
 
@@ -6790,18 +6789,23 @@
   //   var :async_then_callback;
   //   var :async_catch_error_callback;
   //   var :async_completer;
-  const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
   LocalVariable* async_op_var = new(Z) LocalVariable(
-      Scanner::kNoSourcePos, Symbols::AsyncOperation(), dynamic_type);
+      Scanner::kNoSourcePos, Symbols::AsyncOperation(), Object::dynamic_type());
   current_block_->scope->AddVariable(async_op_var);
   LocalVariable* async_then_callback_var = new(Z) LocalVariable(
-      Scanner::kNoSourcePos, Symbols::AsyncThenCallback(), dynamic_type);
+      Scanner::kNoSourcePos,
+      Symbols::AsyncThenCallback(),
+      Object::dynamic_type());
   current_block_->scope->AddVariable(async_then_callback_var);
   LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable(
-      Scanner::kNoSourcePos, Symbols::AsyncCatchErrorCallback(), dynamic_type);
+      Scanner::kNoSourcePos,
+      Symbols::AsyncCatchErrorCallback(),
+      Object::dynamic_type());
   current_block_->scope->AddVariable(async_catch_error_callback_var);
   LocalVariable* async_completer = new(Z) LocalVariable(
-      Scanner::kNoSourcePos, Symbols::AsyncCompleter(), dynamic_type);
+      Scanner::kNoSourcePos,
+      Symbols::AsyncCompleter(),
+      Object::dynamic_type());
   current_block_->scope->AddVariable(async_completer);
 }
 
@@ -6817,18 +6821,21 @@
   //   var :async_catch_error_callback;
   // These variables are used to store the async generator closure containing
   // the body of the async* function. They are used by the await operator.
-  const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
   LocalVariable* controller_var = new(Z) LocalVariable(
-      Scanner::kNoSourcePos, Symbols::Controller(), dynamic_type);
+      Scanner::kNoSourcePos, Symbols::Controller(), Object::dynamic_type());
   current_block_->scope->AddVariable(controller_var);
   LocalVariable* async_op_var = new(Z) LocalVariable(
-      Scanner::kNoSourcePos, Symbols::AsyncOperation(), dynamic_type);
+      Scanner::kNoSourcePos, Symbols::AsyncOperation(), Object::dynamic_type());
   current_block_->scope->AddVariable(async_op_var);
   LocalVariable* async_then_callback_var = new(Z) LocalVariable(
-      Scanner::kNoSourcePos, Symbols::AsyncThenCallback(), dynamic_type);
+      Scanner::kNoSourcePos,
+      Symbols::AsyncThenCallback(),
+      Object::dynamic_type());
   current_block_->scope->AddVariable(async_then_callback_var);
   LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable(
-      Scanner::kNoSourcePos, Symbols::AsyncCatchErrorCallback(), dynamic_type);
+      Scanner::kNoSourcePos,
+      Symbols::AsyncCatchErrorCallback(),
+      Object::dynamic_type());
   current_block_->scope->AddVariable(async_catch_error_callback_var);
 }
 
@@ -6845,11 +6852,8 @@
   // this async generator has already been created by a previous
   // compilation of this function.
   const Function& found_func = Function::Handle(
-      Z, current_class().LookupClosureFunction(async_func_pos));
-  if (!found_func.IsNull() &&
-      (found_func.token_pos() == async_func_pos) &&
-      (found_func.script() == innermost_function().script()) &&
-      (found_func.parent_function() == innermost_function().raw())) {
+      Z, I->LookupClosureFunction(innermost_function(), async_func_pos));
+  if (!found_func.IsNull()) {
     ASSERT(found_func.IsAsyncGenClosure());
     closure = found_func.raw();
   } else {
@@ -6857,8 +6861,8 @@
     const String& async_generator_name =
         String::Handle(Z, innermost_function().name());
     String& closure_name = String::Handle(Z,
-        String::NewFormatted("<%s_async_gen_body>",
-                             async_generator_name.ToCString()));
+        Symbols::NewFormatted("<%s_async_gen_body>",
+                              async_generator_name.ToCString()));
     closure = Function::NewClosureFunction(
         String::Handle(Z, Symbols::New(closure_name)),
         innermost_function(),
@@ -7335,39 +7339,20 @@
 void Parser::ParseNativeFunctionBlock(const ParamList* params,
                                       const Function& func) {
   ASSERT(func.is_native());
-  TRACE_PARSER("ParseNativeFunctionBlock");
-  const Class& cls = Class::Handle(Z, func.Owner());
-  const Library& library = Library::Handle(Z, cls.library());
   ASSERT(func.NumParameters() == params->parameters->length());
+  TRACE_PARSER("ParseNativeFunctionBlock");
 
   // Parse the function name out.
-  const intptr_t native_pos = TokenPos();
   const String& native_name = ParseNativeDeclaration();
 
-  // Now resolve the native function to the corresponding native entrypoint.
-  const int num_params = NativeArguments::ParameterCountForResolution(func);
-  bool auto_setup_scope = true;
-  NativeFunction native_function = NativeEntry::ResolveNative(
-      library, native_name, num_params, &auto_setup_scope);
-  if (native_function == NULL) {
-    ReportError(native_pos,
-                "native function '%s' (%" Pd " arguments) cannot be found",
-                native_name.ToCString(), func.NumParameters());
-  }
-  func.SetIsNativeAutoSetupScope(auto_setup_scope);
-
   // Now add the NativeBodyNode and return statement.
-  Dart_NativeEntryResolver resolver = library.native_entry_resolver();
-  bool is_bootstrap_native = Bootstrap::IsBootstapResolver(resolver);
   current_block_->statements->Add(new(Z) ReturnNode(
       TokenPos(),
       new(Z) NativeBodyNode(
           TokenPos(),
           Function::ZoneHandle(Z, func.raw()),
           native_name,
-          native_function,
           current_block_->scope,
-          is_bootstrap_native,
           FLAG_link_natives_lazily)));
 }
 
@@ -7635,9 +7620,8 @@
   // TODO(hausner): There could be two different closures at the given
   // function_pos, one enclosed in a closurized function and one enclosed in the
   // non-closurized version of this same function.
-  function = current_class().LookupClosureFunction(function_pos);
-  if (function.IsNull() || (function.token_pos() != function_pos) ||
-      (function.parent_function() != innermost_function().raw())) {
+  function = I->LookupClosureFunction(innermost_function(), function_pos);
+  if (function.IsNull()) {
     // The function will be registered in the lookup table by the
     // EffectGraphVisitor::VisitClosureNode when the newly allocated closure
     // function has been properly setup.
@@ -8863,9 +8847,9 @@
   // Create the try-statement and add to the current sequence, which is
   // the block around the loop statement.
 
-  const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
   const Array& handler_types = Array::ZoneHandle(Z, Array::New(1, Heap::kOld));
-  handler_types.SetAt(0, dynamic_type);  // Catch block handles all exceptions.
+  // Catch block handles all exceptions.
+  handler_types.SetAt(0, Object::dynamic_type());
 
   CatchClauseNode* catch_clause = new(Z) CatchClauseNode(await_for_pos,
       catch_block,
@@ -9586,14 +9570,13 @@
                                      LocalVariable** stack_trace_var,
                                      LocalVariable** saved_exception_var,
                                      LocalVariable** saved_stack_trace_var) {
-  const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
   // Consecutive try statements share the same set of variables.
   *context_var = try_scope->LocalLookupVariable(Symbols::SavedTryContextVar());
   if (*context_var == NULL) {
     *context_var = new(Z) LocalVariable(
         TokenPos(),
         Symbols::SavedTryContextVar(),
-        dynamic_type);
+        Object::dynamic_type());
     try_scope->AddVariable(*context_var);
   }
   *exception_var = try_scope->LocalLookupVariable(Symbols::ExceptionVar());
@@ -9601,7 +9584,7 @@
     *exception_var = new(Z) LocalVariable(
         TokenPos(),
         Symbols::ExceptionVar(),
-        dynamic_type);
+        Object::dynamic_type());
     try_scope->AddVariable(*exception_var);
   }
   *stack_trace_var = try_scope->LocalLookupVariable(Symbols::StackTraceVar());
@@ -9609,7 +9592,7 @@
     *stack_trace_var = new(Z) LocalVariable(
         TokenPos(),
         Symbols::StackTraceVar(),
-        dynamic_type);
+        Object::dynamic_type());
     try_scope->AddVariable(*stack_trace_var);
   }
   if (is_async) {
@@ -9619,7 +9602,7 @@
       *saved_exception_var = new(Z) LocalVariable(
           TokenPos(),
           Symbols::SavedExceptionVar(),
-          dynamic_type);
+          Object::dynamic_type());
       try_scope->AddVariable(*saved_exception_var);
     }
     *saved_stack_trace_var = try_scope->LocalLookupVariable(
@@ -9628,7 +9611,7 @@
       *saved_stack_trace_var = new(Z) LocalVariable(
           TokenPos(),
           Symbols::SavedStackTraceVar(),
-          dynamic_type);
+          Object::dynamic_type());
       try_scope->AddVariable(*saved_stack_trace_var);
     }
   }
@@ -10565,6 +10548,25 @@
       }
     }
   }
+  if (binary_op == Token::kIFNULL) {
+    // Handle a ?? b.
+    LetNode* result = new(Z) LetNode(op_pos);
+    LocalVariable* left_temp = result->AddInitializer(lhs);
+    const intptr_t no_pos = Scanner::kNoSourcePos;
+    LiteralNode* null_operand =
+        new(Z) LiteralNode(no_pos, Instance::ZoneHandle(Z));
+    LoadLocalNode* load_left_temp = new(Z) LoadLocalNode(no_pos, left_temp);
+    ComparisonNode* null_compare =
+        new(Z) ComparisonNode(no_pos,
+                              Token::kNE_STRICT,
+                              load_left_temp,
+                              null_operand);
+    result->AddNode(new(Z) ConditionalExprNode(op_pos,
+                                               null_compare,
+                                               load_left_temp,
+                                               rhs));
+    return result;
+  }
   return new(Z) BinaryOpNode(op_pos, binary_op, lhs, rhs);
 }
 
@@ -10736,10 +10738,10 @@
                              ifnull->right(),
                              left_ident,
                              left_pos);
-    result = new(Z) BinaryOpNode(rhs->token_pos(),
-                                 Token::kIFNULL,
-                                 ifnull->left(),
-                                 modified_assign);
+    result = OptimizeBinaryOpNode(ifnull->token_pos(),
+                                  ifnull->kind(),
+                                  ifnull->left(),
+                                  modified_assign);
   }
   return result;
 }
@@ -11251,7 +11253,8 @@
     // NoSuchMethodError to be thrown.
     // In an instance method, we convert this into a getter call
     // for a field (which may be defined in a subclass.)
-    String& name = String::CheckedZoneHandle(primary->primary().raw());
+    const String& name =
+        String::Cast(Object::ZoneHandle(primary->primary().raw()));
     if (current_function().is_static() ||
         current_function().IsInFactoryScope()) {
       StaticGetterNode* getter = new(Z) StaticGetterNode(
@@ -11273,7 +11276,7 @@
 AstNode* Parser::LoadClosure(PrimaryNode* primary) {
   ASSERT(primary->primary().IsFunction());
   const Function& func =
-      Function::CheckedZoneHandle(primary->primary().raw());
+      Function::Cast(Object::ZoneHandle(primary->primary().raw()));
   const String& funcname = String::ZoneHandle(Z, func.name());
   if (func.is_static()) {
     // Static function access.
@@ -11462,8 +11465,8 @@
           if (primary_node->IsSuper()) {
             ReportError(primary_pos, "illegal use of super");
           }
-          String& name =
-              String::CheckedZoneHandle(primary_node->primary().raw());
+          const String& name =
+              String::Cast(Object::ZoneHandle(primary_node->primary().raw()));
           if (current_function().is_static()) {
             // The static call will be converted to throwing a NSM error.
             selector = ParseStaticCall(current_class(), name, primary_pos);
@@ -11906,30 +11909,65 @@
   return current_class().NumTypeParameters() > 0;
 }
 
+// We cache computed compile-time constants in a map so we can look them
+// up when the same code gets compiled again. The map key is a pair
+// (script url, token position) which is encoded in an array with 2
+// elements:
+// - key[0] contains the canonicalized url of the script.
+// - key[1] contains the token position of the constant in the script.
+
+// ConstantPosKey allows us to look up a constant in the map without
+// allocating a key pair (array).
+struct ConstantPosKey : ValueObject {
+  ConstantPosKey(const String& url, intptr_t pos)
+      : script_url(url), token_pos(pos) { }
+  const String& script_url;
+  intptr_t token_pos;
+};
+
 
 class ConstMapKeyEqualsTraits {
  public:
   static bool IsMatch(const Object& a, const Object& b) {
-    return String::Cast(a).Equals(String::Cast(b));
+    const Array& key1 = Array::Cast(a);
+    const Array& key2 = Array::Cast(b);
+    // Compare raw strings of script url symbol and raw smi of token positon.
+    return (key1.At(0) == key2.At(0)) && (key1.At(1) == key2.At(1));
   }
-  static bool IsMatch(const char* key, const Object& b) {
-    return String::Cast(b).Equals(key);
+  static bool IsMatch(const ConstantPosKey& key1, const Object& b) {
+    const Array& key2 = Array::Cast(b);
+    // Compare raw strings of script url symbol and token positon.
+    return (key1.script_url.raw() == key2.At(0))
+        && (key1.token_pos == Smi::Value(Smi::RawCast(key2.At(1))));
   }
   static uword Hash(const Object& obj) {
-    return String::Cast(obj).Hash();
+    const Array& key = Array::Cast(obj);
+    intptr_t url_hash = String::HashRawSymbol(String::RawCast(key.At(0)));
+    intptr_t pos = Smi::Value(Smi::RawCast(key.At(1)));
+    return HashValue(url_hash, pos);
   }
-  static uword Hash(const char* key) {
-    return String::Hash(key, strlen(key));
+  static uword Hash(const ConstantPosKey& key) {
+    return HashValue(String::HashRawSymbol(key.script_url.raw()),
+                     key.token_pos);
+  }
+  // Used by CachConstantValue if a new constant is added to the map.
+  static RawObject* NewKey(const ConstantPosKey& key) {
+    const Array& key_obj = Array::Handle(Array::New(2));
+    key_obj.SetAt(0, key.script_url);
+    key_obj.SetAt(1, Smi::Handle(Smi::New(key.token_pos)));
+    return key_obj.raw();;
+  }
+
+ private:
+  static uword HashValue(intptr_t url_hash, intptr_t pos) {
+    return url_hash * pos % (Smi::kMaxValue - 13);
   }
 };
 typedef UnorderedHashMap<ConstMapKeyEqualsTraits> ConstantsMap;
 
 
 void Parser::CacheConstantValue(intptr_t token_pos, const Instance& value) {
-  String& key = String::Handle(Z, script_.url());
-  String& suffix =
-      String::Handle(Z, String::NewFormatted("_%" Pd "", token_pos));
-  key = Symbols::FromConcat(key, suffix);
+  ConstantPosKey key(String::Handle(Z, script_.url()), token_pos);
   if (isolate()->object_store()->compile_time_constants() == Array::null()) {
     const intptr_t kInitialConstMapSize = 16;
     isolate()->object_store()->set_compile_time_constants(
@@ -11937,7 +11975,7 @@
                                                        Heap::kNew)));
   }
   ConstantsMap constants(isolate()->object_store()->compile_time_constants());
-  constants.UpdateOrInsert(key, value);
+  constants.InsertNewOrGetValue(key, value);
   if (FLAG_compiler_stats) {
     isolate_->compiler_stats()->num_cached_consts = constants.NumOccupied();
   }
@@ -11949,17 +11987,7 @@
   if (isolate()->object_store()->compile_time_constants() == Array::null()) {
     return false;
   }
-  // We don't want to allocate anything in the heap here since this code
-  // is called from the optimizing compiler in the background thread. Allocate
-  // the key value in the zone instead.
-  // const char* key = Z->PrintToString("%s_%" Pd "",
-  //     String::Handle(Z, script_.url()).ToCString(),
-  //    token_pos);
-
-  const String& key = String::Handle(Z,
-      Symbols::NewFormatted("%s_%" Pd "",
-          String::Handle(Z, script_.url()).ToCString(),
-          token_pos));
+  ConstantPosKey key(String::Handle(Z, script_.url()), token_pos);
   ConstantsMap constants(isolate()->object_store()->compile_time_constants());
   bool is_present = false;
   *value ^= constants.GetOrNull(key, &is_present);
@@ -13093,7 +13121,7 @@
                                                      intptr_t token_pos) {
   ASSERT(ctr.kind() == RawFunction::kConstructor);
   Function& closure = Function::Handle(Z);
-  closure = current_class().LookupClosureFunction(token_pos);
+  closure = I->LookupClosureFunction(innermost_function(), token_pos);
   if (!closure.IsNull()) {
     ASSERT(closure.IsConstructorClosureFunction());
     return closure.raw();
diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc
index f061da0..56e4ffc 100644
--- a/runtime/vm/precompiler.cc
+++ b/runtime/vm/precompiler.cc
@@ -17,6 +17,7 @@
 namespace dart {
 
 
+#define T (thread())
 #define I (isolate())
 #define Z (zone())
 
@@ -59,31 +60,55 @@
     libraries_(GrowableObjectArray::Handle(Z, I->object_store()->libraries())),
     pending_functions_(
         GrowableObjectArray::Handle(Z, GrowableObjectArray::New())),
-    collected_closures_(
-        GrowableObjectArray::Handle(Z, GrowableObjectArray::New())),
     sent_selectors_(),
+    enqueued_functions_(),
     error_(Error::Handle(Z)) {
-  I->set_collected_closures(collected_closures_);
 }
 
 
 void Precompiler::DoCompileAll(
     Dart_QualifiedFunctionName embedder_entry_points[]) {
-  // Drop all existing code so we can use the presence of code as an indicator
-  // that we have already looked for the function's callees.
-  ClearAllCode();
+  ASSERT(I->compilation_allowed());
 
-  // Start with the allocations and invocations that happen from C++.
-  AddRoots(embedder_entry_points);
+  // Make sure class hierarchy is stable before compilation so that CHA
+  // can be used. Also ensures lookup of entry points won't miss functions
+  // because their class hasn't been finalized yet.
+  FinalizeAllClasses();
 
-  // TODO(rmacnak): Eagerly add field-invocation functions to all signature
-  // classes so closure calls don't go through the runtime.
+  const intptr_t kPrecompilerRounds = 1;
+  for (intptr_t round = 0; round < kPrecompilerRounds; round++) {
+    if (FLAG_trace_precompiler) {
+      OS::Print("Precompiler round %" Pd "\n", round);
+    }
 
-  // Compile newly found targets and add their callees until we reach a fixed
-  // point.
-  Iterate();
+    if (round > 0) {
+      ResetPrecompilerState();
+    }
 
-  CleanUp();
+    // TODO(rmacnak): We should be able to do a more thorough job and drop some
+    //  - implicit static closures
+    //  - field initializers
+    //  - invoke-field-dispatchers
+    //  - method-extractors
+    // that are needed in early iterations but optimized away in later
+    // iterations.
+    ClearAllCode();
+
+    // Start with the allocations and invocations that happen from C++.
+    AddRoots(embedder_entry_points);
+
+    // Compile newly found targets and add their callees until we reach a fixed
+    // point.
+    Iterate();
+  }
+
+  DropUncompiledFunctions();
+
+  // TODO(rmacnak): DropEmptyClasses();
+
+  BindStaticCalls();
+
+  DedupStackmaps();
 
   if (FLAG_trace_precompiler) {
     THR_Print("Precompiled %" Pd " functions, %" Pd " dynamic types,"
@@ -142,13 +167,19 @@
     kTypedDataUint16ArrayCid,
     kTypedDataUint32ArrayCid,
     kTypedDataUint64ArrayCid,
-
     kTypedDataInt8ArrayCid,
     kTypedDataInt16ArrayCid,
     kTypedDataInt32ArrayCid,
     kTypedDataInt64ArrayCid,
 
     kExternalTypedDataUint8ArrayCid,
+    kExternalTypedDataUint16ArrayCid,
+    kExternalTypedDataUint32ArrayCid,
+    kExternalTypedDataUint64ArrayCid,
+    kExternalTypedDataInt8ArrayCid,
+    kExternalTypedDataInt16ArrayCid,
+    kExternalTypedDataInt32ArrayCid,
+    kExternalTypedDataInt64ArrayCid,
 
     kTypedDataFloat32ArrayCid,
     kTypedDataFloat64ArrayCid,
@@ -181,11 +212,12 @@
   Class& cls = Class::Handle(Z);
   for (intptr_t i = 0; kExternallyAllocatedCids[i] != kIllegalCid; i++) {
     cls = isolate()->class_table()->At(kExternallyAllocatedCids[i]);
-    AddClass(cls);
+    AddInstantiatedClass(cls);
   }
 
   Dart_QualifiedFunctionName vm_entry_points[] = {
     { "dart:async", "::", "_setScheduleImmediateClosure" },
+    { "dart:core", "::", "_completeDeferredLoads"},
     { "dart:core", "AbstractClassInstantiationError",
                    "AbstractClassInstantiationError._create" },
     { "dart:core", "ArgumentError", "ArgumentError." },
@@ -217,8 +249,13 @@
     { "dart:isolate", "::", "_startMainIsolate" },
     { "dart:isolate", "_RawReceivePortImpl", "_handleMessage" },
     { "dart:isolate", "_RawReceivePortImpl", "_lookupHandler" },
-    { "dart:vmservice", "::", "_registerIsolate" },
-    { "dart:vmservice", "::", "boot" },
+    { "dart:isolate", "_SendPortImpl", "send" },
+    { "dart:typed_data", "ByteData", "ByteData." },
+    { "dart:typed_data", "ByteData", "ByteData._view" },
+    { "dart:typed_data", "_ByteBuffer", "_ByteBuffer._New" },
+    { "dart:_vmservice", "::", "_registerIsolate" },
+    { "dart:_vmservice", "::", "boot" },
+    { "dart:developer", "Metrics", "_printMetrics" },
     { NULL, NULL, NULL }  // Must be terminated with NULL entries.
   };
 
@@ -276,6 +313,13 @@
     }
 
     AddFunction(func);
+    if (func.IsGenerativeConstructor()) {
+      // Allocation stubs are referenced from the call site of the constructor,
+      // not in the constructor itself. So compiling the constructor isn't
+      // enough for us to discover the class is instantiated if the class isn't
+      // otherwise instantiated from Dart code and only instantiated from C++.
+      AddInstantiatedClass(cls);
+    }
   }
 }
 
@@ -292,30 +336,10 @@
     }
 
     CheckForNewDynamicFunctions();
-
-    // Drain collected_closures last because additions to this list come from
-    // outside the Precompiler and so do not flip our changed_ flag.
-    while (collected_closures_.Length() > 0) {
-      function ^= collected_closures_.RemoveLast();
-      ProcessFunction(function);
-    }
   }
 }
 
 
-void Precompiler::CleanUp() {
-  I->set_collected_closures(GrowableObjectArray::Handle(Z));
-
-  DropUncompiledFunctions();
-
-  // TODO(rmacnak): DropEmptyClasses();
-
-  BindStaticCalls();
-
-  DedupStackmaps();
-}
-
-
 void Precompiler::ProcessFunction(const Function& function) {
   if (!function.HasCode()) {
     function_count_++;
@@ -335,6 +359,15 @@
     if (!error_.IsNull()) {
       Jump(error_);
     }
+  } else {
+    if (FLAG_trace_precompiler) {
+      // This function was compiled from somewhere other than Precompiler,
+      // such as const constructors compiled by the parser.
+      THR_Print("Already has code: %s (%" Pd ", %s)\n",
+                function.ToLibNamePrefixedQualifiedCString(),
+                function.token_pos(),
+                Function::KindToCString(function.kind()));
+    }
   }
 
   ASSERT(function.HasCode());
@@ -364,9 +397,12 @@
 
   const ObjectPool& pool = ObjectPool::Handle(Z, code.GetObjectPool());
   ICData& call_site = ICData::Handle(Z);
+  MegamorphicCache& cache = MegamorphicCache::Handle(Z);
   String& selector = String::Handle(Z);
   Field& field = Field::Handle(Z);
   Class& cls = Class::Handle(Z);
+  Instance& instance = Instance::Handle(Z);
+  Code& target_code = Code::Handle(Z);
   for (intptr_t i = 0; i < pool.Length(); i++) {
     if (pool.InfoAt(i) == ObjectPool::kTaggedObject) {
       entry = pool.ObjectAt(i);
@@ -391,20 +427,81 @@
             AddClosureCall(call_site);
           }
         }
+      } else if (entry.IsMegamorphicCache()) {
+        // A dynamic call.
+        cache ^= entry.raw();
+        selector = cache.target_name();
+        AddSelector(selector);
       } else if (entry.IsField()) {
         // Potential need for field initializer.
         field ^= entry.raw();
         AddField(field);
       } else if (entry.IsInstance()) {
-        // Potential const object.
-        cls = entry.clazz();
-        AddClass(cls);
+        // Const object, literal or args descriptor.
+        instance ^= entry.raw();
+        AddConstObject(instance);
+      } else if (entry.IsFunction()) {
+        // Local closure function.
+        target ^= entry.raw();
+        AddFunction(target);
+      } else if (entry.IsCode()) {
+        target_code ^= entry.raw();
+        if (target_code.IsAllocationStubCode()) {
+          cls ^= target_code.owner();
+          AddInstantiatedClass(cls);
+        }
       }
     }
   }
 }
 
 
+void Precompiler::AddConstObject(const Instance& instance) {
+  const Class& cls = Class::Handle(Z, instance.clazz());
+  AddInstantiatedClass(cls);
+
+  if (instance.IsClosure()) {
+    // An implicit static closure.
+    const Function& func = Function::Handle(Z, Closure::function(instance));
+    ASSERT(func.is_static());
+    AddFunction(func);
+    return;
+  }
+
+  // Can't ask immediate objects if they're canoncial.
+  if (instance.IsSmi()) return;
+
+  // Some Instances in the ObjectPool aren't const objects, such as
+  // argument descriptors.
+  if (!instance.IsCanonical()) return;
+
+  class ConstObjectVisitor : public ObjectPointerVisitor {
+   public:
+    ConstObjectVisitor(Precompiler* precompiler, Isolate* isolate) :
+        ObjectPointerVisitor(isolate),
+        precompiler_(precompiler),
+        subinstance_(Object::Handle()) {}
+
+    virtual void VisitPointers(RawObject** first, RawObject** last) {
+      for (RawObject** current = first; current <= last; current++) {
+        subinstance_ = *current;
+        if (subinstance_.IsInstance()) {
+          precompiler_->AddConstObject(Instance::Cast(subinstance_));
+        }
+      }
+      subinstance_ = Object::null();
+    }
+
+   private:
+    Precompiler* precompiler_;
+    Object& subinstance_;
+  };
+
+  ConstObjectVisitor visitor(this, I);
+  instance.raw()->VisitPointers(&visitor);
+}
+
+
 void Precompiler::AddClosureCall(const ICData& call_site) {
   const Array& arguments_descriptor =
       Array::Handle(Z, call_site.arguments_descriptor());
@@ -423,11 +520,10 @@
 
 void Precompiler::AddField(const Field& field) {
   if (field.is_static()) {
-    // Potential const object. Uninitialized field will harmlessly do a
-    // redundant add of the Null class.
     const Object& value = Object::Handle(Z, field.StaticValue());
-    const Class& cls = Class::Handle(Z, value.clazz());
-    AddClass(cls);
+    if (value.IsInstance()) {
+      AddConstObject(Instance::Cast(value));
+    }
 
     if (field.has_initializer()) {
       // Should not be in the middle of initialization while precompiling.
@@ -436,14 +532,14 @@
       const bool is_initialized = value.raw() != Object::sentinel().raw();
       if (is_initialized && !reset_fields_) return;
 
-      if (field.HasPrecompiledInitializer()) return;
-
-      if (FLAG_trace_precompiler) {
-        THR_Print("Precompiling initializer for %s\n", field.ToCString());
+      if (!field.HasPrecompiledInitializer()) {
+        if (FLAG_trace_precompiler) {
+          THR_Print("Precompiling initializer for %s\n", field.ToCString());
+        }
+        ASSERT(!Dart::IsRunningPrecompiledCode());
+        field.SetStaticValue(Instance::Handle(field.SavedInitialStaticValue()));
+        Compiler::CompileStaticInitializer(field);
       }
-      ASSERT(!Dart::IsRunningPrecompiledCode());
-      field.SetStaticValue(Instance::Handle(field.SavedInitialStaticValue()));
-      Compiler::CompileStaticInitializer(field);
 
       const Function& function =
           Function::Handle(Z, field.PrecompiledInitializer());
@@ -454,8 +550,9 @@
 
 
 void Precompiler::AddFunction(const Function& function) {
-  if (function.HasCode()) return;
+  if (enqueued_functions_.Lookup(&function) != NULL) return;
 
+  enqueued_functions_.Insert(&Function::ZoneHandle(Z, function.raw()));
   pending_functions_.Add(function);
   changed_ = true;
 }
@@ -486,11 +583,11 @@
 }
 
 
-void Precompiler::AddClass(const Class& cls) {
+void Precompiler::AddInstantiatedClass(const Class& cls) {
   if (cls.is_allocated()) return;
 
   class_count_++;
-  cls.set_is_allocated();
+  cls.set_is_allocated(true);
   changed_ = true;
 
   if (FLAG_trace_precompiler) {
@@ -499,7 +596,7 @@
 
   const Class& superclass = Class::Handle(cls.SuperClass());
   if (!superclass.IsNull()) {
-    AddClass(superclass);
+    AddInstantiatedClass(superclass);
   }
 }
 
@@ -520,43 +617,7 @@
     while (it.HasNext()) {
       cls = it.GetNextClass();
 
-      if (!cls.is_allocated()) {
-        bool has_compiled_constructor = false;
-        if (cls.allocation_stub() != Code::null()) {
-          // Regular objects.
-          has_compiled_constructor = true;
-        } else if (cls.is_synthesized_class()) {
-          // Enums.
-          has_compiled_constructor = true;
-        } else {
-          // Objects only allocated via const constructors, and not stored in a
-          // static field or code.
-          // E.g. A in
-          //   class A {
-          //     const A();
-          //     toString() => "Don't drop me!";
-          //   }
-          //   class B {
-          //     const a = const A();
-          //     const B();
-          //     static const theB = const B();
-          //   }
-          //   main() => print(B.theB.a);
-          functions = cls.functions();
-          for (intptr_t k = 0; k < functions.Length(); k++) {
-            function ^= functions.At(k);
-            if (function.IsGenerativeConstructor() &&
-                function.HasCode()) {
-              has_compiled_constructor = true;
-              break;
-            }
-          }
-        }
-        if (!has_compiled_constructor) {
-          continue;
-        }
-        AddClass(cls);
-      }
+      if (!cls.is_allocated()) continue;
 
       functions = cls.functions();
       for (intptr_t k = 0; k < functions.Length(); k++) {
@@ -591,6 +652,10 @@
 
             function2 = function.ImplicitClosureFunction();
             AddFunction(function2);
+
+            // Add corresponding method extractor get:#foo.
+            function2 = function.GetMethodExtractor(selector3);
+            AddFunction(function2);
           }
         } else if (Field::IsSetterName(selector)) {
           selector2 = Symbols::LookupFromConcat(Symbols::ClosurizePrefix(),
@@ -602,6 +667,10 @@
 
             function2 = function.ImplicitClosureFunction();
             AddFunction(function2);
+
+            // Add corresponding method extractor get:#set:foo.
+            function2 = function.GetMethodExtractor(selector2);
+            AddFunction(function2);
           }
         } else if (function.kind() == RawFunction::kRegularFunction) {
           selector2 = Field::LookupGetterSymbol(selector);
@@ -610,6 +679,10 @@
             // Function is foo and somewhere get:foo is called.
             function2 = function.ImplicitClosureFunction();
             AddFunction(function2);
+
+            // Add corresponding method extractor.
+            function2 = function.GetMethodExtractor(selector2);
+            AddFunction(function2);
           }
           selector2 = Symbols::LookupFromConcat(Symbols::ClosurizePrefix(),
                                                 selector);
@@ -618,6 +691,10 @@
             // Function is foo and somewhere get:#foo is called.
             function2 = function.ImplicitClosureFunction();
             AddFunction(function2);
+
+            // Add corresponding method extractor get:#foo
+            function2 = function.GetMethodExtractor(selector2);
+            AddFunction(function2);
           }
         }
       }
@@ -649,6 +726,7 @@
         function ^= functions.At(j);
         if (function.HasCode()) {
           retained_functions.Add(function);
+          function.DropUncompiledImplicitClosureFunction();
         } else {
           dropped_function_count_++;
           if (FLAG_trace_precompiler) {
@@ -664,26 +742,24 @@
         functions.SetAt(j, function);
       }
       cls.SetFunctions(functions);
+    }
+  }
 
-      closures = cls.closures();
-      if (!closures.IsNull()) {
-        retained_functions = GrowableObjectArray::New();
-        for (intptr_t j = 0; j < closures.Length(); j++) {
-          function ^= closures.At(j);
-          if (function.HasCode()) {
-            retained_functions.Add(function);
-          } else {
-            dropped_function_count_++;
-            if (FLAG_trace_precompiler) {
-              THR_Print("Precompilation dropping %s\n",
-                        function.ToLibNamePrefixedQualifiedCString());
-            }
-          }
-        }
-        cls.set_closures(retained_functions);
+  closures = isolate()->object_store()->closure_functions();
+  retained_functions = GrowableObjectArray::New();
+  for (intptr_t j = 0; j < closures.Length(); j++) {
+    function ^= closures.At(j);
+    if (function.HasCode()) {
+      retained_functions.Add(function);
+    } else {
+      dropped_function_count_++;
+      if (FLAG_trace_precompiler) {
+        THR_Print("Precompilation dropping %s\n",
+                  function.ToLibNamePrefixedQualifiedCString());
       }
     }
   }
+  isolate()->object_store()->set_closure_functions(retained_functions);
 }
 
 
@@ -811,17 +887,72 @@
       for (intptr_t j = 0; j < functions.Length(); j++) {
         function ^= functions.At(j);
         visitor->VisitFunction(function);
-      }
-
-      closures = cls.closures();
-      if (!closures.IsNull()) {
-        for (intptr_t j = 0; j < closures.Length(); j++) {
-          function ^= closures.At(j);
+        if (function.HasImplicitClosureFunction()) {
+          function = function.ImplicitClosureFunction();
           visitor->VisitFunction(function);
         }
       }
     }
   }
+  closures = isolate()->object_store()->closure_functions();
+  for (intptr_t j = 0; j < closures.Length(); j++) {
+    function ^= closures.At(j);
+    visitor->VisitFunction(function);
+  }
+}
+
+
+void Precompiler::FinalizeAllClasses() {
+  Library& lib = Library::Handle(Z);
+  Class& cls = Class::Handle(Z);
+
+  for (intptr_t i = 0; i < libraries_.Length(); i++) {
+    lib ^= libraries_.At(i);
+    if (!lib.Loaded()) {
+      String& uri = String::Handle(Z, lib.url());
+      String& msg = String::Handle(Z, String::NewFormatted(
+          "Library '%s' is not loaded. "
+          "Did you forget to call Dart_FinalizeLoading?", uri.ToCString()));
+      Jump(Error::Handle(Z, ApiError::New(msg)));
+    }
+
+    ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
+    while (it.HasNext()) {
+      cls = it.GetNextClass();
+      if (cls.IsDynamicClass()) {
+        continue;  // class 'dynamic' is in the read-only VM isolate.
+      }
+      cls.EnsureIsFinalized(T);
+    }
+  }
+  I->set_all_classes_finalized(true);
+}
+
+
+void Precompiler::ResetPrecompilerState() {
+  changed_ = false;
+  function_count_ = 0;
+  class_count_ = 0;
+  selector_count_ = 0;
+  dropped_function_count_ = 0;
+  ASSERT(pending_functions_.Length() == 0);
+  sent_selectors_.Clear();
+  enqueued_functions_.Clear();
+
+  Library& lib = Library::Handle(Z);
+  Class& cls = Class::Handle(Z);
+
+  for (intptr_t i = 0; i < libraries_.Length(); i++) {
+    lib ^= libraries_.At(i);
+    ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
+    while (it.HasNext()) {
+      cls = it.GetNextClass();
+      if (cls.IsDynamicClass()) {
+        continue;  // class 'dynamic' is in the read-only VM isolate.
+      }
+      cls.set_is_allocated(false);
+    }
+  }
 }
 
 }  // namespace dart
diff --git a/runtime/vm/precompiler.h b/runtime/vm/precompiler.h
index 5051ead..3710edf 100644
--- a/runtime/vm/precompiler.h
+++ b/runtime/vm/precompiler.h
@@ -64,6 +64,28 @@
 
 typedef DirectChainedHashMap<StackmapKeyValueTrait> StackmapSet;
 
+class FunctionKeyValueTrait {
+ public:
+  // Typedefs needed for the DirectChainedHashMap template.
+  typedef const Function* Key;
+  typedef const Function* Value;
+  typedef const Function* Pair;
+
+  static Key KeyOf(Pair kv) { return kv; }
+
+  static Value ValueOf(Pair kv) { return kv; }
+
+  static inline intptr_t Hashcode(Key key) {
+    return key->token_pos();
+  }
+
+  static inline bool IsKeyEqual(Pair pair, Key key) {
+    return pair->raw() == key->raw();
+  }
+};
+
+typedef DirectChainedHashMap<FunctionKeyValueTrait> FunctionSet;
+
 
 class Precompiler : public ValueObject {
  public:
@@ -79,13 +101,13 @@
   void AddRoots(Dart_QualifiedFunctionName embedder_entry_points[]);
   void AddEntryPoints(Dart_QualifiedFunctionName entry_points[]);
   void Iterate();
-  void CleanUp();
 
   void AddCalleesOf(const Function& function);
+  void AddConstObject(const Instance& instance);
   void AddClosureCall(const ICData& call_site);
   void AddField(const Field& field);
   void AddFunction(const Function& function);
-  void AddClass(const Class& cls);
+  void AddInstantiatedClass(const Class& cls);
   void AddSelector(const String& selector);
   bool IsSent(const String& selector);
 
@@ -95,6 +117,7 @@
   void DropUncompiledFunctions();
   void BindStaticCalls();
   void DedupStackmaps();
+  void ResetPrecompilerState();
 
   class FunctionVisitor : public ValueObject {
    public:
@@ -104,6 +127,8 @@
 
   void VisitFunctions(FunctionVisitor* visitor);
 
+  void FinalizeAllClasses();
+
   Thread* thread() const { return thread_; }
   Zone* zone() const { return zone_; }
   Isolate* isolate() const { return isolate_; }
@@ -122,8 +147,8 @@
 
   const GrowableObjectArray& libraries_;
   const GrowableObjectArray& pending_functions_;
-  const GrowableObjectArray& collected_closures_;
   SymbolSet sent_selectors_;
+  FunctionSet enqueued_functions_;
   Error& error_;
 };
 
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc
index 1515eed..d1d52b8 100644
--- a/runtime/vm/profiler.cc
+++ b/runtime/vm/profiler.cc
@@ -9,10 +9,12 @@
 #include "vm/allocation.h"
 #include "vm/atomic.h"
 #include "vm/code_patcher.h"
+#include "vm/debugger.h"
 #include "vm/instructions.h"
 #include "vm/isolate.h"
 #include "vm/json_stream.h"
 #include "vm/lockers.h"
+#include "vm/message_handler.h"
 #include "vm/native_symbol.h"
 #include "vm/object.h"
 #include "vm/os.h"
@@ -104,120 +106,6 @@
 }
 
 
-void Profiler::InitProfilingForIsolate(Isolate* isolate, bool shared_buffer) {
-  if (!FLAG_profile) {
-    return;
-  }
-  ASSERT(isolate == Isolate::Current());
-  ASSERT(isolate != NULL);
-  ASSERT(sample_buffer_ != NULL);
-  {
-    MutexLocker profiler_data_lock(isolate->profiler_data_mutex());
-    SampleBuffer* sample_buffer = sample_buffer_;
-    if (!shared_buffer) {
-      sample_buffer = new SampleBuffer();
-    }
-    IsolateProfilerData* profiler_data =
-        new IsolateProfilerData(sample_buffer, !shared_buffer);
-    ASSERT(profiler_data != NULL);
-    isolate->set_profiler_data(profiler_data);
-    if (FLAG_trace_profiled_isolates) {
-      OS::Print("Profiler Setup %p %s\n", isolate, isolate->name());
-    }
-  }
-  BeginExecution(isolate);
-}
-
-
-void Profiler::ShutdownProfilingForIsolate(Isolate* isolate) {
-  ASSERT(isolate != NULL);
-  if (!FLAG_profile) {
-    return;
-  }
-  // We do not have a current isolate.
-  ASSERT(Isolate::Current() == NULL);
-  {
-    MutexLocker profiler_data_lock(isolate->profiler_data_mutex());
-    IsolateProfilerData* profiler_data = isolate->profiler_data();
-    if (profiler_data == NULL) {
-      // Already freed.
-      return;
-    }
-    isolate->set_profiler_data(NULL);
-    delete profiler_data;
-    if (FLAG_trace_profiled_isolates) {
-      OS::Print("Profiler Shutdown %p %s\n", isolate, isolate->name());
-    }
-  }
-}
-
-
-void Profiler::BeginExecution(Isolate* isolate) {
-  if (isolate == NULL) {
-    return;
-  }
-  if (!FLAG_profile) {
-    return;
-  }
-  ASSERT(initialized_);
-  IsolateProfilerData* profiler_data = isolate->profiler_data();
-  if (profiler_data == NULL) {
-    return;
-  }
-  Thread* thread = Thread::Current();
-  thread->SetThreadInterrupter(RecordSampleInterruptCallback, thread);
-  ThreadInterrupter::WakeUp();
-}
-
-
-void Profiler::EndExecution(Isolate* isolate) {
-  if (isolate == NULL) {
-    return;
-  }
-  if (!FLAG_profile) {
-    return;
-  }
-  ASSERT(initialized_);
-  Thread* thread = Thread::Current();
-  thread->SetThreadInterrupter(NULL, NULL);
-}
-
-
-IsolateProfilerData::IsolateProfilerData(SampleBuffer* sample_buffer,
-                                         bool own_sample_buffer) {
-  ASSERT(sample_buffer != NULL);
-  sample_buffer_ = sample_buffer;
-  own_sample_buffer_ = own_sample_buffer;
-  block_count_ = 0;
-}
-
-
-IsolateProfilerData::~IsolateProfilerData() {
-  if (own_sample_buffer_) {
-    delete sample_buffer_;
-    sample_buffer_ = NULL;
-    own_sample_buffer_ = false;
-  }
-}
-
-
-void IsolateProfilerData::Block() {
-  block_count_++;
-}
-
-
-void IsolateProfilerData::Unblock() {
-  block_count_--;
-  if (block_count_ < 0) {
-    FATAL("Too many calls to Dart_IsolateUnblocked.");
-  }
-  if (!blocked()) {
-    // We just unblocked this isolate, wake up the thread interrupter.
-    ThreadInterrupter::WakeUp();
-  }
-}
-
-
 intptr_t Sample::pcs_length_ = 0;
 intptr_t Sample::instance_size_ = 0;
 
@@ -469,11 +357,12 @@
 // Given an exit frame, walk the Dart stack.
 class ProfilerDartExitStackWalker : public ProfilerStackWalker {
  public:
-  ProfilerDartExitStackWalker(Isolate* isolate,
+  ProfilerDartExitStackWalker(Thread* thread,
+                              Isolate* isolate,
                               Sample* sample,
                               SampleBuffer* sample_buffer)
       : ProfilerStackWalker(isolate, sample, sample_buffer),
-        frame_iterator_(isolate) {
+        frame_iterator_(thread) {
   }
 
   void walk() {
@@ -816,10 +705,10 @@
   if (FLAG_profile_vm) {
     // Always walk the native stack collecting both native and Dart frames.
     native_stack_walker->walk();
-  } else if (exited_dart_code) {
+  } else if (StubCode::HasBeenInitialized() && exited_dart_code) {
     // We have a valid exit frame info, use the Dart stack walker.
     dart_exit_stack_walker->walk();
-  } else if (in_dart_code) {
+  } else if (StubCode::HasBeenInitialized() && in_dart_code) {
     // We are executing Dart code. We have frame pointers.
     dart_stack_walker->walk();
   } else {
@@ -850,26 +739,11 @@
 }
 
 
-// Is |thread| executing Dart code?
-static bool ExecutingDart(Thread* thread) {
-  ASSERT(thread != NULL);
-  return (thread->top_exit_frame_info() == 0) &&
-         (thread->vm_tag() == VMTag::kDartTagId);
-}
-
-
-// Has |thread| exited Dart code?
-static bool ExitedDart(Thread* thread) {
-  return (thread->top_exit_frame_info() != 0) &&
-         (thread->vm_tag() != VMTag::kDartTagId);
-}
-
-
 // Get |isolate|'s stack boundary and verify that |sp| and |fp| are within
 // it. Return |false| if anything looks suspicious.
 static bool GetAndValidateIsolateStackBounds(Thread* thread,
-                                             uintptr_t sp,
                                              uintptr_t fp,
+                                             uintptr_t sp,
                                              uword* stack_lower,
                                              uword* stack_upper) {
   ASSERT(thread != NULL);
@@ -878,7 +752,7 @@
   ASSERT(stack_lower != NULL);
   ASSERT(stack_upper != NULL);
 #if defined(USING_SIMULATOR)
-  const bool in_dart_code = ExecutingDart(thread);
+  const bool in_dart_code = thread->IsExecutingDartCode();
   if (in_dart_code) {
     Simulator* simulator = isolate->simulator();
     *stack_lower = simulator->StackBase();
@@ -921,8 +795,8 @@
 }
 
 
-// Some simple sanity checking of |pc|, |sp|, and |fp|.
-static bool InitialRegisterCheck(uintptr_t pc, uintptr_t sp, uintptr_t fp) {
+// Some simple sanity checking of |pc|, |fp|, and |sp|.
+static bool InitialRegisterCheck(uintptr_t pc, uintptr_t fp, uintptr_t sp) {
   if ((sp == 0) || (fp == 0) || (pc == 0)) {
     // None of these registers should be zero.
     return false;
@@ -938,18 +812,6 @@
 }
 
 
-// Return |isolate|'s sample buffer.
-static SampleBuffer* GetSampleBuffer(Isolate* isolate) {
-  IsolateProfilerData* profiler_data = isolate->profiler_data();
-  if (profiler_data == NULL) {
-    // Profiler not initialized.
-    return NULL;
-  }
-  SampleBuffer* sample_buffer = profiler_data->sample_buffer();
-  return sample_buffer;
-}
-
-
 static Sample* SetupSample(Thread* thread,
                            SampleBuffer* sample_buffer,
                            ThreadId tid) {
@@ -979,8 +841,7 @@
     // No isolate.
     return false;
   }
-  ASSERT(isolate != Dart::vm_isolate());
-  return true;
+  return isolate != Dart::vm_isolate();
 }
 
 
@@ -996,16 +857,16 @@
 }
 #endif
 
-void Profiler::RecordAllocation(Thread* thread, intptr_t cid) {
+void Profiler::SampleAllocation(Thread* thread, intptr_t cid) {
   ASSERT(thread != NULL);
   Isolate* isolate = thread->isolate();
   if (!CheckIsolate(isolate)) {
     return;
   }
 
-  const bool exited_dart_code = ExitedDart(thread);
+  const bool exited_dart_code = thread->HasExitedDartCode();
 
-  SampleBuffer* sample_buffer = GetSampleBuffer(isolate);
+  SampleBuffer* sample_buffer = Profiler::sample_buffer();
   if (sample_buffer == NULL) {
     // Profiler not initialized.
     return;
@@ -1021,13 +882,13 @@
     uword stack_lower = 0;
     uword stack_upper = 0;
 
-    if (!InitialRegisterCheck(pc, sp, fp)) {
+    if (!InitialRegisterCheck(pc, fp, sp)) {
       return;
     }
 
     if (!GetAndValidateIsolateStackBounds(thread,
-                                          sp,
                                           fp,
+                                          sp,
                                           &stack_lower,
                                           &stack_upper)) {
       // Could not get stack boundary.
@@ -1052,7 +913,8 @@
                                  sample_buffer,
                                  OSThread::GetCurrentThreadId());
     sample->SetAllocationCid(cid);
-    ProfilerDartExitStackWalker dart_exit_stack_walker(isolate,
+    ProfilerDartExitStackWalker dart_exit_stack_walker(thread,
+                                                       isolate,
                                                        sample,
                                                        sample_buffer);
     dart_exit_stack_walker.walk();
@@ -1069,25 +931,20 @@
 }
 
 
-void Profiler::RecordSampleInterruptCallback(
-    const InterruptedThreadState& state,
-    void* data) {
-  Thread* thread = reinterpret_cast<Thread*>(data);
+void Profiler::SampleThread(Thread* thread,
+                            const InterruptedThreadState& state) {
+  ASSERT(thread != NULL);
   Isolate* isolate = thread->isolate();
-  if ((isolate == NULL) || (Dart::vm_isolate() == NULL)) {
-    // No isolate.
-    return;
-  }
-  ASSERT(isolate != Dart::vm_isolate());
 
-  SampleBuffer* sample_buffer = GetSampleBuffer(isolate);
-  if (sample_buffer == NULL) {
-    // Profiler not initialized.
+  if (StubCode::HasBeenInitialized() &&
+      StubCode::InJumpToExceptionHandlerStub(state.pc)) {
+    // The JumpToExceptionHandler stub manually adjusts the stack pointer,
+    // frame pointer, and some isolate state before jumping to a catch entry.
+    // It is not safe to walk the stack when executing this stub.
     return;
   }
 
-  const bool exited_dart_code = ExitedDart(thread);
-  const bool in_dart_code = ExecutingDart(thread);
+  const bool in_dart_code = thread->IsExecutingDartCode();
 
   uintptr_t sp = 0;
   uintptr_t fp = state.fp;
@@ -1111,22 +968,25 @@
     sp = state.csp;
   }
 
-  if (!InitialRegisterCheck(pc, sp, fp)) {
+  if (!InitialRegisterCheck(pc, fp, sp)) {
     return;
   }
 
-  if (StubCode::InJumpToExceptionHandlerStub(pc)) {
-    // The JumpToExceptionHandler stub manually adjusts the stack pointer,
-    // frame pointer, and some isolate state before jumping to a catch entry.
-    // It is not safe to walk the stack when executing this stub.
+  if (!CheckIsolate(isolate)) {
+    return;
+  }
+
+  if (!thread->IsMutatorThread()) {
+    // Not a mutator thread.
+    // TODO(johnmccutchan): Profile all threads with an isolate.
     return;
   }
 
   uword stack_lower = 0;
   uword stack_upper = 0;
   if (!GetAndValidateIsolateStackBounds(thread,
-                                        sp,
                                         fp,
+                                        sp,
                                         &stack_lower,
                                         &stack_upper)) {
     // Could not get stack boundary.
@@ -1135,6 +995,11 @@
 
   // At this point we have a valid stack boundary for this isolate and
   // know that our initial stack and frame pointers are within the boundary.
+  SampleBuffer* sample_buffer = Profiler::sample_buffer();
+  if (sample_buffer == NULL) {
+    // Profiler not initialized.
+    return;
+  }
 
   // Setup sample.
   Sample* sample = SetupSample(thread,
@@ -1154,7 +1019,8 @@
                                                 fp,
                                                 sp);
 
-  ProfilerDartExitStackWalker dart_exit_stack_walker(isolate,
+  ProfilerDartExitStackWalker dart_exit_stack_walker(thread,
+                                                     isolate,
                                                      sample,
                                                      sample_buffer);
 
@@ -1167,6 +1033,8 @@
                                             fp,
                                             sp);
 
+  const bool exited_dart_code = thread->HasExitedDartCode();
+
   // All memory access is done inside CollectSample.
   CollectSample(isolate,
                 exited_dart_code,
@@ -1181,6 +1049,138 @@
 }
 
 
+
+CodeDescriptor::CodeDescriptor(const Code& code) : code_(code) {
+  ASSERT(!code_.IsNull());
+}
+
+
+uword CodeDescriptor::Entry() const {
+  return code_.EntryPoint();
+}
+
+
+uword CodeDescriptor::Size() const {
+  return code_.Size();
+}
+
+
+int64_t CodeDescriptor::CompileTimestamp() const {
+  return code_.compile_timestamp();
+}
+
+
+CodeLookupTable::CodeLookupTable(Thread* thread) {
+  Build(thread);
+}
+
+
+class CodeLookupTableBuilder : public ObjectVisitor {
+ public:
+  CodeLookupTableBuilder(Isolate* isolate, CodeLookupTable* table)
+      : ObjectVisitor(isolate),
+        table_(table) {
+    ASSERT(table_ != NULL);
+  }
+
+  ~CodeLookupTableBuilder() {
+  }
+
+  void VisitObject(RawObject* raw_obj) {
+    uword tags = raw_obj->ptr()->tags_;
+    if (RawObject::ClassIdTag::decode(tags) == kCodeCid) {
+      RawCode* raw_code = reinterpret_cast<RawCode*>(raw_obj);
+      const Code& code = Code::Handle(raw_code);
+      ASSERT(!code.IsNull());
+      const Instructions& instructions =
+          Instructions::Handle(code.instructions());
+      ASSERT(!instructions.IsNull());
+      table_->Add(code);
+    }
+  }
+
+ private:
+  CodeLookupTable* table_;
+};
+
+
+void CodeLookupTable::Build(Thread* thread) {
+  ASSERT(thread != NULL);
+  Isolate* isolate = thread->isolate();
+  ASSERT(isolate != NULL);
+  Isolate* vm_isolate = Dart::vm_isolate();
+  ASSERT(vm_isolate != NULL);
+
+  // Clear.
+  code_objects_.Clear();
+
+  // Add all found Code objects.
+  CodeLookupTableBuilder cltb(isolate, this);
+  vm_isolate->heap()->IterateOldObjects(&cltb);
+  isolate->heap()->IterateOldObjects(&cltb);
+
+  // Sort by entry.
+  code_objects_.Sort(CodeDescriptor::Compare);
+
+#if defined(DEBUG)
+  if (length() <= 1) {
+    return;
+  }
+  ASSERT(FindCode(0) == NULL);
+  ASSERT(FindCode(~0) == NULL);
+  // Sanity check that we don't have duplicate entries and that the entries
+  // are sorted.
+  for (intptr_t i = 0; i < length() - 1; i++) {
+    const CodeDescriptor* a = At(i);
+    const CodeDescriptor* b = At(i + 1);
+    ASSERT(a->Entry() < b->Entry());
+    ASSERT(FindCode(a->Entry()) == a);
+    ASSERT(FindCode(b->Entry()) == b);
+    ASSERT(FindCode(a->Entry() + a->Size() - 1) == a);
+    ASSERT(FindCode(b->Entry() + b->Size() - 1) == b);
+  }
+#endif
+}
+
+
+void CodeLookupTable::Add(const Code& code) {
+  ASSERT(!code.IsNull());
+  CodeDescriptor* cd = new CodeDescriptor(code);
+  code_objects_.Add(cd);
+}
+
+
+const CodeDescriptor* CodeLookupTable::FindCode(uword pc) const {
+  intptr_t first = 0;
+  intptr_t count = length();
+  while (count > 0) {
+    intptr_t current = first;
+    intptr_t step = count / 2;
+    current += step;
+    const CodeDescriptor* cd = At(current);
+    if (pc >= cd->Entry()) {
+      first = ++current;
+      count -= step + 1;
+    } else {
+      count = step;
+    }
+  }
+  // First points to the first code object whose entry is greater than PC.
+  // That means the code object we need to check is first - 1.
+  if (first == 0) {
+    return NULL;
+  }
+  first--;
+  ASSERT(first >= 0);
+  ASSERT(first < length());
+  const CodeDescriptor* cd = At(first);
+  if (cd->Contains(pc)) {
+    return cd;
+  }
+  return NULL;
+}
+
+
 ProcessedSampleBuffer* SampleBuffer::BuildProcessedSampleBuffer(
     SampleFilter* filter) {
   ASSERT(filter != NULL);
@@ -1216,13 +1216,15 @@
       // Did not pass filter.
       continue;
     }
-    buffer->Add(BuildProcessedSample(sample));
+    buffer->Add(BuildProcessedSample(sample, buffer->code_lookup_table()));
   }
   return buffer;
 }
 
 
-ProcessedSample* SampleBuffer::BuildProcessedSample(Sample* sample) {
+ProcessedSample* SampleBuffer::BuildProcessedSample(
+    Sample* sample,
+    const CodeLookupTable& clt) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
 
@@ -1253,9 +1255,7 @@
   }
 
   if (!sample->exit_frame_sample()) {
-    Isolate* vm_isolate = Dart::vm_isolate();
-    processed_sample->FixupCaller(thread,
-                                  vm_isolate,
+    processed_sample->FixupCaller(clt,
                                   sample->pc_marker(),
                                   sample->GetStackBuffer());
   }
@@ -1295,31 +1295,29 @@
 }
 
 
-void ProcessedSample::FixupCaller(Thread* thread,
-                                  Isolate* vm_isolate,
+void ProcessedSample::FixupCaller(const CodeLookupTable& clt,
                                   uword pc_marker,
                                   uword* stack_buffer) {
-  REUSABLE_CODE_HANDLESCOPE(thread);
-  // Lookup code object for leaf frame.
-  Code& code = reused_code_handle.Handle();
-  code = FindCodeForPC(thread->isolate(), vm_isolate, At(0));
-  if (code.IsNull()) {
+  const CodeDescriptor* cd = clt.FindCode(At(0));
+  if (cd == NULL) {
+    // No Dart code.
     return;
   }
-  if (code.compile_timestamp() > timestamp()) {
+  if (cd->CompileTimestamp() > timestamp()) {
     // Code compiled after sample. Ignore.
     return;
   }
-  CheckForMissingDartFrame(
-      thread->isolate(), vm_isolate, code, pc_marker, stack_buffer);
+  CheckForMissingDartFrame(clt, cd, pc_marker, stack_buffer);
 }
 
 
-void ProcessedSample::CheckForMissingDartFrame(Isolate* isolate,
-                                               Isolate* vm_isolate,
-                                               const Code& code,
+void ProcessedSample::CheckForMissingDartFrame(const CodeLookupTable& clt,
+                                               const CodeDescriptor* cd,
                                                uword pc_marker,
                                                uword* stack_buffer) {
+  ASSERT(cd != NULL);
+  const Code& code = Code::Handle(cd->code());
+  ASSERT(!code.IsNull());
   // Some stubs (and intrinsics) do not push a frame onto the stack leaving
   // the frame pointer in the caller.
   //
@@ -1336,7 +1334,6 @@
   // the PC marker. We can use the PC marker to insert DART3 into the stack
   // so that it will correctly be: STUB, DART3, DART2, DART1. Note the
   // inserted PC may not accurately reflect the true return address into DART3.
-  ASSERT(!code.IsNull());
 
   // The pc marker is our current best guess of a return address.
   uword return_address = pc_marker;
@@ -1358,8 +1355,8 @@
     }
   }
 
-  if (!ContainedInDartCodeHeaps(isolate, vm_isolate, return_address)) {
-    // return address is not from the Dart heap. Do not insert.
+  if (clt.FindCode(return_address) == NULL) {
+    // Return address is not from a Dart code object. Do not insert.
     return;
   }
 
@@ -1369,32 +1366,9 @@
 }
 
 
-RawCode* ProcessedSample::FindCodeForPC(Isolate* isolate,
-                                        Isolate* vm_isolate,
-                                        uword pc) {
-  // Check current isolate for pc.
-  if (isolate->heap()->CodeContains(pc)) {
-    return Code::LookupCode(pc);
-  }
-
-  // Check VM isolate for pc.
-  if (vm_isolate->heap()->CodeContains(pc)) {
-    return Code::LookupCodeInVmIsolate(pc);
-  }
-
-  return Code::null();
-}
-
-
-bool ProcessedSample::ContainedInDartCodeHeaps(Isolate* isolate,
-                                               Isolate* vm_isolate,
-                                               uword pc) {
-  return vm_isolate->heap()->CodeContains(pc)
-         || isolate->heap()->CodeContains(pc);
-}
-
-
-ProcessedSampleBuffer::ProcessedSampleBuffer() {
+ProcessedSampleBuffer::ProcessedSampleBuffer()
+    : code_lookup_table_(new CodeLookupTable(Thread::Current())) {
+  ASSERT(code_lookup_table_ != NULL);
 }
 
 }  // namespace dart
diff --git a/runtime/vm/profiler.h b/runtime/vm/profiler.h
index ff8e148..f4b481e 100644
--- a/runtime/vm/profiler.h
+++ b/runtime/vm/profiler.h
@@ -10,6 +10,7 @@
 #include "vm/code_observers.h"
 #include "vm/globals.h"
 #include "vm/growable_array.h"
+#include "vm/object.h"
 #include "vm/tags.h"
 #include "vm/thread_interrupter.h"
 
@@ -33,55 +34,30 @@
   static void SetSampleDepth(intptr_t depth);
   static void SetSamplePeriod(intptr_t period);
 
-  static void InitProfilingForIsolate(Isolate* isolate,
-                                      bool shared_buffer = true);
-  static void ShutdownProfilingForIsolate(Isolate* isolate);
-
-  static void BeginExecution(Isolate* isolate);
-  static void EndExecution(Isolate* isolate);
-
   static SampleBuffer* sample_buffer() {
     return sample_buffer_;
   }
 
-  static void RecordAllocation(Thread* thread, intptr_t cid);
+  static void SampleAllocation(Thread* thread, intptr_t cid);
+
+  // SampleThread is called from inside the signal handler and hence it is very
+  // critical that the implementation of SampleThread does not do any of the
+  // following:
+  //   * Accessing TLS -- Because on Windows the callback will be running in a
+  //                      different thread.
+  //   * Allocating memory -- Because this takes locks which may already be
+  //                          held, resulting in a dead lock.
+  //   * Taking a lock -- See above.
+  static void SampleThread(Thread* thread,
+                           const InterruptedThreadState& state);
 
  private:
   static bool initialized_;
   static Monitor* monitor_;
 
-  static void RecordSampleInterruptCallback(const InterruptedThreadState& state,
-                                            void* data);
-
   static SampleBuffer* sample_buffer_;
-};
 
-
-class IsolateProfilerData {
- public:
-  IsolateProfilerData(SampleBuffer* sample_buffer, bool own_sample_buffer);
-  ~IsolateProfilerData();
-
-  SampleBuffer* sample_buffer() const { return sample_buffer_; }
-
-  void set_sample_buffer(SampleBuffer* sample_buffer) {
-    sample_buffer_ = sample_buffer;
-  }
-
-  bool blocked() const {
-    return block_count_ > 0;
-  }
-
-  void Block();
-
-  void Unblock();
-
- private:
-  SampleBuffer* sample_buffer_;
-  bool own_sample_buffer_;
-  intptr_t block_count_;
-
-  DISALLOW_COPY_AND_ASSIGN(IsolateProfilerData);
+  friend class Thread;
 };
 
 
@@ -380,6 +356,84 @@
 };
 
 
+// A Code object descriptor.
+class CodeDescriptor : public ZoneAllocated {
+ public:
+  explicit CodeDescriptor(const Code& code);
+
+  uword Entry() const;
+
+  uword Size() const;
+
+  int64_t CompileTimestamp() const;
+
+  RawCode* code() const {
+    return code_.raw();
+  }
+
+  const char* Name() const {
+    const String& name = String::Handle(code_.Name());
+    return name.ToCString();
+  }
+
+  bool Contains(uword pc) const {
+    uword end = Entry() + Size();
+    return (pc >= Entry()) && (pc < end);
+  }
+
+  static int Compare(CodeDescriptor* const* a,
+                     CodeDescriptor* const* b) {
+    ASSERT(a != NULL);
+    ASSERT(b != NULL);
+
+    uword a_entry = (*a)->Entry();
+    uword b_entry = (*b)->Entry();
+
+    if (a_entry < b_entry) {
+      return -1;
+    } else if (a_entry > b_entry) {
+      return 1;
+    } else {
+      return 0;
+    }
+  }
+
+ private:
+  const Code& code_;
+
+  DISALLOW_COPY_AND_ASSIGN(CodeDescriptor);
+};
+
+
+// Fast lookup of Dart code objects.
+class CodeLookupTable : public ZoneAllocated {
+ public:
+  explicit CodeLookupTable(Thread* thread);
+
+  intptr_t length() const {
+    return code_objects_.length();
+  }
+
+  const CodeDescriptor* At(intptr_t index) const {
+    return code_objects_.At(index);
+  }
+
+  const CodeDescriptor* FindCode(uword pc) const;
+
+ private:
+  void Build(Thread* thread);
+
+  void Add(const Code& code);
+
+  // Code objects sorted by entry.
+  ZoneGrowableArray<CodeDescriptor*> code_objects_;
+
+  friend class CodeLookupTableBuilder;
+
+  DISALLOW_COPY_AND_ASSIGN(CodeLookupTable);
+};
+
+
 // Ring buffer of Samples that is (usually) shared by many isolates.
 class SampleBuffer {
  public:
@@ -436,7 +490,8 @@
   ProcessedSampleBuffer* BuildProcessedSampleBuffer(SampleFilter* filter);
 
  private:
-  ProcessedSample* BuildProcessedSample(Sample* sample);
+  ProcessedSample* BuildProcessedSample(Sample* sample,
+                                        const CodeLookupTable& clt);
   Sample* Next(Sample* sample);
 
   Sample* samples_;
@@ -505,25 +560,15 @@
   }
 
  private:
-  void FixupCaller(Thread* thread,
-                   Isolate* vm_isolate,
+  void FixupCaller(const CodeLookupTable& clt,
                    uword pc_marker,
                    uword* stack_buffer);
 
-  void CheckForMissingDartFrame(Isolate* isolate,
-                                Isolate* vm_isolate,
-                                const Code& code,
+  void CheckForMissingDartFrame(const CodeLookupTable& clt,
+                                const CodeDescriptor* code,
                                 uword pc_marker,
                                 uword* stack_buffer);
 
-  static RawCode* FindCodeForPC(Isolate* isolate,
-                                Isolate* vm_isolate,
-                                uword pc);
-
-  static bool ContainedInDartCodeHeaps(Isolate* isolate,
-                                       Isolate* vm_isolate,
-                                       uword pc);
-
   ZoneGrowableArray<uword> pcs_;
   int64_t timestamp_;
   uword vm_tag_;
@@ -554,8 +599,13 @@
     return samples_.At(index);
   }
 
+  const CodeLookupTable& code_lookup_table() const {
+    return *code_lookup_table_;
+  }
+
  private:
   ZoneGrowableArray<ProcessedSample*> samples_;
+  CodeLookupTable* code_lookup_table_;
 
   DISALLOW_COPY_AND_ASSIGN(ProcessedSampleBuffer);
 };
diff --git a/runtime/vm/profiler_service.cc b/runtime/vm/profiler_service.cc
index 6419707..40b7bdc 100644
--- a/runtime/vm/profiler_service.cc
+++ b/runtime/vm/profiler_service.cc
@@ -984,18 +984,18 @@
     kNumProfileInfoKind,
   };
 
-  ProfileBuilder(Isolate* isolate,
+  ProfileBuilder(Thread* thread,
                  SampleFilter* filter,
                  Profile::TagOrder tag_order,
                  intptr_t extra_tags,
                  Profile* profile)
-      : isolate_(isolate),
+      : thread_(thread),
         vm_isolate_(Dart::vm_isolate()),
         filter_(filter),
         tag_order_(tag_order),
         extra_tags_(extra_tags),
         profile_(profile),
-        deoptimized_code_(new DeoptimizedCodeSet(isolate)),
+        deoptimized_code_(new DeoptimizedCodeSet(thread->isolate())),
         null_code_(Code::ZoneHandle()),
         null_function_(Function::ZoneHandle()),
         tick_functions_(false),
@@ -1051,12 +1051,7 @@
 
   void FilterSamples() {
     ScopeTimer sw("ProfileBuilder::FilterSamples", FLAG_trace_profiler);
-    MutexLocker profiler_data_lock(isolate_->profiler_data_mutex());
-    IsolateProfilerData* profiler_data = isolate_->profiler_data();
-    if (profiler_data == NULL) {
-      return;
-    }
-    SampleBuffer* sample_buffer = profiler_data->sample_buffer();
+    SampleBuffer* sample_buffer = Profiler::sample_buffer();
     if (sample_buffer == NULL) {
       return;
     }
@@ -1080,6 +1075,27 @@
 
   void BuildCodeTable() {
     ScopeTimer sw("ProfileBuilder::BuildCodeTable", FLAG_trace_profiler);
+
+    Isolate* isolate = thread_->isolate();
+    ASSERT(isolate != NULL);
+
+    // Build the live code table eagerly by populating it with code objects
+    // from the processed sample buffer.
+    const CodeLookupTable& code_lookup_table = samples_->code_lookup_table();
+    for (intptr_t i = 0; i < code_lookup_table.length(); i++) {
+      const CodeDescriptor* descriptor = code_lookup_table.At(i);
+      ASSERT(descriptor != NULL);
+      const Code& code = Code::Handle(descriptor->code());
+      ASSERT(!code.IsNull());
+      RegisterLiveProfileCode(
+          new ProfileCode(ProfileCode::kDartCode,
+                          code.EntryPoint(),
+                          code.EntryPoint() + code.Size(),
+                          code.compile_timestamp(),
+                          code));
+    }
+
+    // Iterate over samples.
     for (intptr_t sample_index = 0;
          sample_index < samples_->length();
          sample_index++) {
@@ -1107,7 +1123,7 @@
            frame_index++) {
         const uword pc = sample->At(frame_index);
         ASSERT(pc != 0);
-        ProfileCode* code = RegisterProfileCode(pc, timestamp);
+        ProfileCode* code = FindOrRegisterProfileCode(pc, timestamp);
         ASSERT(code != NULL);
         code->Tick(pc, IsExecutingFrame(sample, frame_index), sample_index);
       }
@@ -1842,107 +1858,88 @@
     return code;
   }
 
-  ProfileCode* CreateProfileCode(uword pc) {
-    const intptr_t kDartCodeAlignment = OS::PreferredCodeAlignment();
-    const intptr_t kDartCodeAlignmentMask = ~(kDartCodeAlignment - 1);
-    Code& code = Code::Handle(isolate_->current_zone());
+  bool IsPCInDartHeap(uword pc) {
+    return vm_isolate_->heap()->CodeContains(pc) ||
+           thread_->isolate()->heap()->CodeContains(pc);
+  }
 
-    // Check current isolate for pc.
-    if (isolate_->heap()->CodeContains(pc)) {
-      code ^= Code::LookupCode(pc);
-      if (!code.IsNull()) {
-        deoptimized_code_->Add(code);
-        return new ProfileCode(ProfileCode::kDartCode,
-                              code.EntryPoint(),
-                              code.EntryPoint() + code.Size(),
-                              code.compile_timestamp(),
-                              code);
-      }
-      return new ProfileCode(ProfileCode::kCollectedCode,
-                            pc,
-                            (pc & kDartCodeAlignmentMask) + kDartCodeAlignment,
-                            0,
-                            code);
+
+  ProfileCode* FindOrRegisterNativeProfileCode(uword pc) {
+    // Check if |pc| is already known in the live code table.
+    ProfileCodeTable* live_table = profile_->live_code_;
+    ProfileCode* profile_code = live_table->FindCodeForPC(pc);
+    if (profile_code != NULL) {
+      return profile_code;
     }
 
-    // Check VM isolate for pc.
-    if (vm_isolate_->heap()->CodeContains(pc)) {
-      code ^= Code::LookupCodeInVmIsolate(pc);
-      if (!code.IsNull()) {
-        return new ProfileCode(ProfileCode::kDartCode,
-                              code.EntryPoint(),
-                              code.EntryPoint() + code.Size(),
-                              code.compile_timestamp(),
-                              code);
-      }
-      return new ProfileCode(ProfileCode::kCollectedCode,
-                            pc,
-                            (pc & kDartCodeAlignmentMask) + kDartCodeAlignment,
-                            0,
-                            code);
-    }
+    // We haven't seen this pc yet.
+    Code& code = Code::Handle(thread_->zone());
 
     // Check NativeSymbolResolver for pc.
     uintptr_t native_start = 0;
     char* native_name = NativeSymbolResolver::LookupSymbolName(pc,
                                                                &native_start);
     if (native_name == NULL) {
-      // No native name found.
-      return new ProfileCode(ProfileCode::kNativeCode,
-                            pc,
-                            pc + 1,
-                            0,
-                            code);
+      // Failed to find a native symbol for pc.
+      native_start = pc;
     }
+
+#if defined(HOST_ARCH_ARM)
+    // The symbol for a Thumb function will be xxx1, but we may have samples
+    // at function entry which will have pc xxx0.
+    native_start &= ~1;
+#endif
+
     ASSERT(pc >= native_start);
-    ProfileCode* profile_code =
-        new ProfileCode(ProfileCode::kNativeCode,
-                       native_start,
-                       pc + 1,
-                       0,
-                       code);
-    profile_code->SetName(native_name);
-    free(native_name);
+    profile_code = new ProfileCode(ProfileCode::kNativeCode,
+                                   native_start,
+                                   pc + 1,
+                                   0,
+                                   code);
+    if (native_name != NULL) {
+      profile_code->SetName(native_name);
+      NativeSymbolResolver::FreeSymbolName(native_name);
+    }
+
+    RegisterLiveProfileCode(profile_code);
     return profile_code;
   }
 
-  ProfileCode* RegisterProfileCode(uword pc, int64_t timestamp) {
+  void RegisterLiveProfileCode(ProfileCode* code) {
     ProfileCodeTable* live_table = profile_->live_code_;
+    intptr_t index = live_table->InsertCode(code);
+    ASSERT(index >= 0);
+  }
+
+  ProfileCode* FindOrRegisterDeadProfileCode(uword pc) {
     ProfileCodeTable* dead_table = profile_->dead_code_;
 
-    ProfileCode* code = live_table->FindCodeForPC(pc);
-    if (code == NULL) {
-      // Code not found.
-      intptr_t index = live_table->InsertCode(CreateProfileCode(pc));
-      ASSERT(index >= 0);
-      code = live_table->At(index);
-      if (code->compile_timestamp() <= timestamp) {
-        // Code was compiled before sample was taken.
-        return code;
-      }
-      // Code was compiled after the sample was taken. Insert code object into
-      // the dead code table.
-      index = dead_table->InsertCode(CreateProfileCodeReused(pc));
-      ASSERT(index >= 0);
-      return dead_table->At(index);
-    }
-    // Existing code found.
-    if (code->compile_timestamp() <= timestamp) {
-      // Code was compiled before sample was taken.
-      return code;
-    }
-    // Code was compiled after the sample was taken. Check if we have an entry
-    // in the dead code table.
-    code = dead_table->FindCodeForPC(pc);
+    ProfileCode* code = dead_table->FindCodeForPC(pc);
     if (code != NULL) {
       return code;
     }
+
     // Create a new dead code entry.
     intptr_t index = dead_table->InsertCode(CreateProfileCodeReused(pc));
     ASSERT(index >= 0);
     return dead_table->At(index);
   }
 
+  ProfileCode* FindOrRegisterProfileCode(uword pc, int64_t timestamp) {
+    ProfileCodeTable* live_table = profile_->live_code_;
+    ProfileCode* code = live_table->FindCodeForPC(pc);
+    if ((code != NULL) && (code->compile_timestamp() <= timestamp)) {
+      // Code was compiled before sample was taken.
+      return code;
+    }
+    if ((code == NULL) && !IsPCInDartHeap(pc)) {
+      // Not a PC from Dart code. Check with native code.
+      return FindOrRegisterNativeProfileCode(pc);
+    }
+    // We either didn't find the code or it was compiled after the sample.
+    return FindOrRegisterDeadProfileCode(pc);
+  }
+
   Profile::TagOrder tag_order() const {
     return tag_order_;
   }
@@ -1957,7 +1954,7 @@
     return (extra_tags_ & extra_tags_bits) != 0;
   }
 
-  Isolate* isolate_;
+  Thread* thread_;
   Isolate* vm_isolate_;
   SampleFilter* filter_;
   Profile::TagOrder tag_order_;
@@ -1971,7 +1968,7 @@
 
   ProcessedSampleBuffer* samples_;
   ProfileInfoKind info_kind_;
-};
+};  // ProfileBuilder.
 
 
 Profile::Profile(Isolate* isolate)
@@ -1991,10 +1988,11 @@
 }
 
 
-void Profile::Build(SampleFilter* filter,
+void Profile::Build(Thread* thread,
+                    SampleFilter* filter,
                     TagOrder tag_order,
                     intptr_t extra_tags) {
-  ProfileBuilder builder(isolate_, filter, tag_order, extra_tags, this);
+  ProfileBuilder builder(thread, filter, tag_order, extra_tags, this);
   builder.Build();
 }
 
@@ -2200,28 +2198,22 @@
                                     intptr_t extra_tags,
                                     SampleFilter* filter) {
   Isolate* isolate = thread->isolate();
-  // Disable profile interrupts while processing the buffer.
-  Profiler::EndExecution(isolate);
+  // Disable thread interrupts while processing the buffer.
+  DisableThreadInterruptsScope dtis(thread);
 
-  {
-    MutexLocker profiler_data_lock(isolate->profiler_data_mutex());
-    IsolateProfilerData* profiler_data = isolate->profiler_data();
-    if (profiler_data == NULL) {
-      stream->PrintError(kFeatureDisabled, NULL);
-      return;
-    }
+  SampleBuffer* sample_buffer = Profiler::sample_buffer();
+  if (sample_buffer == NULL) {
+    stream->PrintError(kFeatureDisabled, NULL);
+    return;
   }
 
   {
     StackZone zone(thread);
     HANDLESCOPE(thread);
     Profile profile(isolate);
-    profile.Build(filter, tag_order, extra_tags);
+    profile.Build(thread, filter, tag_order, extra_tags);
     profile.PrintJSON(stream);
   }
-
-  // Enable profile interrupts.
-  Profiler::BeginExecution(isolate);
 }
 
 
@@ -2276,24 +2268,19 @@
 
 
 void ProfilerService::ClearSamples() {
-  Isolate* isolate = Isolate::Current();
-
-  // Disable profile interrupts while processing the buffer.
-  Profiler::EndExecution(isolate);
-
-  MutexLocker profiler_data_lock(isolate->profiler_data_mutex());
-  IsolateProfilerData* profiler_data = isolate->profiler_data();
-  if (profiler_data == NULL) {
+  SampleBuffer* sample_buffer = Profiler::sample_buffer();
+  if (sample_buffer == NULL) {
     return;
   }
-  SampleBuffer* sample_buffer = profiler_data->sample_buffer();
-  ASSERT(sample_buffer != NULL);
+
+  Thread* thread = Thread::Current();
+  Isolate* isolate = thread->isolate();
+
+  // Disable thread interrupts while processing the buffer.
+  DisableThreadInterruptsScope dtis(thread);
 
   ClearProfileVisitor clear_profile(isolate);
   sample_buffer->VisitSamples(&clear_profile);
-
-  // Enable profile interrupts.
-  Profiler::BeginExecution(isolate);
 }
 
 }  // namespace dart
diff --git a/runtime/vm/profiler_service.h b/runtime/vm/profiler_service.h
index 621db01..83df5e7 100644
--- a/runtime/vm/profiler_service.h
+++ b/runtime/vm/profiler_service.h
@@ -300,7 +300,8 @@
   explicit Profile(Isolate* isolate);
 
   // Build a filtered model using |filter| with the specified |tag_order|.
-  void Build(SampleFilter* filter, TagOrder tag_order, intptr_t extra_tags = 0);
+  void Build(Thread* thread,
+             SampleFilter* filter, TagOrder tag_order, intptr_t extra_tags = 0);
 
   // After building:
   int64_t min_time() const { return min_time_; }
diff --git a/runtime/vm/profiler_test.cc b/runtime/vm/profiler_test.cc
index bc43d5f..7ed4c36 100644
--- a/runtime/vm/profiler_test.cc
+++ b/runtime/vm/profiler_test.cc
@@ -13,6 +13,7 @@
 
 namespace dart {
 
+DECLARE_FLAG(bool, background_compilation);
 DECLARE_FLAG(bool, profile_vm);
 DECLARE_FLAG(int, max_profile_depth);
 
@@ -210,7 +211,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, class_a.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have 1 allocation sample.
     EXPECT_EQ(1, profile.sample_count());
     ProfileTrieWalker walker(&profile);
@@ -289,7 +290,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, class_a.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have no allocation samples.
     EXPECT_EQ(0, profile.sample_count());
   }
@@ -307,7 +308,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, class_a.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
     ProfileTrieWalker walker(&profile);
@@ -362,7 +363,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, class_a.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should still only have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
   }
@@ -403,7 +404,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, class_a.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have no allocation samples.
     EXPECT_EQ(0, profile.sample_count());
   }
@@ -426,7 +427,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, class_a.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have three allocation samples.
     EXPECT_EQ(3, profile.sample_count());
     ProfileTrieWalker walker(&profile);
@@ -498,7 +499,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, class_a.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have no allocation samples.
     EXPECT_EQ(0, profile.sample_count());
   }
@@ -521,7 +522,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, class_a.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have three allocation samples.
     EXPECT_EQ(3, profile.sample_count());
     ProfileTrieWalker walker(&profile);
@@ -582,7 +583,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, double_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have no allocation samples.
     EXPECT_EQ(0, profile.sample_count());
   }
@@ -596,7 +597,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, double_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
     ProfileTrieWalker walker(&profile);
@@ -620,7 +621,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, double_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should still only have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
   }
@@ -650,7 +651,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, array_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have no allocation samples.
     EXPECT_EQ(0, profile.sample_count());
   }
@@ -664,7 +665,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, array_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
     ProfileTrieWalker walker(&profile);
@@ -688,7 +689,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, array_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should still only have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
   }
@@ -712,7 +713,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, array_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should still only have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
     ProfileTrieWalker walker(&profile);
@@ -757,7 +758,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, context_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have no allocation samples.
     EXPECT_EQ(0, profile.sample_count());
   }
@@ -771,7 +772,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, context_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
     ProfileTrieWalker walker(&profile);
@@ -791,7 +792,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, context_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should still only have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
   }
@@ -835,7 +836,7 @@
     Profile profile(isolate);
     AllocationFilter filter(isolate, class_class.id());
     filter.set_enable_embedder_ticks(true);
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
     ProfileTrieWalker walker(&profile);
@@ -846,7 +847,7 @@
     // TODO(johnmccutchan): Hookup native symbol resolver on Windows.
     EXPECT_SUBSTRING("[Native]", walker.CurrentName());
 #else
-    EXPECT_SUBSTRING("dart::Profiler::RecordAllocation", walker.CurrentName());
+    EXPECT_SUBSTRING("dart::Profiler::SampleAllocation", walker.CurrentName());
 #endif
     EXPECT(!walker.Down());
   }
@@ -864,7 +865,7 @@
     Profile profile(isolate);
     AllocationFilter filter(isolate, class_class.id());
     filter.set_enable_embedder_ticks(true);
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should still only have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
   }
@@ -897,7 +898,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, float32_list_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have no allocation samples.
     EXPECT_EQ(0, profile.sample_count());
   }
@@ -911,7 +912,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, float32_list_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
     ProfileTrieWalker walker(&profile);
@@ -937,7 +938,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, float32_list_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should still only have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
   }
@@ -951,7 +952,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, float32_list_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should now have two allocation samples.
     EXPECT_EQ(2, profile.sample_count());
   }
@@ -981,7 +982,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, one_byte_string_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have no allocation samples.
     EXPECT_EQ(0, profile.sample_count());
   }
@@ -995,7 +996,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, one_byte_string_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should still only have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
     ProfileTrieWalker walker(&profile);
@@ -1017,7 +1018,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, one_byte_string_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should still only have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
   }
@@ -1031,7 +1032,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, one_byte_string_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should now have two allocation samples.
     EXPECT_EQ(2, profile.sample_count());
   }
@@ -1061,7 +1062,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, one_byte_string_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have no allocation samples.
     EXPECT_EQ(0, profile.sample_count());
   }
@@ -1075,7 +1076,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, one_byte_string_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should still only have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
     ProfileTrieWalker walker(&profile);
@@ -1101,7 +1102,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, one_byte_string_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should still only have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
   }
@@ -1115,7 +1116,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, one_byte_string_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should now have two allocation samples.
     EXPECT_EQ(2, profile.sample_count());
   }
@@ -1150,6 +1151,8 @@
       "  B.boo(true);\n"
       "}\n";
 
+  const bool old_flag = FLAG_background_compilation;
+  FLAG_background_compilation = false;
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
   Library& root_library = Library::Handle();
@@ -1173,7 +1176,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, class_a.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have no allocation samples.
     EXPECT_EQ(0, profile.sample_count());
   }
@@ -1192,7 +1195,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, class_a.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have 50,000 allocation samples.
     EXPECT_EQ(50000, profile.sample_count());
     ProfileTrieWalker walker(&profile);
@@ -1294,7 +1297,8 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, class_a.id());
-    profile.Build(&filter,
+    profile.Build(thread,
+                  &filter,
                   Profile::kNoTags,
                   ProfilerService::kCodeTransitionTagsBit);
     // We should have 50,000 allocation samples.
@@ -1365,6 +1369,7 @@
     EXPECT_STREQ("[Inline End]", walker.CurrentName());
     EXPECT(!walker.Down());
   }
+  FLAG_background_compilation = old_flag;
 }
 
 
@@ -1426,7 +1431,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, class_a.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have 1 allocation sample.
     EXPECT_EQ(1, profile.sample_count());
     ProfileTrieWalker walker(&profile);
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index 47fa009..74013a6 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -556,9 +556,6 @@
 intptr_t RawInstructions::VisitInstructionsPointers(
     RawInstructions* raw_obj, ObjectPointerVisitor* visitor) {
   RawInstructions* obj = raw_obj->ptr();
-  if (!Dart::IsRunningPrecompiledCode()) {
-    visitor->VisitPointers(raw_obj->from(), raw_obj->to());
-  }
   return Instructions::InstanceSize(obj->size_);
 }
 
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index bc68552..9b335eb 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -626,6 +626,7 @@
   friend class WeakProperty;  // StorePointer
   friend class Instance;  // StorePointer
   friend class StackFrame;  // GetCodeObject assertion.
+  friend class CodeLookupTableBuilder;  // profiler
 
   DISALLOW_ALLOCATION();
   DISALLOW_IMPLICIT_CONSTRUCTORS(RawObject);
@@ -650,7 +651,6 @@
   RawArray* functions_hash_table_;
   RawArray* fields_;
   RawArray* offset_in_words_to_field_;
-  RawGrowableObjectArray* closure_functions_;  // Local functions and literals.
   RawArray* interfaces_;  // Array of AbstractType.
   RawGrowableObjectArray* direct_subclasses_;  // Array of Class.
   RawScript* script_;
@@ -658,7 +658,6 @@
   RawTypeArguments* type_parameters_;  // Array of TypeParameter.
   RawAbstractType* super_type_;
   RawType* mixin_;  // Generic mixin type, e.g. M<T>, not M<int>.
-  RawClass* patch_class_;
   RawFunction* signature_function_;  // Associated function for signature class.
   RawArray* constants_;  // Canonicalized values of this class.
   RawObject* canonical_types_;  // An array of canonicalized types of this class
@@ -919,7 +918,7 @@
     return reinterpret_cast<RawObject**>(&ptr()->private_key_);
   }
   RawString* private_key_;  // Key used for private identifiers.
-  RawArray* token_objects_;
+  RawGrowableObjectArray* token_objects_;
   RawExternalTypedData* stream_;
   RawObject** to() {
     return reinterpret_cast<RawObject**>(&ptr()->stream_);
@@ -944,6 +943,9 @@
 
   RawObject** from() { return reinterpret_cast<RawObject**>(&ptr()->url_); }
   RawString* url_;
+  RawObject** to_precompiled_snapshot() {
+    return reinterpret_cast<RawObject**>(&ptr()->url_);
+  }
   RawTokenStream* tokens_;
   RawObject** to_snapshot() {
     return reinterpret_cast<RawObject**>(&ptr()->tokens_);
@@ -976,6 +978,7 @@
   RawArray* dictionary_;         // Top-level names in this library.
   RawGrowableObjectArray* metadata_;  // Metadata on classes, methods etc.
   RawArray* anonymous_classes_;  // Classes containing top-level elements.
+  RawGrowableObjectArray* patch_classes_;
   RawArray* imports_;            // List of Namespaces imported without prefix.
   RawArray* exports_;            // List of re-exported Namespaces.
   RawInstance* load_error_;      // Error iff load_state_ == kLoadError.
@@ -1045,9 +1048,12 @@
   RawObject* owner_;  // Function, Null, or a Class.
   RawExceptionHandlers* exception_handlers_;
   RawPcDescriptors* pc_descriptors_;
+  RawArray* stackmaps_;
+  RawObject** to_snapshot() {
+    return reinterpret_cast<RawObject**>(&ptr()->stackmaps_);
+  }
   RawArray* deopt_info_array_;
   RawArray* static_calls_target_table_;  // (code-offset, function, code).
-  RawArray* stackmaps_;
   RawLocalVarDescriptors* var_descriptors_;
   RawArray* inlined_metadata_;
   RawArray* comments_;
@@ -1109,14 +1115,6 @@
 class RawInstructions : public RawObject {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Instructions);
 
-  RawObject** from() {
-    return reinterpret_cast<RawObject**>(&ptr()->code_);
-  }
-  RawCode* code_;
-  RawObject** to() {
-    return reinterpret_cast<RawObject**>(&ptr()->code_);
-  }
-
   int32_t size_;
 
   // Variable length data follows here.
@@ -1421,8 +1419,10 @@
   }
   RawArray* buckets_;
   RawSmi* mask_;
+  RawString* target_name_;     // Name of target function.
+  RawArray* args_descriptor_;  // Arguments descriptor.
   RawObject** to() {
-    return reinterpret_cast<RawObject**>(&ptr()->mask_);
+    return reinterpret_cast<RawObject**>(&ptr()->args_descriptor_);
   }
 
   int32_t filled_entry_count_;
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 8a65fdb..c492b79 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -668,13 +668,20 @@
     // Set all the non object fields.
     func.set_token_pos(reader->Read<int32_t>());
     func.set_end_token_pos(reader->Read<int32_t>());
-    func.set_usage_counter(reader->Read<int32_t>());
     func.set_num_fixed_parameters(reader->Read<int16_t>());
     func.set_num_optional_parameters(reader->Read<int16_t>());
-    func.set_deoptimization_counter(reader->Read<int16_t>());
     func.set_kind_tag(reader->Read<uint32_t>());
-    func.set_optimized_instruction_count(reader->Read<uint16_t>());
-    func.set_optimized_call_site_count(reader->Read<uint16_t>());
+    if (reader->snapshot_code()) {
+      func.set_usage_counter(0);
+      func.set_deoptimization_counter(0);
+      func.set_optimized_instruction_count(0);
+      func.set_optimized_call_site_count(0);
+    } else {
+      func.set_usage_counter(reader->Read<int32_t>());
+      func.set_deoptimization_counter(reader->Read<int16_t>());
+      func.set_optimized_instruction_count(reader->Read<uint16_t>());
+      func.set_optimized_call_site_count(reader->Read<uint16_t>());
+    }
 
     // Set all the object fields.
     READ_OBJECT_FIELDS(func,
@@ -741,17 +748,21 @@
     // Write out all the non object fields.
     writer->Write<int32_t>(ptr()->token_pos_);
     writer->Write<int32_t>(ptr()->end_token_pos_);
-    if (is_optimized) {
-      writer->Write<int32_t>(FLAG_optimization_counter_threshold);
-    } else {
-      writer->Write<int32_t>(0);
-    }
     writer->Write<int16_t>(ptr()->num_fixed_parameters_);
     writer->Write<int16_t>(ptr()->num_optional_parameters_);
-    writer->Write<int16_t>(ptr()->deoptimization_counter_);
     writer->Write<uint32_t>(ptr()->kind_tag_);
-    writer->Write<uint16_t>(ptr()->optimized_instruction_count_);
-    writer->Write<uint16_t>(ptr()->optimized_call_site_count_);
+    if (writer->snapshot_code()) {
+      // Omit fields used to support de/reoptimization.
+    } else {
+      if (is_optimized) {
+        writer->Write<int32_t>(FLAG_optimization_counter_threshold);
+      } else {
+        writer->Write<int32_t>(0);
+      }
+      writer->Write<int16_t>(ptr()->deoptimization_counter_);
+      writer->Write<uint16_t>(ptr()->optimized_instruction_count_);
+      writer->Write<uint16_t>(ptr()->optimized_call_site_count_);
+    }
 
     // Write out all the object pointer fields.
     SnapshotWriterVisitor visitor(writer, kAsReference);
@@ -984,18 +995,23 @@
   script.StoreNonPointer(&script.raw_ptr()->kind_,
                          reader->Read<int8_t>());
 
+  *reader->StringHandle() ^= String::null();
+  script.set_source(*reader->StringHandle());
+  *reader->StreamHandle() ^= TokenStream::null();
+  script.set_tokens(*reader->StreamHandle());
+
   // Set all the object fields.
   // TODO(5411462): Need to assert No GC can happen here, even though
   // allocations may happen.
-  intptr_t num_flds = (script.raw()->to_snapshot() - script.raw()->from());
+  RawObject** toobj = reader->snapshot_code()
+      ? script.raw()->to_precompiled_snapshot()
+      : script.raw()->to_snapshot();
+  intptr_t num_flds = (toobj - script.raw()->from());
   for (intptr_t i = 0; i <= num_flds; i++) {
     (*reader->PassiveObjectHandle()) = reader->ReadObjectImpl(kAsReference);
     script.StorePointer((script.raw()->from() + i),
                         reader->PassiveObjectHandle()->raw());
   }
-  // Script wasn't allocated with nulls?
-  *reader->StringHandle() ^= String::null();
-  script.set_source(*reader->StringHandle());
 
   return script.raw();
 }
@@ -1023,7 +1039,9 @@
 
   // Write out all the object pointer fields.
   SnapshotWriterVisitor visitor(writer, kAsReference);
-  visitor.VisitPointers(from(), to_snapshot());
+  RawObject** toobj = writer->snapshot_code() ? to_precompiled_snapshot()
+                                              : to_snapshot();
+  visitor.VisitPointers(from(), toobj);
 }
 
 
@@ -1247,14 +1265,19 @@
   Code& result = Code::ZoneHandle(reader->zone(), NEW_OBJECT_WITH_LEN(Code, 0));
   reader->AddBackRef(object_id, &result, kIsDeserialized);
 
-  result.set_compile_timestamp(reader->Read<int64_t>());
+  result.set_compile_timestamp(0);
   result.set_state_bits(reader->Read<int32_t>());
-  result.set_lazy_deopt_pc_offset(reader->Read<int32_t>());
+  result.set_lazy_deopt_pc_offset(-1);
 
   // Set all the object fields.
   READ_OBJECT_FIELDS(result,
-                     result.raw()->from(), result.raw()->to(),
+                     result.raw()->from(), result.raw()->to_snapshot(),
                      kAsReference);
+  for (RawObject** ptr = result.raw()->to();
+       ptr > result.raw()->to_snapshot();
+       ptr--) {
+    result.StorePointer(ptr, Object::null());
+  }
 
   // Fix entry point.
   uword new_entry = result.EntryPoint();
@@ -1276,7 +1299,7 @@
       Code::PtrOffBits::decode(ptr()->state_bits_);
   if (pointer_offsets_length != 0) {
     // Should only be IA32.
-    FATAL("Serializing embedded pointer offsets unimplemented");
+    FATAL("Cannot serialize code with embedded pointers");
   }
 
   // Write out the serialization header value for this object.
@@ -1287,13 +1310,11 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out all the non object fields.
-  writer->Write<int64_t>(ptr()->compile_timestamp_);
   writer->Write<int32_t>(ptr()->state_bits_);
-  writer->Write<int32_t>(ptr()->lazy_deopt_pc_offset_);
 
   // Write out all the object pointer fields.
   SnapshotWriterVisitor visitor(writer, kAsReference);
-  visitor.VisitPointers(from(), to());
+  visitor.VisitPointers(from(), to_snapshot());
 
   writer->SetInstructionsCode(ptr()->instructions_, this);
 }
@@ -1349,49 +1370,54 @@
   ASSERT(reader->snapshot_code());
   ASSERT(kind == Snapshot::kFull);
 
-  intptr_t length = reader->Read<intptr_t>();
-
-  ObjectPool* result =
-      reinterpret_cast<ObjectPool*>(reader->GetBackRef(object_id));
-  if (result == NULL) {
-    result =
-        &(ObjectPool::ZoneHandle(reader->zone(),
-                                 NEW_OBJECT_WITH_LEN(ObjectPool, length)));
-    reader->AddBackRef(object_id, result, kIsDeserialized);
+  intptr_t len = reader->Read<intptr_t>();
+  ObjectPool* result = NULL;
+  DeserializeState state;
+  if (!as_reference) {
+    result = reinterpret_cast<ObjectPool*>(reader->GetBackRef(object_id));
+    state = kIsDeserialized;
+  } else {
+    state = kIsNotDeserialized;
   }
+  if (result == NULL) {
+    result = &(ObjectPool::ZoneHandle(
+        reader->zone(), NEW_OBJECT_WITH_LEN(ObjectPool, len)));
+    reader->AddBackRef(object_id, result, state);
+  }
+  if (!as_reference) {
+    // Read all the individual elements for inlined objects.
+    const TypedData& info_array =
+        TypedData::Handle(reader->NewTypedData(kTypedDataInt8ArrayCid, len));
+    result->set_info_array(info_array);
 
-  const TypedData& info_array =
-      TypedData::Handle(reader->NewTypedData(kTypedDataInt8ArrayCid, length));
-  result->set_info_array(info_array);
-
-  NoSafepointScope no_safepoint;
-  for (intptr_t i = 0; i < length; i++) {
-    ObjectPool::EntryType entry_type =
-        static_cast<ObjectPool::EntryType>(reader->Read<int8_t>());
-    *reinterpret_cast<int8_t*>(info_array.DataAddr(i)) = entry_type;
-    switch (entry_type) {
-      case ObjectPool::kTaggedObject: {
-        (*reader->PassiveObjectHandle()) =
-            reader->ReadObjectImpl(kAsReference);
-        result->SetObjectAt(i, *(reader->PassiveObjectHandle()));
-        break;
+    NoSafepointScope no_safepoint;
+    for (intptr_t i = 0; i < len; i++) {
+      ObjectPool::EntryType entry_type =
+          static_cast<ObjectPool::EntryType>(reader->Read<int8_t>());
+      *reinterpret_cast<int8_t*>(info_array.DataAddr(i)) = entry_type;
+      switch (entry_type) {
+        case ObjectPool::kTaggedObject: {
+          (*reader->PassiveObjectHandle()) =
+              reader->ReadObjectImpl(kAsReference);
+          result->SetObjectAt(i, *(reader->PassiveObjectHandle()));
+          break;
+        }
+        case ObjectPool::kImmediate: {
+          intptr_t raw_value = reader->Read<intptr_t>();
+          result->SetRawValueAt(i, raw_value);
+          break;
+        }
+        case ObjectPool::kNativeEntry: {
+          // Read nothing. Initialize with the lazy link entry.
+          uword new_entry = NativeEntry::LinkNativeCallEntry();
+          result->SetRawValueAt(i, static_cast<intptr_t>(new_entry));
+          break;
+        }
+        default:
+          UNREACHABLE();
       }
-      case ObjectPool::kImmediate: {
-        intptr_t raw_value = reader->Read<intptr_t>();
-        result->SetRawValueAt(i, raw_value);
-        break;
-      }
-      case ObjectPool::kNativeEntry: {
-        // Read nothing. Initialize with the lazy link entry.
-        uword new_entry = NativeEntry::LinkNativeCallEntry();
-        result->SetRawValueAt(i, static_cast<intptr_t>(new_entry));
-        break;
-      }
-      default:
-        UNREACHABLE();
     }
   }
-
   return result->raw();
 }
 
@@ -2563,15 +2589,24 @@
 
   // Read the length so that we can determine instance size to allocate.
   intptr_t len = reader->ReadSmiValue();
-  Array* array = reinterpret_cast<Array*>(
-      reader->GetBackRef(object_id));
+  Array* array = NULL;
+  DeserializeState state;
+  if (!as_reference) {
+    array = reinterpret_cast<Array*>(reader->GetBackRef(object_id));
+    state = kIsDeserialized;
+  } else {
+    state = kIsNotDeserialized;
+  }
   if (array == NULL) {
     array = &(Array::ZoneHandle(reader->zone(),
                                 NEW_OBJECT_WITH_LEN_SPACE(Array, len, kind)));
-    reader->AddBackRef(object_id, array, kIsDeserialized);
+    reader->AddBackRef(object_id, array, state);
   }
-  ASSERT(!RawObject::IsCanonical(tags));
-  reader->ArrayReadFrom(object_id, *array, len, tags);
+  if (!as_reference) {
+    // Read all the individual elements for inlined objects.
+    ASSERT(!RawObject::IsCanonical(tags));
+    reader->ArrayReadFrom(object_id, *array, len, tags);
+  }
   return array->raw();
 }
 
@@ -2585,19 +2620,29 @@
 
   // Read the length so that we can determine instance size to allocate.
   intptr_t len = reader->ReadSmiValue();
-  Array* array = reinterpret_cast<Array*>(reader->GetBackRef(object_id));
+  Array* array = NULL;
+  DeserializeState state;
+  if (!as_reference) {
+    array = reinterpret_cast<Array*>(reader->GetBackRef(object_id));
+    state = kIsDeserialized;
+  } else {
+    state = kIsNotDeserialized;
+  }
   if (array == NULL) {
     array = &(Array::ZoneHandle(
         reader->zone(),
         NEW_OBJECT_WITH_LEN_SPACE(ImmutableArray, len, kind)));
-    reader->AddBackRef(object_id, array, kIsDeserialized);
+    reader->AddBackRef(object_id, array, state);
   }
-  reader->ArrayReadFrom(object_id, *array, len, tags);
-  if (RawObject::IsCanonical(tags)) {
-    if (kind == Snapshot::kFull) {
-      array->SetCanonical();
-    } else {
-      *array ^= array->CheckAndCanonicalize(NULL);
+  if (!as_reference) {
+    // Read all the individual elements for inlined objects.
+    reader->ArrayReadFrom(object_id, *array, len, tags);
+    if (RawObject::IsCanonical(tags)) {
+      if (kind == Snapshot::kFull) {
+        array->SetCanonical();
+      } else {
+        *array ^= array->CheckAndCanonicalize(NULL);
+      }
     }
   }
   return raw(*array);
@@ -3316,11 +3361,9 @@
                                 Snapshot::Kind kind,
                                 bool as_reference) {
   ASSERT(reader != NULL);
-  ASSERT(kind == Snapshot::kMessage);
 
   // Allocate JSRegExp object.
-  JSRegExp& regex = JSRegExp::ZoneHandle(
-      reader->zone(), JSRegExp::New(HEAP_SPACE(kind)));
+  JSRegExp& regex = JSRegExp::ZoneHandle(reader->zone(), NEW_OBJECT(JSRegExp));
   reader->AddBackRef(object_id, &regex, kIsDeserialized);
 
   // Read and Set all the other fields.
@@ -3334,6 +3377,16 @@
                         reader->Read<int8_t>());
 
   // TODO(18854): Need to implement a way of recreating the irrexp functions.
+  const Function& no_function = Function::Handle(reader->zone());
+  regex.set_function(kOneByteStringCid, no_function);
+  regex.set_function(kTwoByteStringCid, no_function);
+  regex.set_function(kExternalOneByteStringCid, no_function);
+  regex.set_function(kExternalTwoByteStringCid, no_function);
+
+  const TypedData& no_bytecode = TypedData::Handle(reader->zone());
+  regex.set_bytecode(true, no_bytecode);
+  regex.set_bytecode(false, no_bytecode);
+
   return regex.raw();
 }
 
@@ -3343,7 +3396,6 @@
                           Snapshot::Kind kind,
                           bool as_reference) {
   ASSERT(writer != NULL);
-  ASSERT(kind == Snapshot::kMessage);
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -3369,7 +3421,7 @@
 
   // Allocate the weak property object.
   WeakProperty& weak_property = WeakProperty::ZoneHandle(
-      reader->zone(), WeakProperty::New(HEAP_SPACE(kind)));
+      reader->zone(), NEW_OBJECT(WeakProperty));
   reader->AddBackRef(object_id, &weak_property, kIsDeserialized);
 
   // Set all the object fields.
diff --git a/runtime/vm/regexp_assembler_ir.cc b/runtime/vm/regexp_assembler_ir.cc
index 82c314f..7d4cff2 100644
--- a/runtime/vm/regexp_assembler_ir.cc
+++ b/runtime/vm/regexp_assembler_ir.cc
@@ -112,7 +112,7 @@
       new(zone) GraphEntryInstr(
         *parsed_function_,
         new(zone) TargetEntryInstr(block_id_.Alloc(), kInvalidTryIndex),
-        Thread::kNoDeoptId);
+        Compiler::kNoOSRDeoptId);
   start_block_ =
       new(zone) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex);
   success_block_ =
diff --git a/runtime/vm/report.cc b/runtime/vm/report.cc
index e65391d..d09d2a9 100644
--- a/runtime/vm/report.cc
+++ b/runtime/vm/report.cc
@@ -152,7 +152,7 @@
       if (kind == kJSWarning) {
         TraceJSWarning(script, token_pos, msg);
         // Do not print stacktrace if we have not executed Dart code yet.
-        if (Isolate::Current()->top_exit_frame_info() != 0) {
+        if (Thread::Current()->top_exit_frame_info() != 0) {
           const Stacktrace& stacktrace =
               Stacktrace::Handle(Exceptions::CurrentStacktrace());
           intptr_t idx = 0;
diff --git a/runtime/vm/resolver.cc b/runtime/vm/resolver.cc
index d9fe847..b0ae79b 100644
--- a/runtime/vm/resolver.cc
+++ b/runtime/vm/resolver.cc
@@ -59,47 +59,6 @@
 }
 
 
-// Method extractors are used to create implicit closures from methods.
-// When an expression obj.M is evaluated for the first time and receiver obj
-// does not have a getter called M but has a method called M then an extractor
-// is created and injected as a getter (under the name get:M) into the class
-// owning method M.
-static RawFunction* CreateMethodExtractor(const String& getter_name,
-                                          const Function& method) {
-  ASSERT(FLAG_lazy_dispatchers);
-  const Function& closure_function =
-      Function::Handle(method.ImplicitClosureFunction());
-
-  const Class& owner = Class::Handle(closure_function.Owner());
-  Function& extractor = Function::Handle(
-    Function::New(String::Handle(Symbols::New(getter_name)),
-                  RawFunction::kMethodExtractor,
-                  false,  // Not static.
-                  false,  // Not const.
-                  false,  // Not abstract.
-                  false,  // Not external.
-                  false,  // Not native.
-                  owner,
-                  0));  // No token position.
-
-  // Initialize signature: receiver is a single fixed parameter.
-  const intptr_t kNumParameters = 1;
-  extractor.set_num_fixed_parameters(kNumParameters);
-  extractor.SetNumOptionalParameters(0, 0);
-  extractor.set_parameter_types(Object::extractor_parameter_types());
-  extractor.set_parameter_names(Object::extractor_parameter_names());
-  extractor.set_result_type(Type::Handle(Type::DynamicType()));
-
-  extractor.set_extracted_method_closure(closure_function);
-  extractor.set_is_debuggable(false);
-  extractor.set_is_visible(false);
-
-  owner.AddFunction(extractor);
-
-  return extractor.raw();
-}
-
-
 RawFunction* Resolver::ResolveDynamicAnyArgs(
     const Class& receiver_class,
     const String& function_name) {
@@ -116,10 +75,6 @@
     field_name ^= Field::NameFromGetter(function_name);
 
     if (field_name.CharAt(0) == '#') {
-      if (!FLAG_lazy_dispatchers) {
-        return Function::null();
-      }
-
       // Resolving a getter "get:#..." is a request to closurize an instance
       // property of the receiver object. It can be of the form:
       //  - get:#id, which closurizes a method or getter id
@@ -127,28 +82,28 @@
       //  - get:#operator, eg. get:#<<, which closurizes an operator method.
       // If the property can be resolved, a method extractor function
       // "get:#..." is created and injected into the receiver's class.
-      String& property_name = String::Handle(String::SubString(field_name, 1));
-      ASSERT(!Field::IsGetterName(property_name));
+      field_name = String::SubString(field_name, 1);
+      ASSERT(!Field::IsGetterName(field_name));
 
       String& property_getter_name = String::Handle();
-      if (!Field::IsSetterName(property_name)) {
+      if (!Field::IsSetterName(field_name)) {
         // If this is not a setter, we need to look for both the regular
         // name and the getter name. (In the case of an operator, this
         // code will also try to resolve for example get:<< and will fail,
         // but that's harmless.)
-        property_getter_name = Field::GetterName(property_name);
+        property_getter_name = Field::GetterName(field_name);
       }
 
       Function& function = Function::Handle();
       while (!cls.IsNull()) {
-        function = cls.LookupDynamicFunction(property_name);
+        function = cls.LookupDynamicFunction(field_name);
         if (!function.IsNull()) {
-          return CreateMethodExtractor(function_name, function);
+          return function.GetMethodExtractor(function_name);
         }
         if (!property_getter_name.IsNull()) {
           function = cls.LookupDynamicFunction(property_getter_name);
           if (!function.IsNull()) {
-            return CreateMethodExtractor(function_name, function);
+            return function.GetMethodExtractor(function_name);
           }
         }
         cls = cls.SuperClass();
@@ -172,7 +127,9 @@
         if (!function.IsNull()) {
           // We were looking for the getter but found a method with the same
           // name. Create a method extractor and return it.
-          function ^= CreateMethodExtractor(function_name, function);
+          // The extractor does not exist yet, so using GetMethodExtractor is
+          // not necessary here.
+          function ^= function.CreateMethodExtractor(function_name);
           return function.raw();
         }
       }
diff --git a/runtime/vm/runtime_entry_arm.cc b/runtime/vm/runtime_entry_arm.cc
index a2c9d49..35e15ea 100644
--- a/runtime/vm/runtime_entry_arm.cc
+++ b/runtime/vm/runtime_entry_arm.cc
@@ -42,7 +42,7 @@
 // Generate code to call into the stub which will call the runtime
 // function. Input for the stub is as follows:
 //   SP : points to the arguments and return value array.
-//   R5 : address of the runtime function to call.
+//   R9 : address of the runtime function to call.
 //   R4 : number of arguments to the call.
 void RuntimeEntry::Call(Assembler* assembler, intptr_t argument_count) const {
   if (is_leaf()) {
@@ -51,7 +51,7 @@
   } else {
     // Argument count is not checked here, but in the runtime entry for a more
     // informative error message.
-    __ LoadFromOffset(kWord, R5, THR, Thread::OffsetFromThread(this));
+    __ LoadFromOffset(kWord, R9, THR, Thread::OffsetFromThread(this));
     __ LoadImmediate(R4, argument_count);
     __ BranchLink(*StubCode::CallToRuntime_entry(), kNotPatchable);
   }
diff --git a/runtime/vm/scopes.h b/runtime/vm/scopes.h
index 5faf502..e68a244 100644
--- a/runtime/vm/scopes.h
+++ b/runtime/vm/scopes.h
@@ -34,7 +34,7 @@
       is_invisible_(false),
       is_captured_parameter_(false),
       index_(LocalVariable::kUninitializedIndex) {
-    ASSERT(type.IsZoneHandle());
+    ASSERT(type.IsZoneHandle() || type.IsReadOnlyHandle());
     ASSERT(type.IsFinalized());
     ASSERT(name.IsSymbol());
   }
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 450aadc..50d1aa4 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -103,7 +103,7 @@
 // Support for streams defined in embedders.
 Dart_ServiceStreamListenCallback Service::stream_listen_callback_ = NULL;
 Dart_ServiceStreamCancelCallback Service::stream_cancel_callback_ = NULL;
-
+Dart_GetVMServiceAssetsArchive Service::get_service_assets_callback_ = NULL;
 
 // These are the set of streams known to the core VM.
 StreamInfo Service::vm_stream("VM");
@@ -144,6 +144,7 @@
   return false;
 }
 
+
 void Service::CancelStream(const char* stream_id) {
   if (FLAG_trace_service) {
     OS::Print("vm-service: stopping stream '%s'\n",
@@ -162,11 +163,49 @@
   }
 }
 
+RawObject* Service::RequestAssets() {
+  Thread* T = Thread::Current();
+  Api::Scope api_scope(T);
+  if (get_service_assets_callback_ == NULL) {
+    return Object::null();
+  }
+  Dart_Handle handle = get_service_assets_callback_();
+  if (Dart_IsError(handle)) {
+    Dart_PropagateError(handle);
+  }
+  const Object& object = Object::Handle(Api::UnwrapHandle(handle));
+  if (object.IsNull()) {
+    return Object::null();
+  }
+  if (!object.IsTypedData()) {
+    const String& error_message =
+        String::Handle(
+            String::New("An implementation of Dart_GetVMServiceAssetsArchive "
+                        "should return a Uint8Array or null."));
+    const Error& error = Error::Handle(ApiError::New(error_message));
+    Exceptions::PropagateError(error);
+    return Object::null();
+  }
+  const TypedData& typed_data = TypedData::Cast(object);
+  if (typed_data.ElementSizeInBytes() != 1) {
+    const String& error_message =
+        String::Handle(
+            String::New("An implementation of Dart_GetVMServiceAssetsArchive "
+                        "should return a Uint8Array or null."));
+    const Error& error = Error::Handle(ApiError::New(error_message));
+    Exceptions::PropagateError(error);
+    return Object::null();
+  }
+  return Api::UnwrapHandle(handle);
+}
+
+
 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) {
   void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size);
   return reinterpret_cast<uint8_t*>(new_ptr);
 }
 
+
 static void PrintMissingParamError(JSONStream* js,
                                    const char* param) {
   js->PrintError(kInvalidParams,
@@ -490,7 +529,7 @@
 }
 
 
-typedef bool (*ServiceMethodEntry)(Isolate* isolate, JSONStream* js);
+typedef bool (*ServiceMethodEntry)(Thread* thread, JSONStream* js);
 
 
 struct ServiceMethodDescriptor {
@@ -611,7 +650,7 @@
         js.PostReply();
         return;
       }
-      if (method->entry(I, &js)) {
+      if (method->entry(T, &js)) {
         js.PostReply();
       } else {
         // NOTE(turnidge): All message handlers currently return true,
@@ -925,6 +964,12 @@
 }
 
 
+void Service::SetGetServiceAssetsCallback(
+    Dart_GetVMServiceAssetsArchive get_service_assets) {
+  get_service_assets_callback_ = get_service_assets;
+}
+
+
 EmbedderServiceHandler* Service::FindRootEmbedderHandler(
     const char* name) {
   EmbedderServiceHandler* current = root_service_handler_head_;
@@ -966,8 +1011,8 @@
 };
 
 
-static bool GetIsolate(Isolate* isolate, JSONStream* js) {
-  isolate->PrintJSON(js, false);
+static bool GetIsolate(Thread* thread, JSONStream* js) {
+  thread->isolate()->PrintJSON(js, false);
   return true;
 }
 
@@ -979,7 +1024,13 @@
 };
 
 
-static bool GetStack(Isolate* isolate, JSONStream* js) {
+static bool GetStack(Thread* thread, JSONStream* js) {
+  if (!thread->isolate()->compilation_allowed()) {
+    js->PrintError(kFeatureDisabled,
+        "Cannot get stack when running a precompiled program.");
+    return true;
+  }
+  Isolate* isolate = thread->isolate();
   DebuggerStackTrace* stack = isolate->debugger()->StackTrace();
   // Do we want the complete script object and complete local variable objects?
   // This is true for dump requests.
@@ -1044,20 +1095,20 @@
 }
 
 
-static bool TriggerEchoEvent(Isolate* isolate, JSONStream* js) {
+static bool TriggerEchoEvent(Thread* thread, JSONStream* js) {
   if (Service::echo_stream.enabled()) {
-    Service::SendEchoEvent(isolate, js->LookupParam("text"));
+    Service::SendEchoEvent(thread->isolate(), js->LookupParam("text"));
   }
   JSONObject jsobj(js);
   return HandleCommonEcho(&jsobj, js);
 }
 
 
-static bool DumpIdZone(Isolate* isolate, JSONStream* js) {
+static bool DumpIdZone(Thread* thread, JSONStream* js) {
   // TODO(johnmccutchan): Respect _idZone parameter passed to RPC. For now,
   // always send the ObjectIdRing.
   //
-  ObjectIdRing* ring = isolate->object_id_ring();
+  ObjectIdRing* ring = thread->isolate()->object_id_ring();
   ASSERT(ring != NULL);
   // When printing the ObjectIdRing, force object id reuse policy.
   RingServiceIdZone reuse_zone;
@@ -1068,7 +1119,7 @@
 }
 
 
-static bool Echo(Isolate* isolate, JSONStream* js) {
+static bool Echo(Thread* thread, JSONStream* js) {
   JSONObject jsobj(js);
   return HandleCommonEcho(&jsobj, js);
 }
@@ -1101,7 +1152,7 @@
 }
 
 
-static RawObject* LookupObjectId(Isolate* isolate,
+static RawObject* LookupObjectId(Thread* thread,
                                  const char* arg,
                                  ObjectIdRing::LookupResult* kind) {
   *kind = ObjectIdRing::kValid;
@@ -1113,7 +1164,7 @@
       *kind = ObjectIdRing::kInvalid;
       return Object::null();
     }
-    const Integer& obj = Integer::Handle(isolate->current_zone(),
+    const Integer& obj = Integer::Handle(thread->zone(),
         Smi::New(static_cast<intptr_t>(value)));
     return obj.raw();
   } else if (strcmp(arg, "bool-true") == 0) {
@@ -1124,7 +1175,7 @@
     return Object::null();
   }
 
-  ObjectIdRing* ring = isolate->object_id_ring();
+  ObjectIdRing* ring = thread->isolate()->object_id_ring();
   ASSERT(ring != NULL);
   intptr_t id = -1;
   if (!GetIntegerId(arg, &id)) {
@@ -1185,19 +1236,21 @@
   return Object::sentinel().raw();
 }
 
-static RawObject* LookupHeapObjectClasses(Isolate* isolate,
+static RawObject* LookupHeapObjectClasses(Thread* thread,
                                           char** parts, int num_parts) {
   // Class ids look like: "classes/17"
   if (num_parts < 2) {
     return Object::sentinel().raw();
   }
+  Isolate* isolate = thread->isolate();
+  Zone* zone = thread->zone();
   ClassTable* table = isolate->class_table();
   intptr_t id;
   if (!GetIntegerId(parts[1], &id) ||
       !table->IsValidIndex(id)) {
     return Object::sentinel().raw();
   }
-  Class& cls = Class::Handle(table->At(id));
+  Class& cls = Class::Handle(zone, table->At(id));
   if (num_parts == 2) {
     return cls.raw();
   }
@@ -1210,8 +1263,8 @@
     if (!GetIntegerId(parts[3], &id)) {
       return Object::sentinel().raw();
     }
-    Function& func = Function::Handle();
-    func ^= cls.ClosureFunctionFromIndex(id);
+    Function& func = Function::Handle(zone);
+    func ^= isolate->ClosureFunctionFromIndex(id);
     if (func.IsNull()) {
       return Object::sentinel().raw();
     }
@@ -1226,7 +1279,7 @@
     if (!GetIntegerId(parts[3], &id)) {
       return Object::sentinel().raw();
     }
-    Field& field = Field::Handle(cls.FieldFromIndex(id));
+    Field& field = Field::Handle(zone, cls.FieldFromIndex(id));
     if (field.IsNull()) {
       return Object::sentinel().raw();
     }
@@ -1238,13 +1291,12 @@
       return Object::sentinel().raw();
     }
     const char* encoded_id = parts[3];
-    String& id = String::Handle(isolate->current_zone(),
-        String::New(encoded_id));
+    String& id = String::Handle(zone, String::New(encoded_id));
     id = String::DecodeIRI(id);
     if (id.IsNull()) {
       return Object::sentinel().raw();
     }
-    Function& func = Function::Handle(cls.LookupFunction(id));
+    Function& func = Function::Handle(zone, cls.LookupFunction(id));
     if (func.IsNull()) {
       return Object::sentinel().raw();
     }
@@ -1259,7 +1311,7 @@
     if (!GetIntegerId(parts[3], &id)) {
       return Object::sentinel().raw();
     }
-    Function& func = Function::Handle();
+    Function& func = Function::Handle(zone);
     func ^= cls.ImplicitClosureFunctionFromIndex(id);
     if (func.IsNull()) {
       return Object::sentinel().raw();
@@ -1275,7 +1327,7 @@
     if (!GetIntegerId(parts[3], &id)) {
       return Object::sentinel().raw();
     }
-    Function& func = Function::Handle();
+    Function& func = Function::Handle(zone);
     func ^= cls.InvocationDispatcherFunctionFromIndex(id);
     if (func.IsNull()) {
       return Object::sentinel().raw();
@@ -1291,7 +1343,7 @@
     if (!GetIntegerId(parts[3], &id)) {
       return Object::sentinel().raw();
     }
-    Type& type = Type::Handle();
+    Type& type = Type::Handle(zone);
     type ^= cls.CanonicalTypeFromIndex(id);
     if (type.IsNull()) {
       return Object::sentinel().raw();
@@ -1304,8 +1356,9 @@
 }
 
 
-static RawObject* LookupHeapObjectTypeArguments(Isolate* isolate,
-                                          char** parts, int num_parts) {
+static RawObject* LookupHeapObjectTypeArguments(Thread* thread,
+                                                char** parts, int num_parts) {
+  Isolate* isolate = thread->isolate();
   // TypeArguments ids look like: "typearguments/17"
   if (num_parts < 2) {
     return Object::sentinel().raw();
@@ -1315,7 +1368,8 @@
     return Object::sentinel().raw();
   }
   ObjectStore* object_store = isolate->object_store();
-  const Array& table = Array::Handle(object_store->canonical_type_arguments());
+  const Array& table = Array::Handle(thread->zone(),
+                                     object_store->canonical_type_arguments());
   ASSERT(table.Length() > 0);
   const intptr_t table_size = table.Length() - 1;
   if ((id < 0) || (id >= table_size) || (table.At(id) == Object::null())) {
@@ -1373,7 +1427,7 @@
 }
 
 
-static RawObject* LookupHeapObjectMessage(Isolate* isolate,
+static RawObject* LookupHeapObjectMessage(Thread* thread,
                                           char** parts, int num_parts) {
   if (num_parts != 2) {
     return Object::sentinel().raw();
@@ -1383,7 +1437,7 @@
     return Object::sentinel().raw();
   }
   MessageHandler::AcquiredQueues aq;
-  isolate->message_handler()->AcquireQueues(&aq);
+  thread->isolate()->message_handler()->AcquireQueues(&aq);
   Message* message = aq.queue()->FindMessageById(message_id);
   if (message == NULL) {
     // The user may try to load an expired message.
@@ -1391,15 +1445,15 @@
   }
   MessageSnapshotReader reader(message->data(),
                                message->len(),
-                               Thread::Current());
+                               thread);
   return reader.ReadObject();
 }
 
 
-static RawObject* LookupHeapObject(Isolate* isolate,
+static RawObject* LookupHeapObject(Thread* thread,
                                    const char* id_original,
                                    ObjectIdRing::LookupResult* result) {
-  char* id = Thread::Current()->zone()->MakeCopyOfString(id_original);
+  char* id = thread->zone()->MakeCopyOfString(id_original);
 
   // Parse the id by splitting at each '/'.
   const int MAX_PARTS = 8;
@@ -1427,11 +1481,12 @@
     *result = ObjectIdRing::kValid;
   }
 
+  Isolate* isolate = thread->isolate();
   if (strcmp(parts[0], "objects") == 0) {
     // Object ids look like "objects/1123"
-    Object& obj = Object::Handle(isolate->current_zone());
+    Object& obj = Object::Handle(thread->zone());
     ObjectIdRing::LookupResult lookup_result;
-    obj = LookupObjectId(isolate, parts[1], &lookup_result);
+    obj = LookupObjectId(thread, parts[1], &lookup_result);
     if (lookup_result != ObjectIdRing::kValid) {
       if (result != NULL) {
         *result = lookup_result;
@@ -1443,13 +1498,13 @@
   } else if (strcmp(parts[0], "libraries") == 0) {
     return LookupHeapObjectLibraries(isolate, parts, num_parts);
   } else if (strcmp(parts[0], "classes") == 0) {
-    return LookupHeapObjectClasses(isolate, parts, num_parts);
+    return LookupHeapObjectClasses(thread, parts, num_parts);
   } else if (strcmp(parts[0], "typearguments") == 0) {
-    return LookupHeapObjectTypeArguments(isolate, parts, num_parts);
+    return LookupHeapObjectTypeArguments(thread, parts, num_parts);
   } else if (strcmp(parts[0], "code") == 0) {
     return LookupHeapObjectCode(isolate, parts, num_parts);
   } else if (strcmp(parts[0], "messages") == 0) {
-    return LookupHeapObjectMessage(isolate, parts, num_parts);
+    return LookupHeapObjectMessage(thread, parts, num_parts);
   }
 
   // Not found.
@@ -1515,11 +1570,11 @@
 }
 
 
-static bool PrintInboundReferences(Isolate* isolate,
+static bool PrintInboundReferences(Thread* thread,
                                    Object* target,
                                    intptr_t limit,
                                    JSONStream* js) {
-  ObjectGraph graph(isolate);
+  ObjectGraph graph(thread);
   Array& path = Array::Handle(Array::New(limit * 2));
   intptr_t length = graph.InboundReferences(target, path);
   JSONObject jsobj(js);
@@ -1571,10 +1626,7 @@
 };
 
 
-static bool GetInboundReferences(Isolate* isolate, JSONStream* js) {
-  Thread* thread = Thread::Current();
-  ASSERT(isolate == thread->isolate());
-
+static bool GetInboundReferences(Thread* thread, JSONStream* js) {
   const char* target_id = js->LookupParam("targetId");
   if (target_id == NULL) {
     PrintMissingParamError(js, "targetId");
@@ -1595,7 +1647,7 @@
   ObjectIdRing::LookupResult lookup_result;
   {
     HANDLESCOPE(thread);
-    obj = LookupHeapObject(isolate, target_id, &lookup_result);
+    obj = LookupHeapObject(thread, target_id, &lookup_result);
   }
   if (obj.raw() == Object::sentinel().raw()) {
     if (lookup_result == ObjectIdRing::kCollected) {
@@ -1607,15 +1659,15 @@
     }
     return true;
   }
-  return PrintInboundReferences(isolate, &obj, limit, js);
+  return PrintInboundReferences(thread, &obj, limit, js);
 }
 
 
-static bool PrintRetainingPath(Isolate* isolate,
+static bool PrintRetainingPath(Thread* thread,
                                Object* obj,
                                intptr_t limit,
                                JSONStream* js) {
-  ObjectGraph graph(isolate);
+  ObjectGraph graph(thread);
   Array& path = Array::Handle(Array::New(limit * 2));
   intptr_t length = graph.RetainingPath(obj, path);
   JSONObject jsobj(js);
@@ -1673,10 +1725,7 @@
 };
 
 
-static bool GetRetainingPath(Isolate* isolate, JSONStream* js) {
-  Thread* thread = Thread::Current();
-  ASSERT(isolate == thread->isolate());
-
+static bool GetRetainingPath(Thread* thread, JSONStream* js) {
   const char* target_id = js->LookupParam("targetId");
   if (target_id == NULL) {
     PrintMissingParamError(js, "targetId");
@@ -1697,7 +1746,7 @@
   ObjectIdRing::LookupResult lookup_result;
   {
     HANDLESCOPE(thread);
-    obj = LookupHeapObject(isolate, target_id, &lookup_result);
+    obj = LookupHeapObject(thread, target_id, &lookup_result);
   }
   if (obj.raw() == Object::sentinel().raw()) {
     if (lookup_result == ObjectIdRing::kCollected) {
@@ -1709,7 +1758,7 @@
     }
     return true;
   }
-  return PrintRetainingPath(isolate, &obj, limit, js);
+  return PrintRetainingPath(thread, &obj, limit, js);
 }
 
 
@@ -1719,14 +1768,14 @@
 };
 
 
-static bool GetRetainedSize(Isolate* isolate, JSONStream* js) {
+static bool GetRetainedSize(Thread* thread, JSONStream* js) {
   const char* target_id = js->LookupParam("targetId");
   if (target_id == NULL) {
     PrintMissingParamError(js, "targetId");
     return true;
   }
   ObjectIdRing::LookupResult lookup_result;
-  Object& obj = Object::Handle(LookupHeapObject(isolate, target_id,
+  Object& obj = Object::Handle(LookupHeapObject(thread, target_id,
                                                 &lookup_result));
   if (obj.raw() == Object::sentinel().raw()) {
     if (lookup_result == ObjectIdRing::kCollected) {
@@ -1742,14 +1791,14 @@
   // SizeRetainedByClass should be a separate RPC.
   if (obj.IsClass()) {
     const Class& cls = Class::Cast(obj);
-    ObjectGraph graph(isolate);
+    ObjectGraph graph(thread);
     intptr_t retained_size = graph.SizeRetainedByClass(cls.id());
     const Object& result = Object::Handle(Integer::New(retained_size));
     result.PrintJSON(js, true);
     return true;
   }
 
-  ObjectGraph graph(isolate);
+  ObjectGraph graph(thread);
   intptr_t retained_size = graph.SizeRetainedByInstance(obj);
   const Object& result = Object::Handle(Integer::New(retained_size));
   result.PrintJSON(js, true);
@@ -1763,8 +1812,8 @@
 };
 
 
-static bool Evaluate(Isolate* isolate, JSONStream* js) {
-  if (!isolate->compilation_allowed()) {
+static bool Evaluate(Thread* thread, JSONStream* js) {
+  if (!thread->isolate()->compilation_allowed()) {
     js->PrintError(kFeatureDisabled,
                    "Cannot evaluate when running a precompiled program.");
     return true;
@@ -1779,11 +1828,11 @@
     PrintMissingParamError(js, "expression");
     return true;
   }
-  const String& expr_str =
-      String::Handle(isolate->current_zone(), String::New(expr));
+  Zone* zone = thread->zone();
+  const String& expr_str = String::Handle(zone, String::New(expr));
   ObjectIdRing::LookupResult lookup_result;
-  Object& obj = Object::Handle(LookupHeapObject(isolate, target_id,
-                                                &lookup_result));
+  Object& obj = Object::Handle(zone, LookupHeapObject(thread, target_id,
+                                                      &lookup_result));
   if (obj.raw() == Object::sentinel().raw()) {
     if (lookup_result == ObjectIdRing::kCollected) {
       PrintSentinel(js, kCollectedSentinel);
@@ -1796,29 +1845,27 @@
   }
   if (obj.IsLibrary()) {
     const Library& lib = Library::Cast(obj);
-    const Object& result = Object::Handle(lib.Evaluate(expr_str,
-                                                       Array::empty_array(),
-                                                       Array::empty_array()));
+    const Object& result = Object::Handle(zone,
+        lib.Evaluate(expr_str, Array::empty_array(), Array::empty_array()));
     result.PrintJSON(js, true);
     return true;
   }
   if (obj.IsClass()) {
     const Class& cls = Class::Cast(obj);
-    const Object& result = Object::Handle(cls.Evaluate(expr_str,
-                                                       Array::empty_array(),
-                                                       Array::empty_array()));
+    const Object& result = Object::Handle(zone,
+        cls.Evaluate(expr_str, Array::empty_array(), Array::empty_array()));
     result.PrintJSON(js, true);
     return true;
   }
   if ((obj.IsInstance() || obj.IsNull()) &&
       !ContainsNonInstance(obj)) {
     // We don't use Instance::Cast here because it doesn't allow null.
-    Instance& instance = Instance::Handle(isolate->current_zone());
+    Instance& instance = Instance::Handle(zone);
     instance ^= obj.raw();
     const Object& result =
-        Object::Handle(instance.Evaluate(expr_str,
-                                         Array::empty_array(),
-                                         Array::empty_array()));
+        Object::Handle(zone, instance.Evaluate(expr_str,
+                                               Array::empty_array(),
+                                               Array::empty_array()));
     result.PrintJSON(js, true);
     return true;
   }
@@ -1838,7 +1885,8 @@
 };
 
 
-static bool EvaluateInFrame(Isolate* isolate, JSONStream* js) {
+static bool EvaluateInFrame(Thread* thread, JSONStream* js) {
+  Isolate* isolate = thread->isolate();
   if (!isolate->compilation_allowed()) {
     js->PrintError(kFeatureDisabled,
                    "Cannot evaluate when running a precompiled program.");
@@ -1852,11 +1900,11 @@
   }
   ActivationFrame* frame = stack->FrameAt(framePos);
 
+  Zone* zone = thread->zone();
   const char* expr = js->LookupParam("expression");
-  const String& expr_str = String::Handle(isolate->current_zone(),
-      String::New(expr));
+  const String& expr_str = String::Handle(zone, String::New(expr));
 
-  const Object& result = Object::Handle(frame->Evaluate(expr_str));
+  const Object& result = Object::Handle(zone, frame->Evaluate(expr_str));
   result.PrintJSON(js, true);
   return true;
 }
@@ -1900,7 +1948,7 @@
 };
 
 
-static bool GetInstances(Isolate* isolate, JSONStream* js) {
+static bool GetInstances(Thread* thread, JSONStream* js) {
   const char* target_id = js->LookupParam("classId");
   if (target_id == NULL) {
     PrintMissingParamError(js, "classId");
@@ -1917,7 +1965,7 @@
     return true;
   }
   const Object& obj =
-      Object::Handle(LookupHeapObject(isolate, target_id, NULL));
+      Object::Handle(LookupHeapObject(thread, target_id, NULL));
   if (obj.raw() == Object::sentinel().raw() ||
       !obj.IsClass()) {
     PrintInvalidParamError(js, "classId");
@@ -1926,7 +1974,7 @@
   const Class& cls = Class::Cast(obj);
   Array& storage = Array::Handle(Array::New(limit));
   GetInstancesVisitor visitor(cls, storage);
-  ObjectGraph graph(isolate);
+  ObjectGraph graph(thread);
   graph.IterateObjects(&visitor);
   intptr_t count = visitor.count();
   if (count < limit) {
@@ -2007,14 +2055,18 @@
 };
 
 
-static bool GetHitsOrSites(Isolate* isolate, JSONStream* js, bool as_sites) {
-  Thread* thread = Thread::Current();
+static bool GetHitsOrSites(Thread* thread, JSONStream* js, bool as_sites) {
+  if (!thread->isolate()->compilation_allowed()) {
+    js->PrintError(kFeatureDisabled,
+        "Cannot get coverage data when running a precompiled program.");
+    return true;
+  }
   if (!js->HasParam("targetId")) {
     CodeCoverage::PrintJSON(thread, js, NULL, as_sites);
     return true;
   }
   const char* target_id = js->LookupParam("targetId");
-  Object& obj = Object::Handle(LookupHeapObject(isolate, target_id, NULL));
+  Object& obj = Object::Handle(LookupHeapObject(thread, target_id, NULL));
   if (obj.raw() == Object::sentinel().raw()) {
     PrintInvalidParamError(js, "targetId");
     return true;
@@ -2055,9 +2107,9 @@
 };
 
 
-static bool GetCoverage(Isolate* isolate, JSONStream* js) {
+static bool GetCoverage(Thread* thread, JSONStream* js) {
   // TODO(rmacnak): Remove this response; it is subsumed by GetCallSiteData.
-  return GetHitsOrSites(isolate, js, false);
+  return GetHitsOrSites(thread, js, false);
 }
 
 
@@ -2068,14 +2120,19 @@
 };
 
 
-static bool GetCallSiteData(Isolate* isolate, JSONStream* js) {
-  return GetHitsOrSites(isolate, js, true);
+static bool GetCallSiteData(Thread* thread, JSONStream* js) {
+  return GetHitsOrSites(thread, js, true);
 }
 
 
-static bool AddBreakpointCommon(Isolate* isolate,
+static bool AddBreakpointCommon(Thread* thread,
                                 JSONStream* js,
                                 const String& script_uri) {
+  if (!thread->isolate()->compilation_allowed()) {
+    js->PrintError(kFeatureDisabled,
+        "Cannot use breakpoints when running a precompiled program.");
+    return true;
+  }
   const char* line_param = js->LookupParam("line");
   intptr_t line = UIntParameter::Parse(line_param);
   const char* col_param = js->LookupParam("column");
@@ -2090,7 +2147,8 @@
   }
   ASSERT(!script_uri.IsNull());
   Breakpoint* bpt = NULL;
-  bpt = isolate->debugger()->SetBreakpointAtLineCol(script_uri, line, col);
+  bpt = thread->isolate()->debugger()->
+      SetBreakpointAtLineCol(script_uri, line, col);
   if (bpt == NULL) {
     js->PrintError(kCannotAddBreakpoint,
                    "%s: Cannot add breakpoint at line '%s'",
@@ -2111,10 +2169,14 @@
 };
 
 
-static bool AddBreakpoint(Isolate* isolate, JSONStream* js) {
+static bool AddBreakpoint(Thread* thread, JSONStream* js) {
+  if (!thread->isolate()->compilation_allowed()) {
+    js->PrintError(kFeatureDisabled,
+        "Cannot use breakpoints when running a precompiled program.");
+    return true;
+  }
   const char* script_id_param = js->LookupParam("scriptId");
-  Object& obj =
-      Object::Handle(LookupHeapObject(isolate, script_id_param, NULL));
+  Object& obj = Object::Handle(LookupHeapObject(thread, script_id_param, NULL));
   if (obj.raw() == Object::sentinel().raw() || !obj.IsScript()) {
     PrintInvalidParamError(js, "scriptId");
     return true;
@@ -2122,7 +2184,7 @@
   const Script& script = Script::Cast(obj);
   const String& script_uri = String::Handle(script.url());
   ASSERT(!script_uri.IsNull());
-  return AddBreakpointCommon(isolate, js, script_uri);
+  return AddBreakpointCommon(thread, js, script_uri);
 }
 
 
@@ -2135,10 +2197,15 @@
 };
 
 
-static bool AddBreakpointWithScriptUri(Isolate* isolate, JSONStream* js) {
+static bool AddBreakpointWithScriptUri(Thread* thread, JSONStream* js) {
+  if (!thread->isolate()->compilation_allowed()) {
+    js->PrintError(kFeatureDisabled,
+        "Cannot use breakpoints when running a precompiled program.");
+    return true;
+  }
   const char* script_uri_param = js->LookupParam("scriptUri");
   const String& script_uri = String::Handle(String::New(script_uri_param));
-  return AddBreakpointCommon(isolate, js, script_uri);
+  return AddBreakpointCommon(thread, js, script_uri);
 }
 
 
@@ -2149,16 +2216,21 @@
 };
 
 
-static bool AddBreakpointAtEntry(Isolate* isolate, JSONStream* js) {
+static bool AddBreakpointAtEntry(Thread* thread, JSONStream* js) {
+  if (!thread->isolate()->compilation_allowed()) {
+    js->PrintError(kFeatureDisabled,
+        "Cannot use breakpoints when running a precompiled program.");
+    return true;
+  }
   const char* function_id = js->LookupParam("functionId");
-  Object& obj = Object::Handle(LookupHeapObject(isolate, function_id, NULL));
+  Object& obj = Object::Handle(LookupHeapObject(thread, function_id, NULL));
   if (obj.raw() == Object::sentinel().raw() || !obj.IsFunction()) {
     PrintInvalidParamError(js, "functionId");
     return true;
   }
   const Function& function = Function::Cast(obj);
   Breakpoint* bpt =
-      isolate->debugger()->SetBreakpointAtEntry(function, false);
+      thread->isolate()->debugger()->SetBreakpointAtEntry(function, false);
   if (bpt == NULL) {
     js->PrintError(kCannotAddBreakpoint,
                    "%s: Cannot add breakpoint at function '%s'",
@@ -2177,16 +2249,21 @@
 };
 
 
-static bool AddBreakpointAtActivation(Isolate* isolate, JSONStream* js) {
+static bool AddBreakpointAtActivation(Thread* thread, JSONStream* js) {
+  if (!thread->isolate()->compilation_allowed()) {
+    js->PrintError(kFeatureDisabled,
+        "Cannot use breakpoints when running a precompiled program.");
+    return true;
+  }
   const char* object_id = js->LookupParam("objectId");
-  Object& obj = Object::Handle(LookupHeapObject(isolate, object_id, NULL));
+  Object& obj = Object::Handle(LookupHeapObject(thread, object_id, NULL));
   if (obj.raw() == Object::sentinel().raw() || !obj.IsInstance()) {
     PrintInvalidParamError(js, "objectId");
     return true;
   }
   const Instance& closure = Instance::Cast(obj);
   Breakpoint* bpt =
-      isolate->debugger()->SetBreakpointAtActivation(closure);
+      thread->isolate()->debugger()->SetBreakpointAtActivation(closure);
   if (bpt == NULL) {
     js->PrintError(kCannotAddBreakpoint,
                    "%s: Cannot add breakpoint at activation",
@@ -2204,13 +2281,19 @@
 };
 
 
-static bool RemoveBreakpoint(Isolate* isolate, JSONStream* js) {
+static bool RemoveBreakpoint(Thread* thread, JSONStream* js) {
+  if (!thread->isolate()->compilation_allowed()) {
+    js->PrintError(kFeatureDisabled,
+        "Cannot use breakpoints when running a precompiled program.");
+    return true;
+  }
   if (!js->HasParam("breakpointId")) {
     PrintMissingParamError(js, "breakpointId");
     return true;
   }
   const char* bpt_id = js->LookupParam("breakpointId");
   ObjectIdRing::LookupResult lookup_result;
+  Isolate* isolate = thread->isolate();
   Breakpoint* bpt = LookupBreakpoint(isolate, bpt_id, &lookup_result);
   // TODO(turnidge): Should we return a different error for bpts whic
   // have been already removed?
@@ -2224,8 +2307,8 @@
 }
 
 
-static RawClass* GetMetricsClass(Isolate* isolate) {
-  Zone* zone = isolate->current_zone();
+static RawClass* GetMetricsClass(Thread* thread) {
+  Zone* zone = thread->zone();
   const Library& prof_lib =
       Library::Handle(zone, Library::DeveloperLibrary());
   ASSERT(!prof_lib.IsNull());
@@ -2240,12 +2323,12 @@
 
 
 
-static bool HandleNativeMetricsList(Isolate* isolate, JSONStream* js) {
+static bool HandleNativeMetricsList(Thread* thread, JSONStream* js) {
   JSONObject obj(js);
   obj.AddProperty("type", "MetricList");
   {
     JSONArray metrics(&obj, "metrics");
-    Metric* current = isolate->metrics_list_head();
+    Metric* current = thread->isolate()->metrics_list_head();
     while (current != NULL) {
       metrics.AddValue(current);
       current = current->next();
@@ -2255,10 +2338,8 @@
 }
 
 
-static bool HandleNativeMetric(Isolate* isolate,
-                                JSONStream* js,
-                                const char* id) {
-  Metric* current = isolate->metrics_list_head();
+static bool HandleNativeMetric(Thread* thread, JSONStream* js, const char* id) {
+  Metric* current = thread->isolate()->metrics_list_head();
   while (current != NULL) {
     const char* name = current->name();
     ASSERT(name != NULL);
@@ -2273,9 +2354,10 @@
 }
 
 
-static bool HandleDartMetricsList(Isolate* isolate, JSONStream* js) {
-  Zone* zone = isolate->current_zone();
-  const Class& metrics_cls = Class::Handle(zone, GetMetricsClass(isolate));
+static bool HandleDartMetricsList(Thread* thread, JSONStream* js) {
+  Zone* zone = thread->zone();
+  const Class& metrics_cls =
+      Class::Handle(zone, GetMetricsClass(thread));
   const String& print_metrics_name =
       String::Handle(String::New("_printMetrics"));
   ASSERT(!print_metrics_name.IsNull());
@@ -2294,9 +2376,10 @@
 }
 
 
-static bool HandleDartMetric(Isolate* isolate, JSONStream* js, const char* id) {
-  Zone* zone = isolate->current_zone();
-  const Class& metrics_cls = Class::Handle(zone, GetMetricsClass(isolate));
+static bool HandleDartMetric(Thread* thread, JSONStream* js, const char* id) {
+  Zone* zone = thread->zone();
+  const Class& metrics_cls =
+      Class::Handle(zone, GetMetricsClass(thread));
   const String& print_metric_name =
       String::Handle(String::New("_printMetric"));
   ASSERT(!print_metric_name.IsNull());
@@ -2328,7 +2411,7 @@
 };
 
 
-static bool GetIsolateMetricList(Isolate* isolate, JSONStream* js) {
+static bool GetIsolateMetricList(Thread* thread, JSONStream* js) {
   bool native_metrics = false;
   if (js->HasParam("type")) {
     if (js->ParamIs("type", "Native")) {
@@ -2344,9 +2427,9 @@
     return true;
   }
   if (native_metrics) {
-    return HandleNativeMetricsList(isolate, js);
+    return HandleNativeMetricsList(thread, js);
   }
-  return HandleDartMetricsList(isolate, js);
+  return HandleDartMetricsList(thread, js);
 }
 
 
@@ -2356,7 +2439,7 @@
 };
 
 
-static bool GetIsolateMetric(Isolate* isolate, JSONStream* js) {
+static bool GetIsolateMetric(Thread* thread, JSONStream* js) {
   const char* metric_id = js->LookupParam("metricId");
   if (metric_id == NULL) {
     PrintMissingParamError(js, "metricId");
@@ -2376,10 +2459,10 @@
       strncmp(metric_id, kNativeMetricIdPrefix, kNativeMetricIdPrefixLen) == 0;
   if (native_metric) {
     const char* id = metric_id + kNativeMetricIdPrefixLen;
-    return HandleNativeMetric(isolate, js, id);
+    return HandleNativeMetric(thread, js, id);
   }
   const char* id = metric_id + kMetricIdPrefixLen;
-  return HandleDartMetric(isolate, js, id);
+  return HandleDartMetric(thread, js, id);
 }
 
 
@@ -2389,7 +2472,7 @@
 };
 
 
-static bool GetVMMetricList(Isolate* isolate, JSONStream* js) {
+static bool GetVMMetricList(Thread* thread, JSONStream* js) {
   return false;
 }
 
@@ -2400,7 +2483,7 @@
 };
 
 
-static bool GetVMMetric(Isolate* isolate, JSONStream* js) {
+static bool GetVMMetric(Thread* thread, JSONStream* js) {
   const char* metric_id = js->LookupParam("metricId");
   if (metric_id == NULL) {
     PrintMissingParamError(js, "metricId");
@@ -2409,14 +2492,99 @@
 }
 
 
+static const MethodParameter* set_vm_timeline_flag_params[] = {
+  NO_ISOLATE_PARAMETER,
+  new MethodParameter("_record", true),
+  NULL,
+};
+
+
+static bool SetVMTimelineFlag(Thread* thread, JSONStream* js) {
+  Isolate* isolate = thread->isolate();
+  ASSERT(isolate != NULL);
+  StackZone zone(thread);
+
+  bool recording = strcmp(js->LookupParam("_record"), "all") == 0;
+  Timeline::SetStreamAPIEnabled(recording);
+  Timeline::SetStreamCompilerEnabled(recording);
+  Timeline::SetStreamDartEnabled(recording);
+  Timeline::SetStreamDebuggerEnabled(recording);
+  Timeline::SetStreamEmbedderEnabled(recording);
+  Timeline::SetStreamGCEnabled(recording);
+  Timeline::SetStreamIsolateEnabled(recording);
+
+  PrintSuccess(js);
+
+  return true;
+}
+
+
+static const MethodParameter* get_vm_timeline_flag_params[] = {
+  NO_ISOLATE_PARAMETER,
+  new MethodParameter("_record", false),
+  NULL,
+};
+
+
+static bool GetVMTimelineFlag(Thread* thread, JSONStream* js) {
+  Isolate* isolate = thread->isolate();
+  ASSERT(isolate != NULL);
+  StackZone zone(thread);
+
+  js->PrintError(kFeatureDisabled, "TODO(johnmccutchan)");
+  return true;
+}
+
+
+static const MethodParameter* clear_vm_timeline_params[] = {
+  NO_ISOLATE_PARAMETER,
+  NULL,
+};
+
+
+static bool ClearVMTimeline(Thread* thread, JSONStream* js) {
+  Isolate* isolate = thread->isolate();
+  ASSERT(isolate != NULL);
+  StackZone zone(thread);
+
+  Timeline::Clear();
+
+  PrintSuccess(js);
+
+  return true;
+}
+
+
+static const MethodParameter* get_vm_timeline_params[] = {
+  NO_ISOLATE_PARAMETER,
+  NULL,
+};
+
+
+static bool GetVMTimeline(Thread* thread, JSONStream* js) {
+  Isolate* isolate = thread->isolate();
+  ASSERT(isolate != NULL);
+  StackZone zone(thread);
+  Timeline::ReclaimCachedBlocksFromThreads();
+  TimelineEventRecorder* timeline_recorder = Timeline::recorder();
+  // TODO(johnmccutchan): Return an error.
+  ASSERT(timeline_recorder != NULL);
+  TimelineEventFilter filter;
+  timeline_recorder->PrintJSON(js, &filter);
+
+  return true;
+}
+
+
 static const MethodParameter* resume_params[] = {
   ISOLATE_PARAMETER,
   NULL,
 };
 
 
-static bool Resume(Isolate* isolate, JSONStream* js) {
+static bool Resume(Thread* thread, JSONStream* js) {
   const char* step_param = js->LookupParam("step");
+  Isolate* isolate = thread->isolate();
   if (isolate->message_handler()->paused_on_start()) {
     // If the user is issuing a 'Over' or an 'Out' step, that is the
     // same as a regular resume request.
@@ -2467,11 +2635,12 @@
 };
 
 
-static bool Pause(Isolate* isolate, JSONStream* js) {
+static bool Pause(Thread* thread, JSONStream* js) {
   // TODO(turnidge): This interrupt message could have been sent from
   // the service isolate directly, but would require some special case
   // code.  That would prevent this isolate getting double-interrupted
   // with OOB messages.
+  Isolate* isolate = thread->isolate();
   isolate->SendInternalLibMessage(Isolate::kInterruptMsg,
                                   isolate->pause_capability());
   PrintSuccess(js);
@@ -2485,10 +2654,10 @@
 };
 
 
-static bool GetTagProfile(Isolate* isolate, JSONStream* js) {
+static bool GetTagProfile(Thread* thread, JSONStream* js) {
   JSONObject miniProfile(js);
   miniProfile.AddProperty("type", "TagProfile");
-  isolate->vm_tag_counters()->PrintToJSONObject(&miniProfile);
+  thread->isolate()->vm_tag_counters()->PrintToJSONObject(&miniProfile);
   return true;
 }
 
@@ -2522,7 +2691,7 @@
 
 
 // TODO(johnmccutchan): Rename this to GetCpuSamples.
-static bool GetCpuProfile(Isolate* isolate, JSONStream* js) {
+static bool GetCpuProfile(Thread* thread, JSONStream* js) {
   Profile::TagOrder tag_order =
       EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values);
   intptr_t extra_tags = 0;
@@ -2542,12 +2711,13 @@
 };
 
 
-static bool GetAllocationSamples(Isolate* isolate, JSONStream* js) {
+static bool GetAllocationSamples(Thread* thread, JSONStream* js) {
   Profile::TagOrder tag_order =
       EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values);
   const char* class_id = js->LookupParam("classId");
   intptr_t cid = -1;
   GetPrefixedIntegerId(class_id, "classes/", &cid);
+  Isolate* isolate = thread->isolate();
   if (IsValidClassId(isolate, cid)) {
     const Class& cls = Class::Handle(GetClassForId(isolate, cid));
     ProfilerService::PrintAllocationJSON(js, tag_order, cls);
@@ -2564,7 +2734,7 @@
 };
 
 
-static bool ClearCpuProfile(Isolate* isolate, JSONStream* js) {
+static bool ClearCpuProfile(Thread* thread, JSONStream* js) {
   ProfilerService::ClearSamples();
   PrintSuccess(js);
   return true;
@@ -2577,7 +2747,7 @@
 };
 
 
-static bool GetAllocationProfile(Isolate* isolate, JSONStream* js) {
+static bool GetAllocationProfile(Thread* thread, JSONStream* js) {
   bool should_reset_accumulator = false;
   bool should_collect = false;
   if (js->HasParam("reset")) {
@@ -2596,6 +2766,7 @@
       return true;
     }
   }
+  Isolate* isolate = thread->isolate();
   if (should_reset_accumulator) {
     isolate->UpdateLastAllocationProfileAccumulatorResetTimestamp();
     isolate->class_table()->ResetAllocationAccumulators();
@@ -2615,7 +2786,8 @@
 };
 
 
-static bool GetHeapMap(Isolate* isolate, JSONStream* js) {
+static bool GetHeapMap(Thread* thread, JSONStream* js) {
+  Isolate* isolate = thread->isolate();
   isolate->heap()->PrintHeapMapToJSONStream(isolate, js);
   return true;
 }
@@ -2627,9 +2799,9 @@
 };
 
 
-static bool RequestHeapSnapshot(Isolate* isolate, JSONStream* js) {
+static bool RequestHeapSnapshot(Thread* thread, JSONStream* js) {
   if (Service::graph_stream.enabled()) {
-    Service::SendGraphEvent(isolate);
+    Service::SendGraphEvent(thread);
   }
   // TODO(koda): Provide some id that ties this request to async response(s).
   JSONObject jsobj(js);
@@ -2638,10 +2810,10 @@
 }
 
 
-void Service::SendGraphEvent(Isolate* isolate) {
+void Service::SendGraphEvent(Thread* thread) {
   uint8_t* buffer = NULL;
   WriteStream stream(&buffer, &allocator, 1 * MB);
-  ObjectGraph graph(isolate);
+  ObjectGraph graph(thread);
   intptr_t node_count = graph.Serialize(&stream);
 
   // Chrome crashes receiving a single tens-of-megabytes blob, so send the
@@ -2662,7 +2834,7 @@
           JSONObject event(&params, "event");
           event.AddProperty("type", "Event");
           event.AddProperty("kind", "_Graph");
-          event.AddProperty("isolate", isolate);
+          event.AddProperty("isolate", thread->isolate());
           event.AddPropertyTimeMillis("timestamp", OS::GetCurrentTimeMillis());
 
           event.AddProperty("chunkIndex", i);
@@ -2763,11 +2935,12 @@
 };
 
 
-static RawObject* GetObjectHelper(Isolate* isolate, uword addr) {
-  Object& object = Object::Handle(isolate->current_zone());
+static RawObject* GetObjectHelper(Thread* thread, uword addr) {
+  Object& object = Object::Handle(thread->zone());
 
   {
     NoSafepointScope no_safepoint;
+    Isolate* isolate = thread->isolate();
     ContainsAddressVisitor visitor(isolate, addr);
     object = isolate->heap()->FindObject(&visitor);
   }
@@ -2786,7 +2959,7 @@
 }
 
 
-static bool GetObjectByAddress(Isolate* isolate, JSONStream* js) {
+static bool GetObjectByAddress(Thread* thread, JSONStream* js) {
   const char* addr_str = js->LookupParam("address");
   if (addr_str == NULL) {
     PrintMissingParamError(js, "address");
@@ -2800,8 +2973,8 @@
     return true;
   }
   bool ref = js->HasParam("ref") && js->ParamIs("ref", "true");
-  const Object& obj = Object::Handle(isolate->current_zone(),
-      GetObjectHelper(isolate, addr));
+  const Object& obj = Object::Handle(thread->zone(),
+      GetObjectHelper(thread, addr));
   if (obj.IsNull()) {
     PrintSentinel(js, kFreeSentinel);
   } else {
@@ -2817,15 +2990,14 @@
 };
 
 
-static bool GetPorts(Isolate* isolate, JSONStream* js) {
-  MessageHandler* message_handler = isolate->message_handler();
+static bool GetPorts(Thread* thread, JSONStream* js) {
+  MessageHandler* message_handler = thread->isolate()->message_handler();
   PortMap::PrintPortsForMessageHandler(message_handler, js);
   return true;
 }
 
 
-static bool RespondWithMalformedJson(Isolate* isolate,
-                                      JSONStream* js) {
+static bool RespondWithMalformedJson(Thread* thread, JSONStream* js) {
   JSONObject jsobj(js);
   jsobj.AddProperty("a", "a");
   JSONObject jsobj1(js);
@@ -2838,8 +3010,7 @@
 }
 
 
-static bool RespondWithMalformedObject(Isolate* isolate,
-                                        JSONStream* js) {
+static bool RespondWithMalformedObject(Thread* thread, JSONStream* js) {
   JSONObject jsobj(js);
   jsobj.AddProperty("bart", "simpson");
   return true;
@@ -2848,21 +3019,39 @@
 
 static const MethodParameter* get_object_params[] = {
   ISOLATE_PARAMETER,
+  new UIntParameter("offset", false),
+  new UIntParameter("count", false),
   NULL,
 };
 
 
-static bool GetObject(Isolate* isolate, JSONStream* js) {
+static bool GetObject(Thread* thread, JSONStream* js) {
   const char* id = js->LookupParam("objectId");
   if (id == NULL) {
     PrintMissingParamError(js, "objectId");
     return true;
   }
+  if (js->HasParam("offset")) {
+    intptr_t value = UIntParameter::Parse(js->LookupParam("offset"));
+    if (value < 0) {
+      PrintInvalidParamError(js, "offset");
+      return true;
+    }
+    js->set_offset(value);
+  }
+  if (js->HasParam("count")) {
+    intptr_t value = UIntParameter::Parse(js->LookupParam("count"));
+    if (value < 0) {
+      PrintInvalidParamError(js, "count");
+      return true;
+    }
+    js->set_count(value);
+  }
 
   // Handle heap objects.
   ObjectIdRing::LookupResult lookup_result;
   const Object& obj =
-      Object::Handle(LookupHeapObject(isolate, id, &lookup_result));
+      Object::Handle(LookupHeapObject(thread, id, &lookup_result));
   if (obj.raw() != Object::sentinel().raw()) {
     // We found a heap object for this id.  Return it.
     obj.PrintJSON(js, false);
@@ -2876,7 +3065,7 @@
   }
 
   // Handle non-heap objects.
-  Breakpoint* bpt = LookupBreakpoint(isolate, id, &lookup_result);
+  Breakpoint* bpt = LookupBreakpoint(thread->isolate(), id, &lookup_result);
   if (bpt != NULL) {
     bpt->PrintJSON(js);
     return true;
@@ -2896,8 +3085,8 @@
 };
 
 
-static bool GetClassList(Isolate* isolate, JSONStream* js) {
-  ClassTable* table = isolate->class_table();
+static bool GetClassList(Thread* thread, JSONStream* js) {
+  ClassTable* table = thread->isolate()->class_table();
   JSONObject jsobj(js);
   table->PrintToJSONObject(&jsobj);
   return true;
@@ -2910,12 +3099,12 @@
 };
 
 
-static bool GetTypeArgumentsList(Isolate* isolate, JSONStream* js) {
+static bool GetTypeArgumentsList(Thread* thread, JSONStream* js) {
   bool only_with_instantiations = false;
   if (js->ParamIs("onlyWithInstantiations", "true")) {
     only_with_instantiations = true;
   }
-  ObjectStore* object_store = isolate->object_store();
+  ObjectStore* object_store = thread->isolate()->object_store();
   const Array& table = Array::Handle(object_store->canonical_type_arguments());
   ASSERT(table.Length() > 0);
   TypeArguments& type_args = TypeArguments::Handle();
@@ -2944,7 +3133,7 @@
 };
 
 
-static bool GetVersion(Isolate* isolate, JSONStream* js) {
+static bool GetVersion(Thread* thread, JSONStream* js) {
   JSONObject jsobj(js);
   jsobj.AddProperty("type", "Version");
   jsobj.AddProperty("major", static_cast<intptr_t>(3));
@@ -3006,7 +3195,7 @@
 }
 
 
-static bool GetVM(Isolate* isolate, JSONStream* js) {
+static bool GetVM(Thread* thread, JSONStream* js) {
   Service::PrintJSONForVM(js, false);
   return true;
 }
@@ -3018,7 +3207,7 @@
 };
 
 
-static bool RestartVM(Isolate* isolate, JSONStream* js) {
+static bool RestartVM(Thread* thread, JSONStream* js) {
   Isolate::KillAllIsolates(Isolate::kVMRestartMsg);
   PrintSuccess(js);
   return true;
@@ -3048,7 +3237,7 @@
 };
 
 
-static bool SetExceptionPauseMode(Isolate* isolate, JSONStream* js) {
+static bool SetExceptionPauseMode(Thread* thread, JSONStream* js) {
   const char* mode = js->LookupParam("mode");
   if (mode == NULL) {
     PrintMissingParamError(js, "mode");
@@ -3060,6 +3249,7 @@
     PrintInvalidParamError(js, "mode");
     return true;
   }
+  Isolate* isolate = thread->isolate();
   isolate->debugger()->SetExceptionPauseInfo(info);
   if (Service::debug_stream.enabled()) {
     ServiceEvent event(isolate, ServiceEvent::kDebuggerSettingsUpdate);
@@ -3076,7 +3266,7 @@
 };
 
 
-static bool GetFlagList(Isolate* isolate, JSONStream* js) {
+static bool GetFlagList(Thread* thread, JSONStream* js) {
   Flags::PrintJSON(js);
   return true;
 }
@@ -3088,7 +3278,7 @@
 };
 
 
-static bool SetFlag(Isolate* isolate, JSONStream* js) {
+static bool SetFlag(Thread* thread, JSONStream* js) {
   const char* flag_name = js->LookupParam("name");
   if (flag_name == NULL) {
     PrintMissingParamError(js, "name");
@@ -3120,10 +3310,10 @@
 };
 
 
-static bool SetLibraryDebuggable(Isolate* isolate, JSONStream* js) {
+static bool SetLibraryDebuggable(Thread* thread, JSONStream* js) {
   const char* lib_id = js->LookupParam("libraryId");
   ObjectIdRing::LookupResult lookup_result;
-  Object& obj = Object::Handle(LookupHeapObject(isolate, lib_id,
+  Object& obj = Object::Handle(LookupHeapObject(thread, lib_id,
                                                 &lookup_result));
   const bool is_debuggable =
       BoolParameter::Parse(js->LookupParam("isDebuggable"), false);
@@ -3145,7 +3335,8 @@
 };
 
 
-static bool SetName(Isolate* isolate, JSONStream* js) {
+static bool SetName(Thread* thread, JSONStream* js) {
+  Isolate* isolate = thread->isolate();
   isolate->set_debugger_name(js->LookupParam("name"));
   if (Service::isolate_stream.enabled()) {
     ServiceEvent event(isolate, ServiceEvent::kIsolateUpdate);
@@ -3162,7 +3353,7 @@
 };
 
 
-static bool SetVMName(Isolate* isolate, JSONStream* js) {
+static bool SetVMName(Thread* thread, JSONStream* js) {
   const char* name_param = js->LookupParam("name");
   free(vm_name);
   vm_name = strdup(name_param);
@@ -3183,11 +3374,17 @@
 };
 
 
-static bool SetTraceClassAllocation(Isolate* isolate, JSONStream* js) {
+static bool SetTraceClassAllocation(Thread* thread, JSONStream* js) {
+  if (!thread->isolate()->compilation_allowed()) {
+    js->PrintError(kFeatureDisabled,
+        "Cannot trace allocation when running a precompiled program.");
+    return true;
+  }
   const char* class_id = js->LookupParam("classId");
   const bool enable = BoolParameter::Parse(js->LookupParam("enable"));
   intptr_t cid = -1;
   GetPrefixedIntegerId(class_id, "classes/", &cid);
+  Isolate* isolate = thread->isolate();
   if (!IsValidClassId(isolate, cid)) {
     PrintInvalidParamError(js, "classId");
     return true;
@@ -3220,6 +3417,8 @@
     add_breakpoint_at_activation_params },
   { "_clearCpuProfile", ClearCpuProfile,
     clear_cpu_profile_params },
+  { "_clearVMTimeline", ClearVMTimeline,
+    clear_vm_timeline_params, },
   { "evaluate", Evaluate,
     evaluate_params },
   { "evaluateInFrame", EvaluateInFrame,
@@ -3274,6 +3473,10 @@
     get_vm_metric_params },
   { "_getVMMetricList", GetVMMetricList,
     get_vm_metric_list_params },
+  { "_getVMTimeline", GetVMTimeline,
+    get_vm_timeline_params },
+  { "_getVMTimelineFlag", GetVMTimelineFlag,
+    get_vm_timeline_flag_params },
   { "pause", Pause,
     pause_params },
   { "removeBreakpoint", RemoveBreakpoint,
@@ -3296,6 +3499,8 @@
     set_trace_class_allocation_params },
   { "setVMName", SetVMName,
     set_vm_name_params },
+  { "_setVMTimelineFlag", SetVMTimelineFlag,
+    set_vm_timeline_flag_params },
 };
 
 
diff --git a/runtime/vm/service.h b/runtime/vm/service.h
index 3fe90fe..4d99bed 100644
--- a/runtime/vm/service.h
+++ b/runtime/vm/service.h
@@ -101,8 +101,11 @@
       Dart_ServiceStreamListenCallback listen_callback,
       Dart_ServiceStreamCancelCallback cancel_callback);
 
+  static void SetGetServiceAssetsCallback(
+      Dart_GetVMServiceAssetsArchive get_service_assets);
+
   static void SendEchoEvent(Isolate* isolate, const char* text);
-  static void SendGraphEvent(Isolate* isolate);
+  static void SendGraphEvent(Thread* thread);
   static void SendInspectEvent(Isolate* isolate, const Object& inspectee);
 
   static void SendEmbedderEvent(Isolate* isolate,
@@ -140,6 +143,8 @@
   static bool ListenStream(const char* stream_id);
   static void CancelStream(const char* stream_id);
 
+  static RawObject* RequestAssets();
+
   static Dart_ServiceStreamListenCallback stream_listen_callback() {
     return stream_listen_callback_;
   }
@@ -182,6 +187,7 @@
   static EmbedderServiceHandler* root_service_handler_head_;
   static Dart_ServiceStreamListenCallback stream_listen_callback_;
   static Dart_ServiceStreamCancelCallback stream_cancel_callback_;
+  static Dart_GetVMServiceAssetsArchive get_service_assets_callback_;
 
   static bool needs_isolate_events_;
   static bool needs_debug_events_;
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index d0466ef..d824d4d 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -467,7 +467,7 @@
 _targetId_ may refer to a [Library](#library), [Class](#class), or
 [Instance](#instance).
 
-If _targetId_ is a temporary id which has expired, then then _Expired_
+If _targetId_ is a temporary id which has expired, then the _Expired_
 [Sentinel](#sentinel) is returned.
 
 If _targetId_ refers to an object which has been collected by the VM's
@@ -527,13 +527,15 @@
 
 ```
 Object|Sentinel getObject(string isolateId,
-                          string objectId)
+                          string objectId,
+                          int offset [optional],
+                          int count [optional])
 ```
 
 The _getObject_ RPC is used to lookup an _object_ from some isolate by
 its _id_.
 
-If _objectId_ is a temporary id which has expired, then then _Expired_
+If _objectId_ is a temporary id which has expired, then the _Expired_
 [Sentinel](#sentinel) is returned.
 
 If _objectId_ refers to a heap object which has been collected by the VM's
@@ -546,6 +548,13 @@
 If the object handle has not expired and the object has not been
 collected, then an [Object](#object) will be returned.
 
+The _offset_ and _count_ parameters are used to request subranges of
+Instance objects with the kinds: List, Map, Uint8ClampedList,
+Uint8List, Uint16List, Uint32List, Uint64List, Int8List, Int16List,
+Int32List, Int64List, Flooat32List, Float64List, Inst32x3List,
+Float32x4List, and Float64x2List.  These parameters are otherwise
+ignored.
+
 ### getStack
 
 ```
@@ -1312,8 +1321,7 @@
   // The name of this function.
   string name;
 
-  // The owner of this field, which can be a Library, Class, or a
-  // Function.
+  // The owner of this function, which can be a Library, Class, or a Function.
   @Library|@Class|@Function owner;
 
   // Is this function static?
@@ -1332,8 +1340,7 @@
   // The name of this function.
   string name;
 
-  // The owner of this field, which can be a Library, Class, or a
-  // Function.
+  // The owner of this function, which can be a Library, Class, or a Function.
   @Library|@Class|@Function owner;
 
   // The location of this function in the source code.
@@ -1374,7 +1381,7 @@
   // this property is added with the value 'true'.
   bool valueAsStringIsTruncated [optional];
 
-  // The length of a List instance.
+  // The length of a List or the number of associations in a Map.
   //
   // Provided for instance kinds:
   //   List
@@ -1447,7 +1454,7 @@
   // this property is added with the value 'true'.
   bool valueAsStringIsTruncated [optional];
 
-  // The length of a List instance.
+  // The length of a List or the number of associations in a Map.
   //
   // Provided for instance kinds:
   //   List
@@ -1468,6 +1475,50 @@
   //   Float64x2List
   int length [optional];
 
+  // The index of the first element or association returned.
+  // This is only provided when it is non-zero.
+  //
+  // Provided for instance kinds:
+  //   List
+  //   Map
+  //   Uint8ClampedList
+  //   Uint8List
+  //   Uint16List
+  //   Uint32List
+  //   Uint64List
+  //   Int8List
+  //   Int16List
+  //   Int32List
+  //   Int64List
+  //   Float32List
+  //   Float64List
+  //   Int32x4List
+  //   Float32x4List
+  //   Float64x2List
+  int offset [optional];
+
+  // The number of elements or associations returned.
+  // This is only provided when it is less than length.
+  //
+  // Provided for instance kinds:
+  //   List
+  //   Map
+  //   Uint8ClampedList
+  //   Uint8List
+  //   Uint16List
+  //   Uint32List
+  //   Uint64List
+  //   Int8List
+  //   Int16List
+  //   Int32List
+  //   Int64List
+  //   Float32List
+  //   Float64List
+  //   Int32x4List
+  //   Float32x4List
+  //   Float64x2List
+  int count [optional];
+
   // The name of a Type instance.
   //
   // Provided for instance kinds:
@@ -1643,7 +1694,7 @@
   Float64x2,
   Int32x4
 
-  // An instance of the built-in VM TypedData implementations.  User-defined
+  // An instance of the built-in VM TypedData implementations. User-defined
   // TypedDatas will be PlainInstance.
   Uint8ClampedList,
   Uint8List,
@@ -1676,16 +1727,16 @@
   // An instance of the Dart class WeakProperty.
   WeakProperty,
 
-  // An instance of the Dart class Type
+  // An instance of the Dart class Type.
   Type,
 
-  // An instance of the Dart class TypeParamer
+  // An instance of the Dart class TypeParameter.
   TypeParameter,
 
-  // An instance of the Dart class TypeRef
+  // An instance of the Dart class TypeRef.
   TypeRef,
 
-  // An instance of the Dart class BoundedType
+  // An instance of the Dart class BoundedType.
   BoundedType,
 }
 ```
@@ -1753,6 +1804,9 @@
 
   // The error that is causing this isolate to exit, if applicable.
   Error error [optional];
+
+  // The current pause on exception mode for this isolate.
+  ExceptionPauseMode exceptionPauseMode;
 }
 ```
 
@@ -1780,7 +1834,7 @@
   // The uri of this library.
   string uri;
 
-  // Is this library debuggable?  Default true.
+  // Is this library debuggable? Default true.
   bool debuggable;
 
   // A list of the imports for this library.
@@ -2133,15 +2187,15 @@
   // has yet to be loaded.
   string scriptUri [optional];
 
-  // An approximate token position for the source location.  This may
+  // An approximate token position for the source location. This may
   // change when the location is resolved.
   int tokenPos [optional];
 
-  // An approximate line number for the source location.  This may
+  // An approximate line number for the source location. This may
   // change when the location is resolved.
   int line [optional];
 
-  // An approximate column number for the source location.  This may
+  // An approximate column number for the source location. This may
   // change when the location is resolved.
   int column [optional];
 
@@ -2219,7 +2273,7 @@
 ------- | --------
 1.0 | initial revision
 2.0 | Describe protocol version 2.0.
-3.0 | Describe protocol version 3.0.  Added UnresolvedSourceLocation.  Added Sentinel return to getIsolate.  Add AddedBreakpointWithScriptUri.  Removed Isolate.entry. The type of VM.pid was changed from string to int.  Added VMUpdate events.
+3.0 | Describe protocol version 3.0.  Added UnresolvedSourceLocation.  Added Sentinel return to getIsolate.  Add AddedBreakpointWithScriptUri.  Removed Isolate.entry. The type of VM.pid was changed from string to int.  Added VMUpdate events.  Add offset and count parameters to getObject() and offset and count fields to Instance.
 
 
 [discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/runtime/vm/service_event.cc b/runtime/vm/service_event.cc
index 1023043..bad3583 100644
--- a/runtime/vm/service_event.cc
+++ b/runtime/vm/service_event.cc
@@ -197,7 +197,7 @@
     JSONObject jssettings(&jsobj, "_debuggerSettings");
     isolate()->debugger()->PrintSettingsToJSONObject(&jssettings);
   }
-  if (top_frame() != NULL) {
+  if ((top_frame() != NULL) && Isolate::Current()->compilation_allowed()) {
     JSONObject jsFrame(&jsobj, "topFrame");
     top_frame()->PrintToJSONObject(&jsFrame);
     intptr_t index = 0;  // Avoid ambiguity in call to AddProperty.
diff --git a/runtime/vm/service_isolate.cc b/runtime/vm/service_isolate.cc
index cb92d3a..923f6d4 100644
--- a/runtime/vm/service_isolate.cc
+++ b/runtime/vm/service_isolate.cc
@@ -255,7 +255,6 @@
 void ServiceIsolate::ConstructExitMessageAndCache(Isolate* I) {
   // Construct and cache exit message here so we can send it without needing an
   // isolate.
-  StartIsolateScope iso_scope(I);
   Thread* T = Thread::Current();
   ASSERT(I == T->isolate());
   ASSERT(I != NULL);
@@ -319,16 +318,17 @@
                                                    &error));
     if (isolate == NULL) {
       OS::PrintErr("vm-service: Isolate creation error: %s\n", error);
+      ServiceIsolate::SetServiceIsolate(NULL);
       ServiceIsolate::FinishedInitializing();
       return;
     }
 
-
-    Thread::ExitIsolate();
-
-    ServiceIsolate::ConstructExitMessageAndCache(isolate);
-
-    RunMain(isolate);
+    {
+      ASSERT(Isolate::Current() == NULL);
+      StartIsolateScope start_scope(isolate);
+      ServiceIsolate::ConstructExitMessageAndCache(isolate);
+      RunMain(isolate);
+    }
 
     ServiceIsolate::FinishedInitializing();
 
@@ -347,6 +347,7 @@
     {
       // Print the error if there is one.  This may execute dart code to
       // print the exception object, so we need to use a StartIsolateScope.
+      ASSERT(Isolate::Current() == NULL);
       StartIsolateScope start_scope(I);
       Thread* T = Thread::Current();
       ASSERT(I == T->isolate());
@@ -359,11 +360,8 @@
       }
       Dart::RunShutdownCallback();
     }
-    {
-      // Shut the isolate down.
-      SwitchIsolateScope switch_scope(I);
-      Dart::ShutdownIsolate();
-    }
+    // Shut the isolate down.
+    Dart::ShutdownIsolate(I);
     if (FLAG_trace_service) {
       OS::Print("vm-service: Shutdown.\n");
     }
@@ -371,7 +369,6 @@
   }
 
   void RunMain(Isolate* I) {
-    StartIsolateScope iso_scope(I);
     Thread* T = Thread::Current();
     ASSERT(I == T->isolate());
     StackZone zone(T);
diff --git a/runtime/vm/service_test.cc b/runtime/vm/service_test.cc
index de6a0d8..1f70a67 100644
--- a/runtime/vm/service_test.cc
+++ b/runtime/vm/service_test.cc
@@ -46,6 +46,8 @@
 
   const char* msg() const { return _msg; }
 
+  virtual Isolate* isolate() const { return Isolate::Current(); }
+
  private:
   char* _msg;
 };
diff --git a/runtime/vm/signal_handler_android.cc b/runtime/vm/signal_handler_android.cc
index 6540751..a85dbb7 100644
--- a/runtime/vm/signal_handler_android.cc
+++ b/runtime/vm/signal_handler_android.cc
@@ -66,7 +66,7 @@
 #elif defined(HOST_ARCH_ARM)
   sp = static_cast<uintptr_t>(mcontext.arm_sp);
 #elif defined(HOST_ARCH_ARM64)
-  sp = static_cast<uintptr_t>(mcontext.regs[18]);
+  sp = static_cast<uintptr_t>(mcontext.regs[19]);
 #else
 #error Unsupported architecture.
 #endif  // HOST_ARCH_...
diff --git a/runtime/vm/signal_handler_linux.cc b/runtime/vm/signal_handler_linux.cc
index 45fa50d..b49f90a 100644
--- a/runtime/vm/signal_handler_linux.cc
+++ b/runtime/vm/signal_handler_linux.cc
@@ -72,7 +72,7 @@
 
 uintptr_t SignalHandler::GetDartStackPointer(const mcontext_t& mcontext) {
 #if defined(TARGET_ARCH_ARM64) && !defined(USING_SIMULATOR)
-  return static_cast<uintptr_t>(mcontext.regs[18]);
+  return static_cast<uintptr_t>(mcontext.regs[19]);
 #else
   return GetCStackPointer(mcontext);
 #endif
diff --git a/runtime/vm/signal_handler_macos.cc b/runtime/vm/signal_handler_macos.cc
index e0a2a14..ca6e64d 100644
--- a/runtime/vm/signal_handler_macos.cc
+++ b/runtime/vm/signal_handler_macos.cc
@@ -36,7 +36,7 @@
 #elif defined(HOST_ARCH_X64)
   fp = static_cast<uintptr_t>(mcontext->__ss.__rbp);
 #elif defined(HOST_ARCH_ARM)
-  fp = static_cast<uintptr_t>(mcontext->__ss.__r[11]);
+  fp = static_cast<uintptr_t>(mcontext->__ss.__r[7]);
 #elif defined(HOST_ARCH_ARM64)
   fp = static_cast<uintptr_t>(mcontext->__ss.__fp);
 #else
@@ -67,7 +67,11 @@
 
 
 uintptr_t SignalHandler::GetDartStackPointer(const mcontext_t& mcontext) {
+#if defined(TARGET_ARCH_ARM64) && !defined(USING_SIMULATOR)
+  return static_cast<uintptr_t>(mcontext->__ss.__x[19]);
+#else
   return GetCStackPointer(mcontext);
+#endif
 }
 
 
diff --git a/runtime/vm/simulator_arm.cc b/runtime/vm/simulator_arm.cc
index 5419aaa..74464c8 100644
--- a/runtime/vm/simulator_arm.cc
+++ b/runtime/vm/simulator_arm.cc
@@ -145,7 +145,7 @@
       R8,  R9,  R10, R11,
       R12, R13, R14, R15,
       PC,  LR,  SP,  IP,
-      FP,  R10, R9
+      FP,  PP,  CTX
   };
   ASSERT(ARRAY_SIZE(kNames) == ARRAY_SIZE(kRegisters));
   for (unsigned i = 0; i < ARRAY_SIZE(kNames); i++) {
@@ -1996,6 +1996,7 @@
         HandleIllegalAccess(addr, instr);
       } else {
         if (write_back) {
+          ASSERT(rd != rn);  // Unpredictable.
           set_register(rn, rn_val);
         }
         if (!instr->HasSign()) {
@@ -2312,6 +2313,7 @@
     HandleIllegalAccess(addr, instr);
   } else {
     if (write_back) {
+      ASSERT(rd != rn);  // Unpredictable.
       set_register(rn, rn_val);
     }
     if (instr->HasB()) {
@@ -2424,6 +2426,7 @@
     HandleIllegalAccess(addr, instr);
   } else {
     if (write_back) {
+      ASSERT(rd != rn);  // Unpredictable.
       set_register(rn, rn_val);
     }
     if (instr->HasB()) {
@@ -3735,7 +3738,9 @@
   int32_t r6_val = get_register(R6);
   int32_t r7_val = get_register(R7);
   int32_t r8_val = get_register(R8);
+#if !defined(TARGET_OS_MACOS)
   int32_t r9_val = get_register(R9);
+#endif
   int32_t r10_val = get_register(R10);
   int32_t r11_val = get_register(R11);
 
@@ -3767,7 +3772,9 @@
   set_register(R6, callee_saved_value);
   set_register(R7, callee_saved_value);
   set_register(R8, callee_saved_value);
+#if !defined(TARGET_OS_MACOS)
   set_register(R9, callee_saved_value);
+#endif
   set_register(R10, callee_saved_value);
   set_register(R11, callee_saved_value);
 
@@ -3793,7 +3800,9 @@
   ASSERT(callee_saved_value == get_register(R6));
   ASSERT(callee_saved_value == get_register(R7));
   ASSERT(callee_saved_value == get_register(R8));
+#if !defined(TARGET_OS_MACOS)
   ASSERT(callee_saved_value == get_register(R9));
+#endif
   ASSERT(callee_saved_value == get_register(R10));
   ASSERT(callee_saved_value == get_register(R11));
 
@@ -3814,7 +3823,9 @@
   set_register(R6, r6_val);
   set_register(R7, r7_val);
   set_register(R8, r8_val);
+#if !defined(TARGET_OS_MACOS)
   set_register(R9, r9_val);
+#endif
   set_register(R10, r10_val);
   set_register(R11, r11_val);
 
@@ -3859,7 +3870,6 @@
   // The C++ caller has not cleaned up the stack memory of C++ frames.
   // Prepare for unwinding frames by destroying all the stack resources
   // in the previous C++ frames.
-  Isolate* isolate = thread->isolate();
   StackResource::Unwind(thread);
 
   // Unwind the C++ stack and continue simulation in the target frame.
@@ -3870,7 +3880,7 @@
   // Set the tag.
   thread->set_vm_tag(VMTag::kDartTagId);
   // Clear top exit frame.
-  isolate->set_top_exit_frame_info(0);
+  thread->set_top_exit_frame_info(0);
 
   ASSERT(raw_exception != Object::null());
   set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception));
diff --git a/runtime/vm/simulator_arm64.cc b/runtime/vm/simulator_arm64.cc
index ac6fe18..cf25e24 100644
--- a/runtime/vm/simulator_arm64.cc
+++ b/runtime/vm/simulator_arm64.cc
@@ -900,6 +900,7 @@
     Instr* instr, Register reg, int64_t value, R31Type r31t) {
   // Register is in range.
   ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters));
+  ASSERT(instr == NULL || reg != R18);  // R18 is globally reserved on iOS.
   if ((reg != R31) || (r31t != R31IsZR)) {
     registers_[reg] = value;
     // If we're setting CSP, make sure it is 16-byte aligned. In truth, CSP
@@ -1650,24 +1651,24 @@
 
     // Zap caller-saved registers, since the actual runtime call could have
     // used them.
-    set_register(instr, R2, icount_);
-    set_register(instr, R3, icount_);
-    set_register(instr, R4, icount_);
-    set_register(instr, R5, icount_);
-    set_register(instr, R6, icount_);
-    set_register(instr, R7, icount_);
-    set_register(instr, R8, icount_);
-    set_register(instr, R9, icount_);
-    set_register(instr, R10, icount_);
-    set_register(instr, R11, icount_);
-    set_register(instr, R12, icount_);
-    set_register(instr, R13, icount_);
-    set_register(instr, R14, icount_);
-    set_register(instr, R15, icount_);
-    set_register(instr, IP0, icount_);
-    set_register(instr, IP1, icount_);
-    set_register(instr, R18, icount_);
-    set_register(instr, LR, icount_);
+    set_register(NULL, R2, icount_);
+    set_register(NULL, R3, icount_);
+    set_register(NULL, R4, icount_);
+    set_register(NULL, R5, icount_);
+    set_register(NULL, R6, icount_);
+    set_register(NULL, R7, icount_);
+    set_register(NULL, R8, icount_);
+    set_register(NULL, R9, icount_);
+    set_register(NULL, R10, icount_);
+    set_register(NULL, R11, icount_);
+    set_register(NULL, R12, icount_);
+    set_register(NULL, R13, icount_);
+    set_register(NULL, R14, icount_);
+    set_register(NULL, R15, icount_);
+    set_register(NULL, IP0, icount_);
+    set_register(NULL, IP1, icount_);
+    set_register(NULL, R18, icount_);
+    set_register(NULL, LR, icount_);
 
     // TODO(zra): Zap caller-saved fpu registers.
 
@@ -3519,7 +3520,6 @@
   // The C++ caller has not cleaned up the stack memory of C++ frames.
   // Prepare for unwinding frames by destroying all the stack resources
   // in the previous C++ frames.
-  Isolate* isolate = thread->isolate();
   StackResource::Unwind(thread);
 
   // Unwind the C++ stack and continue simulation in the target frame.
@@ -3530,7 +3530,7 @@
   // Set the tag.
   thread->set_vm_tag(VMTag::kDartTagId);
   // Clear top exit frame.
-  isolate->set_top_exit_frame_info(0);
+  thread->set_top_exit_frame_info(0);
 
   ASSERT(raw_exception != Object::null());
   set_register(NULL, kExceptionObjectReg, bit_cast<int64_t>(raw_exception));
diff --git a/runtime/vm/simulator_mips.cc b/runtime/vm/simulator_mips.cc
index a6bd8de..04e0b7f 100644
--- a/runtime/vm/simulator_mips.cc
+++ b/runtime/vm/simulator_mips.cc
@@ -1813,6 +1813,12 @@
         set_fregister_double(instr->FdField(), fs_val);
         break;
       }
+      case COP1_NEG: {
+        // Format(instr, "neg.'fmt 'fd, 'fs");
+        ASSERT(instr->FormatField() == FMT_D);
+        set_fregister_double(instr->FdField(), -fs_val);
+        break;
+      }
       case COP1_C_F: {
         ASSERT(instr->FormatField() == FMT_D);  // Only D supported.
         ASSERT(instr->FdField() == F0);
@@ -2467,7 +2473,6 @@
   // The C++ caller has not cleaned up the stack memory of C++ frames.
   // Prepare for unwinding frames by destroying all the stack resources
   // in the previous C++ frames.
-  Isolate* isolate = thread->isolate();
   StackResource::Unwind(thread);
 
   // Unwind the C++ stack and continue simulation in the target frame.
@@ -2478,7 +2483,7 @@
   // Set the tag.
   thread->set_vm_tag(VMTag::kDartTagId);
   // Clear top exit frame.
-  isolate->set_top_exit_frame_info(0);
+  thread->set_top_exit_frame_info(0);
 
   ASSERT(raw_exception != Object::null());
   set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception));
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index d496aaa..8e6c28e 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -194,7 +194,7 @@
       library_(Library::Handle(zone_)),
       type_(AbstractType::Handle(zone_)),
       type_arguments_(TypeArguments::Handle(zone_)),
-      tokens_(Array::Handle(zone_)),
+      tokens_(GrowableObjectArray::Handle(zone_)),
       stream_(TokenStream::Handle(zone_)),
       data_(ExternalTypedData::Handle(zone_)),
       typed_data_(TypedData::Handle(zone_)),
@@ -398,60 +398,25 @@
                                           intptr_t patch_offset) {
   if (IsVMIsolateObject(header_value)) {
     return ReadVMIsolateObject(header_value);
-  } else {
-    if (SerializedHeaderTag::decode(header_value) == kObjectId) {
-      return ReadIndexedObject(SerializedHeaderData::decode(header_value),
-                               patch_object_id,
-                               patch_offset);
-    }
-    ASSERT(SerializedHeaderTag::decode(header_value) == kInlined);
-    intptr_t object_id = SerializedHeaderData::decode(header_value);
-    if (object_id == kOmittedObjectId) {
-      object_id = NextAvailableObjectId();
-    }
-
-    // Read the class header information.
-    intptr_t class_header = Read<int32_t>();
-    intptr_t tags = ReadTags();
-    if (as_reference && !RawObject::IsCanonical(tags)) {
-      return ReadObjectRef(object_id,
-                           class_header,
-                           tags,
-                           patch_object_id,
-                           patch_offset);
-    }
-    return ReadInlinedObject(object_id,
-                             class_header,
-                             tags,
+  }
+  if (SerializedHeaderTag::decode(header_value) == kObjectId) {
+    return ReadIndexedObject(SerializedHeaderData::decode(header_value),
                              patch_object_id,
                              patch_offset);
   }
-}
+  ASSERT(SerializedHeaderTag::decode(header_value) == kInlined);
+  intptr_t object_id = SerializedHeaderData::decode(header_value);
+  if (object_id == kOmittedObjectId) {
+    object_id = NextAvailableObjectId();
+  }
 
-
-RawObject* SnapshotReader::ReadObjectRef(intptr_t object_id,
-                                         intptr_t class_header,
-                                         intptr_t tags,
-                                         intptr_t patch_object_id,
-                                         intptr_t patch_offset) {
-  // Since we are only reading an object reference, If it is an instance kind
-  // then we only need to figure out the class of the object and allocate an
-  // instance of it. The individual fields will be read later.
+  // Read the class header information.
+  intptr_t class_header = Read<int32_t>();
+  intptr_t tags = ReadTags();
+  bool read_as_reference = as_reference && !RawObject::IsCanonical(tags);
   intptr_t header_id = SerializedHeaderData::decode(class_header);
   if (header_id == kInstanceObjectId) {
-    Instance& result = Instance::ZoneHandle(zone(), Instance::null());
-    AddBackRef(object_id, &result, kIsNotDeserialized);
-
-    cls_ ^= ReadObjectImpl(kAsInlinedObject);  // Read class information.
-    ASSERT(!cls_.IsNull());
-    intptr_t instance_size = cls_.instance_size();
-    ASSERT(instance_size > 0);
-    if (kind_ == Snapshot::kFull) {
-      result ^= AllocateUninitialized(cls_.id(), instance_size);
-    } else {
-      result ^= Object::Allocate(cls_.id(), instance_size, HEAP_SPACE(kind_));
-    }
-    return result.raw();
+    return ReadInstance(object_id, tags, read_as_reference);
   } else if (header_id == kStaticImplicitClosureObjectId) {
     // We skip the tags that have been written as the implicit static
     // closure is going to be created in this isolate or the canonical
@@ -460,57 +425,22 @@
   }
   ASSERT((class_header & kSmiTagMask) != kSmiTag);
 
-  // Similarly Array and ImmutableArray objects are also similarly only
-  // allocated here, the individual array elements are read later.
   intptr_t class_id = LookupInternalClass(class_header);
-  if (class_id == kArrayCid) {
-    // Read the length and allocate an object based on the len.
-    intptr_t len = ReadSmiValue();
-    Array& array = Array::ZoneHandle(
-        zone(),
-        ((kind_ == Snapshot::kFull) ?
-         NewArray(len) : Array::New(len, HEAP_SPACE(kind_))));
-    AddBackRef(object_id, &array, kIsNotDeserialized);
-
-    return array.raw();
-  }
-  if (class_id == kImmutableArrayCid) {
-    // Read the length and allocate an object based on the len.
-    intptr_t len = ReadSmiValue();
-    Array& array = Array::ZoneHandle(
-        zone(),
-        (kind_ == Snapshot::kFull) ?
-        NewImmutableArray(len) : ImmutableArray::New(len, HEAP_SPACE(kind_)));
-    AddBackRef(object_id, &array, kIsNotDeserialized);
-
-    return array.raw();
-  }
-  if (class_id == kObjectPoolCid) {
-    ASSERT(kind_ == Snapshot::kFull);
-    // Read the length and allocate an object based on the len.
-    intptr_t len = Read<intptr_t>();
-    ObjectPool& pool = ObjectPool::ZoneHandle(zone(),
-                                              NewObjectPool(len));
-    AddBackRef(object_id, &pool, kIsNotDeserialized);
-
-    return pool.raw();
-  }
-
-  // For all other internal VM classes we read the object inline.
   switch (class_id) {
 #define SNAPSHOT_READ(clazz)                                                   \
     case clazz::kClassId: {                                                    \
-      pobj_ = clazz::ReadFrom(this, object_id, tags, kind_, true);             \
+      pobj_ = clazz::ReadFrom(this, object_id, tags, kind_, read_as_reference);\
       break;                                                                   \
     }
     CLASS_LIST_NO_OBJECT(SNAPSHOT_READ)
 #undef SNAPSHOT_READ
 #define SNAPSHOT_READ(clazz)                                                   \
-    case kTypedData##clazz##Cid:                                               \
+        case kTypedData##clazz##Cid:                                           \
 
     CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) {
       tags = RawObject::ClassIdTag::update(class_id, tags);
-      pobj_ = TypedData::ReadFrom(this, object_id, tags, kind_, true);
+      pobj_ = TypedData::ReadFrom(
+          this, object_id, tags, kind_, read_as_reference);
       break;
     }
 #undef SNAPSHOT_READ
@@ -525,53 +455,58 @@
 #undef SNAPSHOT_READ
     default: UNREACHABLE(); break;
   }
+  if (!read_as_reference) {
+    AddPatchRecord(object_id, patch_object_id, patch_offset);
+  }
   return pobj_.raw();
 }
 
 
-RawObject* SnapshotReader::ReadInlinedObject(intptr_t object_id,
-                                             intptr_t class_header,
-                                             intptr_t tags,
-                                             intptr_t patch_object_id,
-                                             intptr_t patch_offset) {
-  // Lookup the class based on the class header information.
-  intptr_t header_id = SerializedHeaderData::decode(class_header);
-  if (header_id == kInstanceObjectId) {
-    // Object is regular dart instance.
-    Instance* result = reinterpret_cast<Instance*>(GetBackRef(object_id));
-    intptr_t instance_size = 0;
-    if (result == NULL) {
-      result = &(Instance::ZoneHandle(zone(), Instance::null()));
-      AddBackRef(object_id, result, kIsDeserialized);
-      cls_ ^= ReadObjectImpl(kAsInlinedObject);
-      ASSERT(!cls_.IsNull());
-      instance_size = cls_.instance_size();
-      ASSERT(instance_size > 0);
-      // Allocate the instance and read in all the fields for the object.
-      if (kind_ == Snapshot::kFull) {
-        *result ^= AllocateUninitialized(cls_.id(), instance_size);
-      } else {
-        *result ^= Object::Allocate(cls_.id(),
-                                    instance_size,
-                                    HEAP_SPACE(kind_));
-      }
+RawObject* SnapshotReader::ReadInstance(intptr_t object_id,
+                                        intptr_t tags,
+                                        bool as_reference) {
+  // Object is regular dart instance.
+  intptr_t instance_size = 0;
+  Instance* result = NULL;
+  DeserializeState state;
+  if (!as_reference) {
+    result = reinterpret_cast<Instance*>(GetBackRef(object_id));
+    state = kIsDeserialized;
+  } else {
+    state = kIsNotDeserialized;
+  }
+  if (result == NULL) {
+    result = &(Instance::ZoneHandle(zone(), Instance::null()));
+    AddBackRef(object_id, result, state);
+    cls_ ^= ReadObjectImpl(kAsInlinedObject);
+    ASSERT(!cls_.IsNull());
+    instance_size = cls_.instance_size();
+    ASSERT(instance_size > 0);
+    // Allocate the instance and read in all the fields for the object.
+    if (kind_ == Snapshot::kFull) {
+      *result ^= AllocateUninitialized(cls_.id(), instance_size);
     } else {
-      cls_ ^= ReadObjectImpl(kAsInlinedObject);
-      ASSERT(!cls_.IsNull());
-      instance_size = cls_.instance_size();
+      *result ^= Object::Allocate(cls_.id(), instance_size, HEAP_SPACE(kind_));
     }
+  } else {
+    cls_ ^= ReadObjectImpl(kAsInlinedObject);
+    ASSERT(!cls_.IsNull());
+    instance_size = cls_.instance_size();
+  }
+  if (!as_reference) {
+    // Read all the individual fields for inlined objects.
     intptr_t next_field_offset = Class::IsSignatureClass(cls_.raw())
-      ? Closure::InstanceSize() : cls_.next_field_offset();
+        ? Closure::InstanceSize() : cls_.next_field_offset();
 
     intptr_t type_argument_field_offset = cls_.type_arguments_field_offset();
     ASSERT(next_field_offset > 0);
     // Instance::NextFieldOffset() returns the offset of the first field in
     // a Dart object.
-    bool as_reference = RawObject::IsCanonical(tags) ? false : true;
+    bool read_as_reference = RawObject::IsCanonical(tags) ? false : true;
     intptr_t offset = Instance::NextFieldOffset();
     intptr_t result_cid = result->GetClassId();
     while (offset < next_field_offset) {
-      pobj_ = ReadObjectImpl(as_reference);
+      pobj_ = ReadObjectImpl(read_as_reference);
       result->SetFieldAtOffset(offset, pobj_);
       if ((offset != type_argument_field_offset) &&
           (kind_ == Snapshot::kMessage)) {
@@ -606,45 +541,8 @@
         ASSERT(!result->IsNull());
       }
     }
-    return result->raw();
-  } else if (header_id == kStaticImplicitClosureObjectId) {
-    // We do not use the tags as the implicit static closure
-    // is going to be created in this isolate or the canonical
-    // version already created in the isolate will be used.
-    return ReadStaticImplicitClosure(object_id, class_header);
   }
-  ASSERT((class_header & kSmiTagMask) != kSmiTag);
-  intptr_t class_id = LookupInternalClass(class_header);
-  switch (class_id) {
-#define SNAPSHOT_READ(clazz)                                                   \
-    case clazz::kClassId: {                                                    \
-      pobj_ = clazz::ReadFrom(this, object_id, tags, kind_, false);            \
-      break;                                                                   \
-    }
-    CLASS_LIST_NO_OBJECT(SNAPSHOT_READ)
-#undef SNAPSHOT_READ
-#define SNAPSHOT_READ(clazz)                                                   \
-    case kTypedData##clazz##Cid:                                               \
-
-    CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) {
-      tags = RawObject::ClassIdTag::update(class_id, tags);
-      pobj_ = TypedData::ReadFrom(this, object_id, tags, kind_, false);
-      break;
-    }
-#undef SNAPSHOT_READ
-#define SNAPSHOT_READ(clazz)                                                   \
-    case kExternalTypedData##clazz##Cid:                                       \
-
-    CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) {
-      tags = RawObject::ClassIdTag::update(class_id, tags);
-      pobj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_, false);
-      break;
-    }
-#undef SNAPSHOT_READ
-    default: UNREACHABLE(); break;
-  }
-  AddPatchRecord(object_id, patch_object_id, patch_offset);
-  return pobj_.raw();
+  return result->raw();
 }
 
 
@@ -675,8 +573,8 @@
 
 class HeapLocker : public StackResource {
  public:
-  HeapLocker(Isolate* isolate, PageSpace* page_space)
-      : StackResource(isolate), page_space_(page_space) {
+  HeapLocker(Thread* thread, PageSpace* page_space)
+      : StackResource(thread), page_space_(page_space) {
         page_space_->AcquireDataLock();
   }
   ~HeapLocker() {
@@ -690,7 +588,8 @@
 
 RawApiError* SnapshotReader::ReadFullSnapshot() {
   ASSERT(kind_ == Snapshot::kFull);
-  Isolate* isolate = Isolate::Current();
+  Thread* thread = Thread::Current();
+  Isolate* isolate = thread->isolate();
   ASSERT(isolate != NULL);
   ObjectStore* object_store = isolate->object_store();
   ASSERT(object_store != NULL);
@@ -707,7 +606,7 @@
   // size for the full snapshot being read.
   {
     NoSafepointScope no_safepoint;
-    HeapLocker hl(isolate, old_space());
+    HeapLocker hl(thread, old_space());
 
     // Read in all the objects stored in the object store.
     RawObject** toobj = snapshot_code() ? object_store->to()
@@ -964,7 +863,7 @@
   ASSERT(kind_ == Snapshot::kFull);
   ASSERT_NO_SAFEPOINT_SCOPE();
   RawInstance* obj = reinterpret_cast<RawInstance*>(
-      AllocateUninitialized(kObjectCid, Instance::InstanceSize()));
+      AllocateUninitialized(kInstanceCid, Instance::InstanceSize()));
   return obj;
 }
 
@@ -1117,6 +1016,16 @@
 }
 
 
+RawWeakProperty* SnapshotReader::NewWeakProperty() {
+  ALLOC_NEW_OBJECT(WeakProperty);
+}
+
+
+RawJSRegExp* SnapshotReader::NewJSRegExp() {
+  ALLOC_NEW_OBJECT(JSRegExp);
+}
+
+
 RawFloat32x4* SnapshotReader::NewFloat32x4(float v0, float v1, float v2,
                                            float v3) {
   ASSERT(kind_ == Snapshot::kFull);
@@ -1393,8 +1302,8 @@
                         Object::transition_sentinel().raw());
   READ_VM_SINGLETON_OBJ(kEmptyArrayObject, Object::empty_array().raw());
   READ_VM_SINGLETON_OBJ(kZeroArrayObject, Object::zero_array().raw());
-  READ_VM_SINGLETON_OBJ(kDynamicType, Object::dynamic_type());
-  READ_VM_SINGLETON_OBJ(kVoidType, Object::void_type());
+  READ_VM_SINGLETON_OBJ(kDynamicType, Object::dynamic_type().raw());
+  READ_VM_SINGLETON_OBJ(kVoidType, Object::void_type().raw());
   READ_VM_SINGLETON_OBJ(kTrueValue, Bool::True().raw());
   READ_VM_SINGLETON_OBJ(kFalseValue, Bool::False().raw());
   READ_VM_SINGLETON_OBJ(kExtractorParameterTypes,
@@ -1429,6 +1338,13 @@
     }
   }
 
+  // Check if it is a singleton ICData array object.
+  for (intptr_t i = 0; i < ICData::kCachedICDataArrayCount; i++) {
+    if (object_id == (kCachedICDataArray0 + i)) {
+      return ICData::cached_icdata_arrays_[i];
+    }
+  }
+
   ASSERT(Symbols::IsVMSymbolId(object_id));
   return Symbols::GetVMSymbol(object_id);  // return VM symbol.
 }
@@ -1569,7 +1485,8 @@
 
 RawApiError* VmIsolateSnapshotReader::ReadVmIsolateSnapshot() {
   ASSERT(kind() == Snapshot::kFull);
-  Isolate* isolate = Isolate::Current();
+  Thread* thread = Thread::Current();
+  Isolate* isolate = thread->isolate();
   ASSERT(isolate != NULL);
   ASSERT(isolate == Dart::vm_isolate());
   ObjectStore* object_store = isolate->object_store();
@@ -1585,7 +1502,7 @@
 
   {
     NoSafepointScope no_safepoint;
-    HeapLocker hl(isolate, old_space());
+    HeapLocker hl(thread, old_space());
 
     // Read in the symbol table.
     object_store->symbol_table_ = reinterpret_cast<RawArray*>(ReadObject());
@@ -1732,8 +1649,8 @@
                          kTransitionSentinelObject);
   WRITE_VM_SINGLETON_OBJ(Object::empty_array().raw(), kEmptyArrayObject);
   WRITE_VM_SINGLETON_OBJ(Object::zero_array().raw(), kZeroArrayObject);
-  WRITE_VM_SINGLETON_OBJ(Object::dynamic_type(), kDynamicType);
-  WRITE_VM_SINGLETON_OBJ(Object::void_type(), kVoidType);
+  WRITE_VM_SINGLETON_OBJ(Object::dynamic_type().raw(), kDynamicType);
+  WRITE_VM_SINGLETON_OBJ(Object::void_type().raw(), kVoidType);
   WRITE_VM_SINGLETON_OBJ(Bool::True().raw(), kTrueValue);
   WRITE_VM_SINGLETON_OBJ(Bool::False().raw(), kFalseValue);
   WRITE_VM_SINGLETON_OBJ(Object::extractor_parameter_types().raw(),
@@ -1770,6 +1687,14 @@
     }
   }
 
+  // Check if it is a singleton ICData array object.
+  for (intptr_t i = 0; i < ICData::kCachedICDataArrayCount; i++) {
+    if (rawobj == ICData::cached_icdata_arrays_[i]) {
+      WriteVMIsolateObject(kCachedICDataArray0 + i);
+      return true;
+    }
+  }
+
   if (kind() == Snapshot::kFull) {
     // Check it is a predefined symbol in the VM isolate.
     id = Symbols::LookupVMSymbol(rawobj);
@@ -1826,15 +1751,15 @@
 // objects and their accompanying token streams.
 class ScriptVisitor : public ObjectVisitor {
  public:
-  explicit ScriptVisitor(Isolate* isolate) :
-      ObjectVisitor(isolate),
-      objHandle_(Object::Handle(isolate->current_zone())),
+  explicit ScriptVisitor(Thread* thread) :
+      ObjectVisitor(thread->isolate()),
+      objHandle_(Object::Handle(thread->zone())),
       count_(0),
       scripts_(NULL) {}
 
-  ScriptVisitor(Isolate* isolate, const Array* scripts) :
-      ObjectVisitor(isolate),
-      objHandle_(Object::Handle(isolate->current_zone())),
+  ScriptVisitor(Thread* thread, const Array* scripts) :
+      ObjectVisitor(thread->isolate()),
+      objHandle_(Object::Handle(thread->zone())),
       count_(0),
       scripts_(scripts) {}
 
@@ -1894,11 +1819,11 @@
   // into an array so that we can write it out as part of the VM isolate
   // snapshot. We first count the number of script objects, allocate an array
   // and then fill it up with the script objects.
-  ScriptVisitor scripts_counter(isolate());
+  ScriptVisitor scripts_counter(thread());
   heap()->IterateOldObjects(&scripts_counter);
   intptr_t count = scripts_counter.count();
   scripts_ = Array::New(count, Heap::kOld);
-  ScriptVisitor script_visitor(isolate(), &scripts_);
+  ScriptVisitor script_visitor(thread(), &scripts_);
   heap()->IterateOldObjects(&script_visitor);
 
   // Stash the symbol table away for writing and reading into the vm isolate,
@@ -2031,6 +1956,15 @@
   if (snapshot_code_) {
     instructions_writer_->WriteAssembly();
     instructions_snapshot_size_ = instructions_writer_->BytesWritten();
+
+    OS::Print("VMIsolate(CodeSize): %" Pd "\n", VmIsolateSnapshotSize());
+    OS::Print("Isolate(CodeSize): %" Pd "\n", IsolateSnapshotSize());
+    OS::Print("Instructions(CodeSize): %" Pd "\n",
+              instructions_writer_->binary_size());
+    intptr_t total = VmIsolateSnapshotSize() +
+                     IsolateSnapshotSize() +
+                     instructions_writer_->binary_size();
+    OS::Print("Total(CodeSize): %" Pd "\n", total);
   }
 }
 
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index 949f897..8570a06 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -54,6 +54,7 @@
 class RawImmutableArray;
 class RawInstructions;
 class RawInt32x4;
+class RawJSRegExp;
 class RawLanguageError;
 class RawLibrary;
 class RawLibraryPrefix;
@@ -87,6 +88,7 @@
 class RawTypeRef;
 class RawUnhandledException;
 class RawUnresolvedClass;
+class RawWeakProperty;
 class String;
 class TokenStream;
 class TypeArguments;
@@ -361,7 +363,7 @@
   String* StringHandle() { return &str_; }
   AbstractType* TypeHandle() { return &type_; }
   TypeArguments* TypeArgumentsHandle() { return &type_arguments_; }
-  Array* TokensHandle() { return &tokens_; }
+  GrowableObjectArray* TokensHandle() { return &tokens_; }
   TokenStream* StreamHandle() { return &stream_; }
   ExternalTypedData* DataHandle() { return &data_; }
   TypedData* TypedDataHandle() { return &typed_data_; }
@@ -444,6 +446,8 @@
   RawUnhandledException* NewUnhandledException();
   RawObject* NewInteger(int64_t value);
   RawStacktrace* NewStacktrace();
+  RawWeakProperty* NewWeakProperty();
+  RawJSRegExp* NewJSRegExp();
 
   RawInstructions* GetInstructionsAt(int32_t offset, uword expected_tags) {
     return instructions_reader_->GetInstructionsAt(offset, expected_tags);
@@ -483,19 +487,10 @@
                             intptr_t patch_object_id,
                             intptr_t patch_offset);
 
-  // Read an object reference from the stream.
-  RawObject* ReadObjectRef(intptr_t object_id,
-                           intptr_t class_header,
-                           intptr_t tags,
-                           intptr_t patch_object_id = kInvalidPatchIndex,
-                           intptr_t patch_offset = 0);
-
-  // Read an inlined object from the stream.
-  RawObject* ReadInlinedObject(intptr_t object_id,
-                               intptr_t class_header,
-                               intptr_t tags,
-                               intptr_t patch_object_id,
-                               intptr_t patch_offset);
+  // Read a Dart Instance object.
+  RawObject* ReadInstance(intptr_t object_id,
+                          intptr_t tags,
+                          bool as_reference);
 
   // Read a VM isolate object that was serialized as an Id.
   RawObject* ReadVMIsolateObject(intptr_t object_id);
@@ -546,7 +541,7 @@
   Library& library_;  // Temporary library handle.
   AbstractType& type_;  // Temporary type handle.
   TypeArguments& type_arguments_;  // Temporary type argument handle.
-  Array& tokens_;  // Temporary tokens handle.
+  GrowableObjectArray& tokens_;  // Temporary tokens handle.
   TokenStream& stream_;  // Temporary token stream handle.
   ExternalTypedData& data_;  // Temporary stream data handle.
   TypedData& typed_data_;  // Temporary typed data handle.
@@ -723,7 +718,7 @@
   BaseWriter(uint8_t** buffer,
              ReAlloc alloc,
              intptr_t initial_size)
-      : StackResource(Isolate::Current()),
+      : StackResource(Thread::Current()),
         stream_(buffer, alloc, initial_size) {
     ASSERT(buffer != NULL);
     ASSERT(alloc != NULL);
@@ -811,14 +806,17 @@
                      intptr_t initial_size)
     : stream_(buffer, alloc, initial_size),
       next_offset_(InstructionsSnapshot::kHeaderSize),
+      binary_size_(0),
       instructions_() {
     ASSERT(buffer != NULL);
     ASSERT(alloc != NULL);
   }
 
-  // Size of the snapshot.
+  // Size of the snapshot (assembly code).
   intptr_t BytesWritten() const { return stream_.bytes_written(); }
 
+  intptr_t binary_size() { return binary_size_; }
+
   int32_t GetOffsetFor(RawInstructions* instructions);
 
   void SetInstructionsCode(RawInstructions* insns, RawCode* code) {
@@ -855,10 +853,12 @@
 #else
     stream_.Print(".long 0x%0.8" Px "\n", value);
 #endif
+    binary_size_ += sizeof(value);
   }
 
   WriteStream stream_;
   intptr_t next_offset_;
+  intptr_t binary_size_;
   GrowableArray<InstructionsData> instructions_;
 
   DISALLOW_COPY_AND_ASSIGN(InstructionsWriter);
diff --git a/runtime/vm/snapshot_ids.h b/runtime/vm/snapshot_ids.h
index 856887d..436b2a8 100644
--- a/runtime/vm/snapshot_ids.h
+++ b/runtime/vm/snapshot_ids.h
@@ -54,6 +54,9 @@
   kCachedArgumentsDescriptor0,
   kCachedArgumentsDescriptorN = (kCachedArgumentsDescriptor0 +
       ArgumentsDescriptor::kCachedDescriptorCount - 1),
+  kCachedICDataArray0,
+  kCachedICDataArrayN = (kCachedICDataArray0 +
+      ICData::kCachedICDataArrayCount - 1),
 
   kInstanceObjectId,
   kStaticImplicitClosureObjectId,
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index 5103296..1b73e39 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -869,7 +869,9 @@
   const String& private_key = String::Handle(expected_tokens.PrivateKey());
   Scanner scanner(str, private_key);
   const TokenStream& reconstructed_tokens =
-      TokenStream::Handle(TokenStream::New(scanner.GetStream(), private_key));
+      TokenStream::Handle(TokenStream::New(scanner.GetStream(),
+                                           private_key,
+                                           false));
   expected_iterator.SetCurrentPosition(0);
   TokenStream::Iterator reconstructed_iterator(
       reconstructed_tokens, 0, TokenStream::Iterator::kAllTokens);
diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc
index 7594b91..3ec07cb 100644
--- a/runtime/vm/stack_frame.cc
+++ b/runtime/vm/stack_frame.cc
@@ -35,7 +35,7 @@
 
 
 const char* StackFrame::ToCString() const {
-  ASSERT(isolate_ == Isolate::Current());
+  ASSERT(thread_ == Thread::Current());
   Zone* zone = Thread::Current()->zone();
   if (IsDartFrame()) {
     const Code& code = Code::Handle(LookupDartCode());
@@ -68,7 +68,7 @@
 
 
 void EntryFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) {
-  ASSERT(isolate() == Isolate::Current());
+  ASSERT(thread() == Thread::Current());
   // Visit objects between SP and (FP - callee_save_area).
   ASSERT(visitor != NULL);
   RawObject** first = reinterpret_cast<RawObject**>(sp());
@@ -85,7 +85,7 @@
   // these handles are not traversed. The use of handles is mainly to
   // be able to reuse the handle based code and avoid having to add
   // helper functions to the raw object interface.
-  ASSERT(isolate_ == Isolate::Current());
+  ASSERT(thread() == Thread::Current());
   ASSERT(visitor != NULL);
   NoSafepointScope no_safepoint;
   Code code;
@@ -165,7 +165,6 @@
 
 
 RawFunction* StackFrame::LookupDartFunction() const {
-  ASSERT(isolate_ == Isolate::Current());
   const Code& code = Code::Handle(LookupDartCode());
   if (!code.IsNull()) {
     return code.function();
@@ -175,7 +174,6 @@
 
 
 RawCode* StackFrame::LookupDartCode() const {
-  ASSERT(isolate_ == Isolate::Current());
   // We add a no gc scope to ensure that the code below does not trigger
   // a GC as we are handling raw object references here. It is possible
   // that the code is called while a GC is in progress, that is ok.
@@ -261,7 +259,6 @@
 }
 
 
-
 bool StackFrame::IsValid() const {
   if (IsEntryFrame() || IsExitFrame() || IsStubFrame()) {
     return true;
@@ -271,7 +268,8 @@
 
 
 void StackFrameIterator::SetupLastExitFrameData() {
-  uword exit_marker = isolate_->top_exit_frame_info();
+  ASSERT(thread_ != NULL);
+  uword exit_marker = thread_->top_exit_frame_info();
   frames_.fp_ = exit_marker;
 }
 
@@ -285,6 +283,7 @@
 }
 
 
+// TODO(johnmccutchan): Remove |isolate| argument.
 // Tell MemorySanitizer that generated code initializes part of the stack.
 // TODO(koda): Limit to frames that are actually written by generated code.
 static void UnpoisonStack(Isolate* isolate, uword fp) {
@@ -294,28 +293,28 @@
 }
 
 
-StackFrameIterator::StackFrameIterator(bool validate, Isolate* isolate)
+StackFrameIterator::StackFrameIterator(bool validate, Thread* thread)
     : validate_(validate),
-      entry_(isolate),
-      exit_(isolate),
-      frames_(isolate),
+      entry_(thread),
+      exit_(thread),
+      frames_(thread),
       current_frame_(NULL),
-      isolate_(isolate) {
-  ASSERT((isolate_ == Isolate::Current()) ||
+      thread_(thread) {
+  ASSERT((thread_ == Thread::Current()) ||
          OS::AllowStackFrameIteratorFromAnotherThread());
   SetupLastExitFrameData();  // Setup data for last exit frame.
 }
 
 
 StackFrameIterator::StackFrameIterator(uword last_fp, bool validate,
-                                       Isolate* isolate)
+                                       Thread* thread)
     : validate_(validate),
-      entry_(isolate),
-      exit_(isolate),
-      frames_(isolate),
+      entry_(thread),
+      exit_(thread),
+      frames_(thread),
       current_frame_(NULL),
-      isolate_(isolate) {
-  ASSERT((isolate_ == Isolate::Current()) ||
+      thread_(thread) {
+  ASSERT((thread_ == Thread::Current()) ||
          OS::AllowStackFrameIteratorFromAnotherThread());
   frames_.fp_ = last_fp;
   frames_.sp_ = 0;
@@ -324,14 +323,14 @@
 
 
 StackFrameIterator::StackFrameIterator(uword fp, uword sp, uword pc,
-                                       bool validate, Isolate* isolate)
+                                       bool validate, Thread* thread)
     : validate_(validate),
-      entry_(isolate),
-      exit_(isolate),
-      frames_(isolate),
+      entry_(thread),
+      exit_(thread),
+      frames_(thread),
       current_frame_(NULL),
-      isolate_(isolate) {
-  ASSERT((isolate_ == Isolate::Current()) ||
+      thread_(thread) {
+  ASSERT((thread_ == Thread::Current()) ||
          OS::AllowStackFrameIteratorFromAnotherThread());
   frames_.fp_ = fp;
   frames_.sp_ = sp;
@@ -356,7 +355,7 @@
     if (!HasNextFrame()) {
       return NULL;
     }
-    UnpoisonStack(isolate_, frames_.fp_);
+    UnpoisonStack(thread_->isolate(), frames_.fp_);
     if (frames_.pc_ == 0) {
       // Iteration starts from an exit frame given by its fp.
       current_frame_ = NextExitFrame();
diff --git a/runtime/vm/stack_frame.h b/runtime/vm/stack_frame.h
index 2889a1e..1c59ccb 100644
--- a/runtime/vm/stack_frame.h
+++ b/runtime/vm/stack_frame.h
@@ -85,13 +85,15 @@
   intptr_t GetTokenPos() const;
 
  protected:
-  explicit StackFrame(Isolate* isolate)
-      : fp_(0), sp_(0), pc_(0), isolate_(isolate) { }
+  explicit StackFrame(Thread* thread)
+      : fp_(0), sp_(0), pc_(0), thread_(thread) { }
 
   // Name of the frame, used for generic frame printing functionality.
   virtual const char* GetName() const { return IsStubFrame()? "stub" : "dart"; }
 
-  Isolate* isolate() const { return isolate_; }
+  Isolate* isolate() const { return thread_->isolate(); }
+
+  Thread* thread() const { return thread_; }
 
  private:
   RawCode* GetCodeObject() const;
@@ -111,7 +113,7 @@
   uword fp_;
   uword sp_;
   uword pc_;
-  Isolate* isolate_;
+  Thread* thread_;
 
   // The iterators FrameSetIterator and StackFrameIterator set the private
   // fields fp_ and sp_ when they return the respective frame objects.
@@ -137,7 +139,7 @@
   virtual const char* GetName() const { return "exit"; }
 
  private:
-  explicit ExitFrame(Isolate* isolate) : StackFrame(isolate) { }
+  explicit ExitFrame(Thread* thread) : StackFrame(thread) { }
 
   friend class StackFrameIterator;
   DISALLOW_COPY_AND_ASSIGN(ExitFrame);
@@ -162,18 +164,18 @@
   virtual const char* GetName() const { return "entry"; }
 
  private:
-  explicit EntryFrame(Isolate* isolate) : StackFrame(isolate) { }
+  explicit EntryFrame(Thread* thread) : StackFrame(thread) { }
 
   friend class StackFrameIterator;
   DISALLOW_COPY_AND_ASSIGN(EntryFrame);
 };
 
 
-// A StackFrameIterator can be initialized with an isolate other than the
-// current thread's isolate. Because this is generally a bad idea,
-// it is only allowed on Windows- where it is needed for the profiler.
-// It is the responsibility of users of StackFrameIterator to ensure that the
-// isolate given is not running concurrently on another thread.
+// A StackFrameIterator can be initialized with a thread other than the
+// current thread. Because this is generally a bad idea, it is only allowed on
+// Windows- where it is needed for the profiler. It is the responsibility of
+// users of StackFrameIterator to ensure that the thread given is not running
+// concurrently.
 class StackFrameIterator : public ValueObject {
  public:
   static const bool kValidateFrames = true;
@@ -181,15 +183,15 @@
 
   // Iterators for iterating over all frames from the last ExitFrame to the
   // first EntryFrame.
-  explicit StackFrameIterator(bool validate,
-                              Isolate* isolate = Isolate::Current());
+  StackFrameIterator(bool validate,
+                     Thread* thread = Thread::Current());
   StackFrameIterator(uword last_fp, bool validate,
-                     Isolate* isolate = Isolate::Current());
+                     Thread* thread = Thread::Current());
 
   // Iterator for iterating over all frames from the current frame (given by its
   // fp, sp, and pc) to the first EntryFrame.
   StackFrameIterator(uword fp, uword sp, uword pc, bool validate,
-                     Isolate* isolate = Isolate::Current());
+                     Thread* thread = Thread::Current());
 
   // Checks if a next frame exists.
   bool HasNextFrame() const { return frames_.fp_ != 0; }
@@ -218,13 +220,13 @@
     StackFrame* NextFrame(bool validate);
 
    private:
-    explicit FrameSetIterator(Isolate* isolate)
-        : fp_(0), sp_(0), pc_(0), stack_frame_(isolate), isolate_(isolate) { }
+    explicit FrameSetIterator(Thread* thread)
+        : fp_(0), sp_(0), pc_(0), stack_frame_(thread), thread_(thread) { }
     uword fp_;
     uword sp_;
     uword pc_;
     StackFrame stack_frame_;  // Singleton frame returned by NextFrame().
-    Isolate* isolate_;
+    Thread* thread_;
 
     friend class StackFrameIterator;
     DISALLOW_COPY_AND_ASSIGN(FrameSetIterator);
@@ -250,7 +252,7 @@
   ExitFrame exit_;  // Singleton exit frame returned by NextExitFrame().
   FrameSetIterator frames_;
   StackFrame* current_frame_;  // Points to the current frame in the iterator.
-  Isolate* isolate_;
+  Thread* thread_;
 
   DISALLOW_COPY_AND_ASSIGN(StackFrameIterator);
 };
@@ -265,16 +267,17 @@
 // isolate given is not running concurrently on another thread.
 class DartFrameIterator : public ValueObject {
  public:
-  explicit DartFrameIterator(Isolate* isolate = Isolate::Current())
-      : frames_(StackFrameIterator::kDontValidateFrames, isolate) { }
+  explicit DartFrameIterator(Thread* thread = Thread::Current())
+      : frames_(StackFrameIterator::kDontValidateFrames, thread) { }
   DartFrameIterator(uword last_fp,
-                    Isolate* isolate = Isolate::Current())
-      : frames_(last_fp, StackFrameIterator::kDontValidateFrames, isolate) { }
+                    Thread* thread = Thread::Current())
+      : frames_(last_fp, StackFrameIterator::kDontValidateFrames, thread) { }
   DartFrameIterator(uword fp,
                     uword sp,
                     uword pc,
-                    Isolate* isolate = Isolate::Current())
-      : frames_(fp, sp, pc, StackFrameIterator::kDontValidateFrames, isolate) {
+                    Thread* thread = Thread::Current())
+      : frames_(fp, sp, pc,
+                StackFrameIterator::kDontValidateFrames, thread) {
   }
   // Get next dart frame.
   StackFrame* NextFrame() {
diff --git a/runtime/vm/stack_frame_arm.h b/runtime/vm/stack_frame_arm.h
index 8f22815..ca89fb5 100644
--- a/runtime/vm/stack_frame_arm.h
+++ b/runtime/vm/stack_frame_arm.h
@@ -43,7 +43,15 @@
 static const int kCallerSpSlotFromFp = 2;
 
 // Entry and exit frame layout.
+#if defined(TARGET_OS_MAC)
+static const int kExitLinkSlotFromEntryFp = -26;
+COMPILE_ASSERT(kAbiPreservedCpuRegCount == 6);
+COMPILE_ASSERT(kAbiPreservedFpuRegCount == 4);
+#else
 static const int kExitLinkSlotFromEntryFp = -27;
+COMPILE_ASSERT(kAbiPreservedCpuRegCount == 7);
+COMPILE_ASSERT(kAbiPreservedFpuRegCount == 4);
+#endif
 
 }  // namespace dart
 
diff --git a/runtime/vm/stack_frame_arm64.h b/runtime/vm/stack_frame_arm64.h
index 6733724..a48be15 100644
--- a/runtime/vm/stack_frame_arm64.h
+++ b/runtime/vm/stack_frame_arm64.h
@@ -44,7 +44,9 @@
 static const int kSavedAboveReturnAddress = 3;  // Saved above return address.
 
 // Entry and exit frame layout.
-static const int kExitLinkSlotFromEntryFp = -22;
+static const int kExitLinkSlotFromEntryFp = -21;
+COMPILE_ASSERT(kAbiPreservedCpuRegCount == 9);
+COMPILE_ASSERT(kAbiPreservedFpuRegCount == 8);
 
 }  // namespace dart
 
diff --git a/runtime/vm/stack_frame_mips.h b/runtime/vm/stack_frame_mips.h
index 3f7c7e5..35c9aba 100644
--- a/runtime/vm/stack_frame_mips.h
+++ b/runtime/vm/stack_frame_mips.h
@@ -42,6 +42,8 @@
 
 // Entry and exit frame layout.
 static const int kExitLinkSlotFromEntryFp = -24;
+COMPILE_ASSERT(kAbiPreservedCpuRegCount == 8);
+COMPILE_ASSERT(kAbiPreservedFpuRegCount == 12);
 
 }  // namespace dart
 
diff --git a/runtime/vm/stub_code.cc b/runtime/vm/stub_code.cc
index 7c8fe78..e991fdb 100644
--- a/runtime/vm/stub_code.cc
+++ b/runtime/vm/stub_code.cc
@@ -79,7 +79,16 @@
 }
 
 
+bool StubCode::HasBeenInitialized() {
+  // Use JumpToExceptionHandler and InvokeDart as canaries.
+  const StubEntry* entry_1 = StubCode::JumpToExceptionHandler_entry();
+  const StubEntry* entry_2 = StubCode::InvokeDartCode_entry();
+  return (entry_1 != NULL) && (entry_2 != NULL);
+}
+
+
 bool StubCode::InInvocationStub(uword pc) {
+  ASSERT(HasBeenInitialized());
   uword entry = StubCode::InvokeDartCode_entry()->EntryPoint();
   uword size = StubCode::InvokeDartCodeSize();
   return (pc >= entry) && (pc < (entry + size));
@@ -87,6 +96,7 @@
 
 
 bool StubCode::InJumpToExceptionHandlerStub(uword pc) {
+  ASSERT(HasBeenInitialized());
   uword entry = StubCode::JumpToExceptionHandler_entry()->EntryPoint();
   uword size = StubCode::JumpToExceptionHandlerSize();
   return (pc >= entry) && (pc < (entry + size));
@@ -106,7 +116,7 @@
     Assembler assembler;
     const char* name = cls.ToCString();
     StubCode::GenerateAllocationStubForClass(&assembler, cls);
-    stub ^= Code::FinalizeCode(name, &assembler);
+    stub ^= Code::FinalizeCode(name, &assembler, false /* optimized */);
     stub.set_owner(cls);
     cls.set_allocation_stub(stub);
     if (FLAG_disassemble_stubs) {
@@ -143,7 +153,8 @@
                             void (*GenerateStub)(Assembler* assembler)) {
   Assembler assembler;
   GenerateStub(&assembler);
-  const Code& code = Code::Handle(Code::FinalizeCode(name, &assembler));
+  const Code& code = Code::Handle(
+      Code::FinalizeCode(name, &assembler, false /* optimized */));
   if (FLAG_disassemble_stubs) {
     LogBlock lb;
     THR_Print("Code for stub '%s': {\n", name);
diff --git a/runtime/vm/stub_code.h b/runtime/vm/stub_code.h
index e7da564..f451638 100644
--- a/runtime/vm/stub_code.h
+++ b/runtime/vm/stub_code.h
@@ -35,6 +35,7 @@
   V(OptimizeFunction)                                                          \
   V(InvokeDartCode)                                                            \
   V(DebugStepCheck)                                                            \
+  V(ICLookup)                                                                  \
   V(MegamorphicLookup)                                                         \
   V(FixAllocationStubTarget)                                                   \
   V(Deoptimize)                                                                \
@@ -60,7 +61,7 @@
   V(Subtype1TestCache)                                                         \
   V(Subtype2TestCache)                                                         \
   V(Subtype3TestCache)                                                         \
-  V(CallClosureNoSuchMethod)
+  V(CallClosureNoSuchMethod)                                                   \
 
 // Is it permitted for the stubs above to refer to Object::null(), which is
 // allocated in the VM isolate and shared across all isolates.
@@ -109,6 +110,9 @@
 
   static void VisitObjectPointers(ObjectPointerVisitor* visitor);
 
+  // Returns true if stub code has been initialized.
+  static bool HasBeenInitialized();
+
   // Check if specified pc is in the dart invocation stub used for
   // transitioning into dart code.
   static bool InInvocationStub(uword pc);
@@ -136,8 +140,7 @@
 
   static const intptr_t kNoInstantiator = 0;
 
-  static void EmitMegamorphicLookup(
-      Assembler*, Register recv, Register cache, Register target);
+  static void EmitMegamorphicLookup(Assembler* assembler);
 
  private:
   friend class MegamorphicCacheTable;
diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc
index 5acd669..711c901 100644
--- a/runtime/vm/stub_code_arm.cc
+++ b/runtime/vm/stub_code_arm.cc
@@ -35,7 +35,7 @@
 //   SP : address of last argument in argument array.
 //   SP + 4*R4 - 4 : address of first argument in argument array.
 //   SP + 4*R4 : address of return value.
-//   R5 : address of the runtime function to call.
+//   R9 : address of the runtime function to call.
 //   R4 : number of arguments to the call.
 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
   const intptr_t thread_offset = NativeArguments::thread_offset();
@@ -52,8 +52,8 @@
 #if defined(DEBUG)
   { Label ok;
     // Check that we are always entering from Dart code.
-    __ LoadFromOffset(kWord, R6, THR, Thread::vm_tag_offset());
-    __ CompareImmediate(R6, VMTag::kDartTagId);
+    __ LoadFromOffset(kWord, R8, THR, Thread::vm_tag_offset());
+    __ CompareImmediate(R8, VMTag::kDartTagId);
     __ b(&ok, EQ);
     __ Stop("Not coming from Dart code.");
     __ Bind(&ok);
@@ -61,7 +61,7 @@
 #endif
 
   // Mark that the thread is executing VM code.
-  __ StoreToOffset(kWord, R5, THR, Thread::vm_tag_offset());
+  __ StoreToOffset(kWord, R9, THR, Thread::vm_tag_offset());
 
   // Reserve space for arguments and align frame before entering C++ world.
   // NativeArguments are passed in registers.
@@ -89,7 +89,7 @@
   __ add(R3, R2, Operand(kWordSize));  // Retval is next to 1st argument.
 
   // Call runtime or redirection via simulator.
-  __ blx(R5);
+  __ blx(R9);
 
   // Mark that the thread is executing Dart code.
   __ LoadImmediate(R2, VMTag::kDartTagId);
@@ -126,7 +126,7 @@
 // Input parameters:
 //   LR : return address.
 //   SP : address of return value.
-//   R5 : address of the native function to call.
+//   R9 : address of the native function to call.
 //   R2 : address of first argument in argument array.
 //   R1 : argc_tag including number of arguments and function kind.
 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
@@ -144,8 +144,8 @@
 #if defined(DEBUG)
   { Label ok;
     // Check that we are always entering from Dart code.
-    __ LoadFromOffset(kWord, R6, THR, Thread::vm_tag_offset());
-    __ CompareImmediate(R6, VMTag::kDartTagId);
+    __ LoadFromOffset(kWord, R8, THR, Thread::vm_tag_offset());
+    __ CompareImmediate(R8, VMTag::kDartTagId);
     __ b(&ok, EQ);
     __ Stop("Not coming from Dart code.");
     __ Bind(&ok);
@@ -153,7 +153,7 @@
 #endif
 
   // Mark that the thread is executing native code.
-  __ StoreToOffset(kWord, R5, THR, Thread::vm_tag_offset());
+  __ StoreToOffset(kWord, R9, THR, Thread::vm_tag_offset());
 
   // Reserve space for the native arguments structure passed on the stack (the
   // outgoing pointer parameter to the native arguments structure is passed in
@@ -185,7 +185,7 @@
   __ stm(IA, SP,  (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3));
   __ mov(R0, Operand(SP));  // Pass the pointer to the NativeArguments.
 
-  __ mov(R1, Operand(R5));  // Pass the function entrypoint to call.
+  __ mov(R1, Operand(R9));  // Pass the function entrypoint to call.
 
   // Call native function invocation wrapper or redirection via simulator.
   __ ldr(LR, Address(THR, Thread::native_call_wrapper_entry_point_offset()));
@@ -207,7 +207,7 @@
 // Input parameters:
 //   LR : return address.
 //   SP : address of return value.
-//   R5 : address of the native function to call.
+//   R9 : address of the native function to call.
 //   R2 : address of first argument in argument array.
 //   R1 : argc_tag including number of arguments and function kind.
 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) {
@@ -225,8 +225,8 @@
 #if defined(DEBUG)
   { Label ok;
     // Check that we are always entering from Dart code.
-    __ LoadFromOffset(kWord, R6, THR, Thread::vm_tag_offset());
-    __ CompareImmediate(R6, VMTag::kDartTagId);
+    __ LoadFromOffset(kWord, R8, THR, Thread::vm_tag_offset());
+    __ CompareImmediate(R8, VMTag::kDartTagId);
     __ b(&ok, EQ);
     __ Stop("Not coming from Dart code.");
     __ Bind(&ok);
@@ -234,7 +234,7 @@
 #endif
 
   // Mark that the thread is executing native code.
-  __ StoreToOffset(kWord, R5, THR, Thread::vm_tag_offset());
+  __ StoreToOffset(kWord, R9, THR, Thread::vm_tag_offset());
 
   // Reserve space for the native arguments structure passed on the stack (the
   // outgoing pointer parameter to the native arguments structure is passed in
@@ -267,7 +267,7 @@
   __ mov(R0, Operand(SP));  // Pass the pointer to the NativeArguments.
 
   // Call native function or redirection via simulator.
-  __ blx(R5);
+  __ blx(R9);
 
   // Mark that the thread is executing Dart code.
   __ LoadImmediate(R2, VMTag::kDartTagId);
@@ -419,6 +419,9 @@
   __ eor(IP, IP, Operand(LR));
 
   // Set up the frame manually with return address now stored in IP.
+  COMPILE_ASSERT(PP < CODE_REG);
+  COMPILE_ASSERT(CODE_REG < FP);
+  COMPILE_ASSERT(FP < IP);
   __ EnterFrame((1 << PP) | (1 << CODE_REG) | (1 << FP) | (1 << IP), 0);
   __ LoadPoolPointer();
 
@@ -434,9 +437,12 @@
     if (i == CODE_REG) {
       // Save the original value of CODE_REG pushed before invoking this stub
       // instead of the value used to call this stub.
-      COMPILE_ASSERT(IP > CODE_REG);  // Assert IP is pushed first.
       __ ldr(IP, Address(FP, kCallerSpSlotFromFp * kWordSize));
       __ Push(IP);
+    } else if (i == SP) {
+      // Push(SP) has unpredictable behavior.
+      __ mov(IP, Operand(SP));
+      __ Push(IP);
     } else {
       __ Push(static_cast<Register>(i));
     }
@@ -537,11 +543,11 @@
   // Load the receiver.
   __ ldr(R2, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
   __ add(IP, FP, Operand(R2, LSL, 1));  // R2 is Smi.
-  __ ldr(R6, Address(IP, kParamEndSlotFromFp * kWordSize));
+  __ ldr(R8, Address(IP, kParamEndSlotFromFp * kWordSize));
   __ PushObject(Object::null_object());
-  __ Push(R6);
-  __ Push(R5);
-  __ Push(R4);
+  __ Push(R8);  // Receiver.
+  __ Push(R9);  // ICData/MegamorphicCache.
+  __ Push(R4);  // Arguments descriptor.
   // R2: Smi-tagged arguments array length.
   PushArgumentsArray(assembler);
   const intptr_t kNumArgs = 4;
@@ -559,24 +565,23 @@
   // Load the receiver.
   __ ldr(R2, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
   __ add(IP, FP, Operand(R2, LSL, 1));  // R2 is Smi.
-  __ ldr(R6, Address(IP, kParamEndSlotFromFp * kWordSize));
+  __ ldr(R8, Address(IP, kParamEndSlotFromFp * kWordSize));
 
   // Preserve IC data and arguments descriptor.
-  __ PushList((1 << R4) | (1 << R5));
+  __ PushList((1 << R4) | (1 << R9));
 
-  // Push space for the return value.
-  // Push the receiver.
-  // Push IC data object.
-  // Push arguments descriptor array.
   __ LoadObject(IP, Object::null_object());
-  __ PushList((1 << R4) | (1 << R5) | (1 << R6) | (1 << IP));
+  __ Push(IP);  // result
+  __ Push(R8);  // receiver
+  __ Push(R9);  // ICData
+  __ Push(R4);  // arguments descriptor
   __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3);
   // Remove arguments.
   __ Drop(3);
   __ Pop(R0);  // Get result into R0 (target function).
 
   // Restore IC data and arguments descriptor.
-  __ PopList((1 << R4) | (1 << R5));
+  __ PopList((1 << R4) | (1 << R9));
 
   __ RestoreCodePointer();
   __ LeaveStubFrame();
@@ -627,55 +632,55 @@
                           /* inline_isolate = */ false);
 
   const intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1;
-  __ LoadImmediate(R5, fixed_size);
-  __ add(R5, R5, Operand(R3, LSL, 1));  // R3 is  a Smi.
+  __ LoadImmediate(R9, fixed_size);
+  __ add(R9, R9, Operand(R3, LSL, 1));  // R3 is  a Smi.
   ASSERT(kSmiTagShift == 1);
-  __ bic(R5, R5, Operand(kObjectAlignment - 1));
+  __ bic(R9, R9, Operand(kObjectAlignment - 1));
 
-  // R5: Allocation size.
+  // R9: Allocation size.
   Heap::Space space = Heap::SpaceForAllocation(cid);
-  __ LoadIsolate(R6);
-  __ ldr(R6, Address(R6, Isolate::heap_offset()));
+  __ LoadIsolate(R8);
+  __ ldr(R8, Address(R8, Isolate::heap_offset()));
   // Potential new object start.
-  __ ldr(R0, Address(R6, Heap::TopOffset(space)));
-  __ adds(R7, R0, Operand(R5));  // Potential next object start.
+  __ ldr(R0, Address(R8, Heap::TopOffset(space)));
+  __ adds(NOTFP, R0, Operand(R9));  // Potential next object start.
   __ b(&slow_case, CS);  // Branch if unsigned overflow.
 
   // Check if the allocation fits into the remaining space.
   // R0: potential new object start.
-  // R7: potential next object start.
-  // R5: allocation size.
-  __ ldr(R3, Address(R6, Heap::EndOffset(space)));
-  __ cmp(R7, Operand(R3));
+  // NOTFP: potential next object start.
+  // R9: allocation size.
+  __ ldr(R3, Address(R8, Heap::EndOffset(space)));
+  __ cmp(NOTFP, Operand(R3));
   __ b(&slow_case, CS);
 
   // Successfully allocated the object(s), now update top to point to
   // next object start and initialize the object.
   __ LoadAllocationStatsAddress(R3, cid, /* inline_isolate = */ false);
-  __ str(R7, Address(R6, Heap::TopOffset(space)));
+  __ str(NOTFP, Address(R8, Heap::TopOffset(space)));
   __ add(R0, R0, Operand(kHeapObjectTag));
 
   // Initialize the tags.
   // R0: new object start as a tagged pointer.
   // R3: allocation stats address.
-  // R7: new object end address.
-  // R5: allocation size.
+  // NOTFP: new object end address.
+  // R9: allocation size.
   {
     const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2;
 
-    __ CompareImmediate(R5, RawObject::SizeTag::kMaxSizeTag);
-    __ mov(R6, Operand(R5, LSL, shift), LS);
-    __ mov(R6, Operand(0), HI);
+    __ CompareImmediate(R9, RawObject::SizeTag::kMaxSizeTag);
+    __ mov(R8, Operand(R9, LSL, shift), LS);
+    __ mov(R8, Operand(0), HI);
 
     // Get the class index and insert it into the tags.
-    // R6: size and bit tags.
+    // R8: size and bit tags.
     __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(cid));
-    __ orr(R6, R6, Operand(TMP));
-    __ str(R6, FieldAddress(R0, Array::tags_offset()));  // Store tags.
+    __ orr(R8, R8, Operand(TMP));
+    __ str(R8, FieldAddress(R0, Array::tags_offset()));  // Store tags.
   }
 
   // R0: new object start as a tagged pointer.
-  // R7: new object end address.
+  // NOTFP: new object end address.
   // Store the type argument field.
   __ InitializeFieldNoBarrier(R0,
                               FieldAddress(R0, Array::type_arguments_offset()),
@@ -689,17 +694,17 @@
   // Initialize all array elements to raw_null.
   // R0: new object start as a tagged pointer.
   // R3: allocation stats address.
-  // R4, R5: null
-  // R6: iterator which initially points to the start of the variable
+  // R8, R9: null
+  // R4: iterator which initially points to the start of the variable
   // data area to be initialized.
-  // R7: new object end address.
-  // R5: allocation size.
-  __ IncrementAllocationStatsWithSize(R3, R5, space);
+  // NOTFP: new object end address.
+  // R9: allocation size.
+  __ IncrementAllocationStatsWithSize(R3, R9, space);
 
-  __ LoadObject(R4, Object::null_object());
-  __ mov(R5, Operand(R4));
-  __ AddImmediate(R6, R0, sizeof(RawArray) - kHeapObjectTag);
-  __ InitializeFieldsNoBarrier(R0, R6, R7, R4, R5);
+  __ LoadObject(R8, Object::null_object());
+  __ mov(R9, Operand(R8));
+  __ AddImmediate(R4, R0, sizeof(RawArray) - kHeapObjectTag);
+  __ InitializeFieldsNoBarrier(R0, R4, NOTFP, R8, R9);
   __ Ret();  // Returns the newly allocated object in R0.
   // Unable to allocate the array using the fast inline code, just call
   // into the runtime.
@@ -754,32 +759,36 @@
   }
 
   // Save the current VMTag on the stack.
-  __ LoadFromOffset(kWord, R5, THR, Thread::vm_tag_offset());
-  __ Push(R5);
+  __ LoadFromOffset(kWord, R9, THR, Thread::vm_tag_offset());
+  __ Push(R9);
 
   // Mark that the thread is executing Dart code.
-  __ LoadImmediate(R5, VMTag::kDartTagId);
-  __ StoreToOffset(kWord, R5, THR, Thread::vm_tag_offset());
+  __ LoadImmediate(R9, VMTag::kDartTagId);
+  __ StoreToOffset(kWord, R9, THR, Thread::vm_tag_offset());
 
   // Save top resource and top exit frame info. Use R4-6 as temporary registers.
   // StackFrameIterator reads the top exit frame info saved in this frame.
-  __ LoadFromOffset(kWord, R5, THR, Thread::top_exit_frame_info_offset());
+  __ LoadFromOffset(kWord, R9, THR, Thread::top_exit_frame_info_offset());
   __ LoadFromOffset(kWord, R4, THR, Thread::top_resource_offset());
-  __ LoadImmediate(R6, 0);
-  __ StoreToOffset(kWord, R6, THR, Thread::top_resource_offset());
-  __ StoreToOffset(kWord, R6, THR, Thread::top_exit_frame_info_offset());
+  __ LoadImmediate(R8, 0);
+  __ StoreToOffset(kWord, R8, THR, Thread::top_resource_offset());
+  __ StoreToOffset(kWord, R8, THR, Thread::top_exit_frame_info_offset());
 
   // kExitLinkSlotFromEntryFp must be kept in sync with the code below.
   __ Push(R4);
+#if defined(TARGET_OS_MAC)
+  ASSERT(kExitLinkSlotFromEntryFp == -26);
+#else
   ASSERT(kExitLinkSlotFromEntryFp == -27);
-  __ Push(R5);
+#endif
+  __ Push(R9);
 
   // Load arguments descriptor array into R4, which is passed to Dart code.
   __ ldr(R4, Address(R1, VMHandles::kOffsetOfRawPtrInHandle));
 
-  // Load number of arguments into R5.
-  __ ldr(R5, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
-  __ SmiUntag(R5);
+  // Load number of arguments into R9.
+  __ ldr(R9, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
+  __ SmiUntag(R9);
 
   // Compute address of 'arguments array' data area into R2.
   __ ldr(R2, Address(R2, VMHandles::kOffsetOfRawPtrInHandle));
@@ -788,7 +797,7 @@
   // Set up arguments for the Dart call.
   Label push_arguments;
   Label done_push_arguments;
-  __ CompareImmediate(R5, 0);  // check if there are arguments.
+  __ CompareImmediate(R9, 0);  // check if there are arguments.
   __ b(&done_push_arguments, EQ);
   __ LoadImmediate(R1, 0);
   __ Bind(&push_arguments);
@@ -796,7 +805,7 @@
   __ Push(R3);
   __ AddImmediate(R2, kWordSize);
   __ AddImmediate(R1, 1);
-  __ cmp(R1, Operand(R5));
+  __ cmp(R1, Operand(R9));
   __ b(&push_arguments, LT);
   __ Bind(&done_push_arguments);
 
@@ -810,11 +819,11 @@
   __ AddImmediate(SP, FP, kExitLinkSlotFromEntryFp * kWordSize);
 
   // Restore the saved top exit frame info and top resource back into the
-  // Isolate structure. Uses R5 as a temporary register for this.
-  __ Pop(R5);
-  __ StoreToOffset(kWord, R5, THR, Thread::top_exit_frame_info_offset());
-  __ Pop(R5);
-  __ StoreToOffset(kWord, R5, THR, Thread::top_resource_offset());
+  // Isolate structure. Uses R9 as a temporary register for this.
+  __ Pop(R9);
+  __ StoreToOffset(kWord, R9, THR, Thread::top_exit_frame_info_offset());
+  __ Pop(R9);
+  __ StoreToOffset(kWord, R9, THR, Thread::top_resource_offset());
 
   // Restore the current VMTag from the stack.
   __ Pop(R4);
@@ -853,24 +862,24 @@
     ASSERT(kSmiTagShift == 1);
     __ bic(R2, R2, Operand(kObjectAlignment - 1));
 
-    __ MaybeTraceAllocation(kContextCid, R4, &slow_case,
+    __ MaybeTraceAllocation(kContextCid, R8, &slow_case,
                             /* inline_isolate = */ false);
     // Now allocate the object.
     // R1: number of context variables.
     // R2: object size.
     const intptr_t cid = kContextCid;
     Heap::Space space = Heap::SpaceForAllocation(cid);
-    __ LoadIsolate(R5);
-    __ ldr(R5, Address(R5, Isolate::heap_offset()));
-    __ ldr(R0, Address(R5, Heap::TopOffset(space)));
+    __ LoadIsolate(R9);
+    __ ldr(R9, Address(R9, Isolate::heap_offset()));
+    __ ldr(R0, Address(R9, Heap::TopOffset(space)));
     __ add(R3, R2, Operand(R0));
     // Check if the allocation fits into the remaining space.
     // R0: potential new object.
     // R1: number of context variables.
     // R2: object size.
     // R3: potential next object start.
-    // R5: heap.
-    __ ldr(IP, Address(R5, Heap::EndOffset(space)));
+    // R9: heap.
+    __ ldr(IP, Address(R9, Heap::EndOffset(space)));
     __ cmp(R3, Operand(IP));
     if (FLAG_use_slow_path) {
       __ b(&slow_case);
@@ -884,9 +893,9 @@
     // R1: number of context variables.
     // R2: object size.
     // R3: next object start.
-    // R5: heap.
-    __ LoadAllocationStatsAddress(R6, cid, /* inline_isolate = */ false);
-    __ str(R3, Address(R5, Heap::TopOffset(space)));
+    // R9: heap.
+    __ LoadAllocationStatsAddress(R4, cid, /* inline_isolate = */ false);
+    __ str(R3, Address(R9, Heap::TopOffset(space)));
     __ add(R0, R0, Operand(kHeapObjectTag));
 
     // Calculate the size tag.
@@ -894,25 +903,25 @@
     // R1: number of context variables.
     // R2: object size.
     // R3: next object start.
-    // R6: allocation stats address.
+    // R4: allocation stats address.
     const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2;
     __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag);
     // If no size tag overflow, shift R2 left, else set R2 to zero.
-    __ mov(R5, Operand(R2, LSL, shift), LS);
-    __ mov(R5, Operand(0), HI);
+    __ mov(R9, Operand(R2, LSL, shift), LS);
+    __ mov(R9, Operand(0), HI);
 
     // Get the class index and insert it into the tags.
-    // R5: size and bit tags.
+    // R9: size and bit tags.
     __ LoadImmediate(IP, RawObject::ClassIdTag::encode(cid));
-    __ orr(R5, R5, Operand(IP));
-    __ str(R5, FieldAddress(R0, Context::tags_offset()));
+    __ orr(R9, R9, Operand(IP));
+    __ str(R9, FieldAddress(R0, Context::tags_offset()));
 
     // Setup up number of context variables field.
     // R0: new object.
     // R1: number of context variables as integer value (not object).
     // R2: object size.
     // R3: next object start.
-    // R6: allocation stats address.
+    // R4: allocation stats address.
     __ str(R1, FieldAddress(R0, Context::num_variables_offset()));
 
     // Setup the parent field.
@@ -920,22 +929,22 @@
     // R1: number of context variables.
     // R2: object size.
     // R3: next object start.
-    // R6: allocation stats address.
-    __ LoadObject(R4, Object::null_object());
+    // R4: allocation stats address.
+    __ LoadObject(R8, Object::null_object());
     __ InitializeFieldNoBarrier(R0, FieldAddress(R0, Context::parent_offset()),
-                                R4);
+                                R8);
 
     // Initialize the context variables.
     // R0: new object.
     // R1: number of context variables.
     // R2: object size.
     // R3: next object start.
-    // R4, R5: raw null.
-    // R6: allocation stats address.
+    // R8, R9: raw null.
+    // R4: allocation stats address.
     Label loop;
-    __ AddImmediate(R7, R0, Context::variable_offset(0) - kHeapObjectTag);
-    __ InitializeFieldsNoBarrier(R0, R7, R3, R4, R5);
-    __ IncrementAllocationStatsWithSize(R6, R2, space);
+    __ AddImmediate(NOTFP, R0, Context::variable_offset(0) - kHeapObjectTag);
+    __ InitializeFieldsNoBarrier(R0, NOTFP, R3, R8, R9);
+    __ IncrementAllocationStatsWithSize(R4, R2, space);
 
     // Done allocating and initializing the context.
     // R0: new object.
@@ -1040,7 +1049,7 @@
 void StubCode::GenerateAllocationStubForClass(Assembler* assembler,
                                               const Class& cls) {
   // Must load pool pointer before being able to patch.
-  Register new_pp = R7;
+  Register new_pp = NOTFP;
   __ LoadPoolPointer(new_pp);
   // The generated code is different if the class is parameterized.
   const bool is_cls_parameterized = cls.NumTypeArguments() > 0;
@@ -1059,29 +1068,29 @@
     // Allocate the object and update top to point to
     // next object start and initialize the allocated object.
     Heap::Space space = Heap::SpaceForAllocation(cls.id());
-    __ ldr(R5, Address(THR, Thread::heap_offset()));
-    __ ldr(R0, Address(R5, Heap::TopOffset(space)));
+    __ ldr(R9, Address(THR, Thread::heap_offset()));
+    __ ldr(R0, Address(R9, Heap::TopOffset(space)));
     __ AddImmediate(R1, R0, instance_size);
     // Check if the allocation fits into the remaining space.
     // R0: potential new object start.
     // R1: potential next object start.
-    // R5: heap.
-    __ ldr(IP, Address(R5, Heap::EndOffset(space)));
+    // R9: heap.
+    __ ldr(IP, Address(R9, Heap::EndOffset(space)));
     __ cmp(R1, Operand(IP));
     if (FLAG_use_slow_path) {
       __ b(&slow_case);
     } else {
       __ b(&slow_case, CS);  // Unsigned higher or equal.
     }
-    __ str(R1, Address(R5, Heap::TopOffset(space)));
+    __ str(R1, Address(R9, Heap::TopOffset(space)));
 
     // Load the address of the allocation stats table. We split up the load
     // and the increment so that the dependent load is not too nearby.
-    __ LoadAllocationStatsAddress(R5, cls.id(), /* inline_isolate = */ false);
+    __ LoadAllocationStatsAddress(R9, cls.id(), /* inline_isolate = */ false);
 
     // R0: new object start.
     // R1: next object start.
-    // R5: allocation stats table.
+    // R9: allocation stats table.
     // Set the tags.
     uword tags = 0;
     tags = RawObject::SizeTag::update(instance_size, tags);
@@ -1097,7 +1106,7 @@
     // R2: raw null.
     // R0: new object (tagged).
     // R1: next object start.
-    // R5: allocation stats table.
+    // R9: allocation stats table.
     // First try inlining the initialization without a loop.
     if (instance_size < (kInlineInstanceSize * kWordSize)) {
       // Small objects are initialized using a consecutive set of writes.
@@ -1119,7 +1128,7 @@
       // R0: new object (tagged).
       // R1: next object start.
       // R4: next word to be initialized.
-      // R5: allocation stats table.
+      // R9: allocation stats table.
       __ InitializeFieldsNoBarrier(R0, R4, R1, R2, R3);
     }
     if (is_cls_parameterized) {
@@ -1131,10 +1140,10 @@
 
     // Done allocating and initializing the instance.
     // R0: new object (tagged).
-    // R5: allocation stats table.
+    // R9: allocation stats table.
 
     // Update allocation stats.
-    __ IncrementAllocationStats(R5, cls.id(), space);
+    __ IncrementAllocationStats(R9, cls.id(), space);
 
     // R0: new object (tagged).
     __ Ret();
@@ -1183,13 +1192,13 @@
   // Load the receiver.
   __ ldr(R2, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
   __ add(IP, FP, Operand(R2, LSL, 1));  // R2 is Smi.
-  __ ldr(R6, Address(IP, kParamEndSlotFromFp * kWordSize));
+  __ ldr(R8, Address(IP, kParamEndSlotFromFp * kWordSize));
 
   // Push space for the return value.
   // Push the receiver.
   // Push arguments descriptor array.
   __ LoadObject(IP, Object::null_object());
-  __ PushList((1 << R4) | (1 << R6) | (1 << IP));
+  __ PushList((1 << R4) | (1 << R8) | (1 << IP));
 
   // R2: Smi-tagged arguments array length.
   PushArgumentsArray(assembler);
@@ -1201,26 +1210,26 @@
 }
 
 
-//  R6: function object.
-//  R5: inline cache data object.
+//  R8: function object.
+//  R9: inline cache data object.
 // Cannot use function object from ICData as it may be the inlined
 // function and not the top-scope function.
 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) {
-  Register ic_reg = R5;
-  Register func_reg = R6;
+  Register ic_reg = R9;
+  Register func_reg = R8;
   if (FLAG_trace_optimized_ic_calls) {
     __ EnterStubFrame();
-    __ PushList((1 << R5) | (1 << R6));  // Preserve.
+    __ PushList((1 << R9) | (1 << R8));  // Preserve.
     __ Push(ic_reg);  // Argument.
     __ Push(func_reg);  // Argument.
     __ CallRuntime(kTraceICCallRuntimeEntry, 2);
     __ Drop(2);  // Discard argument;
-    __ PopList((1 << R5) | (1 << R6));  // Restore.
+    __ PopList((1 << R9) | (1 << R8));  // Restore.
     __ LeaveStubFrame();
   }
-  __ ldr(R7, FieldAddress(func_reg, Function::usage_counter_offset()));
-  __ add(R7, R7, Operand(1));
-  __ str(R7, FieldAddress(func_reg, Function::usage_counter_offset()));
+  __ ldr(NOTFP, FieldAddress(func_reg, Function::usage_counter_offset()));
+  __ add(NOTFP, NOTFP, Operand(1));
+  __ str(NOTFP, FieldAddress(func_reg, Function::usage_counter_offset()));
 }
 
 
@@ -1228,19 +1237,19 @@
 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler,
                                              Register temp_reg) {
   if (FLAG_optimization_counter_threshold >= 0) {
-    Register ic_reg = R5;
+    Register ic_reg = R9;
     Register func_reg = temp_reg;
-    ASSERT(temp_reg == R6);
+    ASSERT(temp_reg == R8);
     __ Comment("Increment function counter");
     __ ldr(func_reg, FieldAddress(ic_reg, ICData::owner_offset()));
-    __ ldr(R7, FieldAddress(func_reg, Function::usage_counter_offset()));
-    __ add(R7, R7, Operand(1));
-    __ str(R7, FieldAddress(func_reg, Function::usage_counter_offset()));
+    __ ldr(NOTFP, FieldAddress(func_reg, Function::usage_counter_offset()));
+    __ add(NOTFP, NOTFP, Operand(1));
+    __ str(NOTFP, FieldAddress(func_reg, Function::usage_counter_offset()));
   }
 }
 
 
-// Note: R5 must be preserved.
+// Note: R9 must be preserved.
 // Attempt a quick Smi operation for known operations ('kind'). The ICData
 // must have been primed with a Smi/Smi check that will be used for counting
 // the invocations.
@@ -1273,19 +1282,19 @@
     }
     default: UNIMPLEMENTED();
   }
-  // R5: IC data object (preserved).
-  __ ldr(R6, FieldAddress(R5, ICData::ic_data_offset()));
-  // R6: ic_data_array with check entries: classes and target functions.
-  __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag);
-  // R6: points directly to the first ic data array element.
+  // R9: IC data object (preserved).
+  __ ldr(R8, FieldAddress(R9, ICData::ic_data_offset()));
+  // R8: ic_data_array with check entries: classes and target functions.
+  __ AddImmediate(R8, R8, Array::data_offset() - kHeapObjectTag);
+  // R8: points directly to the first ic data array element.
 #if defined(DEBUG)
   // Check that first entry is for Smi/Smi.
   Label error, ok;
   const intptr_t imm_smi_cid = reinterpret_cast<intptr_t>(Smi::New(kSmiCid));
-  __ ldr(R1, Address(R6, 0));
+  __ ldr(R1, Address(R8, 0));
   __ CompareImmediate(R1, imm_smi_cid);
   __ b(&error, NE);
-  __ ldr(R1, Address(R6, kWordSize));
+  __ ldr(R1, Address(R8, kWordSize));
   __ CompareImmediate(R1, imm_smi_cid);
   __ b(&ok, EQ);
   __ Bind(&error);
@@ -1295,10 +1304,10 @@
   if (FLAG_optimization_counter_threshold >= 0) {
     // Update counter.
     const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize;
-    __ LoadFromOffset(kWord, R1, R6, count_offset);
+    __ LoadFromOffset(kWord, R1, R8, count_offset);
     __ adds(R1, R1, Operand(Smi::RawValue(1)));
     __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue), VS);  // Overflow.
-    __ StoreIntoSmiField(Address(R6, count_offset), R1);
+    __ StoreIntoSmiField(Address(R8, count_offset), R1);
   }
   __ Ret();
 }
@@ -1306,7 +1315,7 @@
 
 // Generate inline cache check for 'num_args'.
 //  LR: return address.
-//  R5: inline cache data object.
+//  R9: inline cache data object.
 // Control flow:
 // - If receiver is null -> jump to IC miss.
 // - If receiver is Smi -> load Smi class.
@@ -1327,10 +1336,10 @@
   { Label ok;
     // Check that the IC data array has NumArgsTested() == num_args.
     // 'NumArgsTested' is stored in the least significant bits of 'state_bits'.
-    __ ldr(R6, FieldAddress(R5, ICData::state_bits_offset()));
+    __ ldr(R8, FieldAddress(R9, ICData::state_bits_offset()));
     ASSERT(ICData::NumArgsTestedShift() == 0);  // No shift needed.
-    __ and_(R6, R6, Operand(ICData::NumArgsTestedMask()));
-    __ CompareImmediate(R6, num_args);
+    __ and_(R8, R8, Operand(ICData::NumArgsTestedMask()));
+    __ CompareImmediate(R8, num_args);
     __ b(&ok, EQ);
     __ Stop("Incorrect stub for IC data");
     __ Bind(&ok);
@@ -1340,9 +1349,9 @@
   Label stepping, done_stepping;
   if (FLAG_support_debugger && !optimized) {
     __ Comment("Check single stepping");
-    __ LoadIsolate(R6);
-    __ ldrb(R6, Address(R6, Isolate::single_step_offset()));
-    __ CompareImmediate(R6, 0);
+    __ LoadIsolate(R8);
+    __ ldrb(R8, Address(R8, Isolate::single_step_offset()));
+    __ CompareImmediate(R8, 0);
     __ b(&stepping, NE);
     __ Bind(&done_stepping);
   }
@@ -1353,11 +1362,11 @@
     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);
+      __ UpdateRangeFeedback(R0, 0, R9, R1, R4, &not_smi_or_overflow);
     }
 
     __ ldr(R0, Address(SP, 0 * kWordSize));
-    __ UpdateRangeFeedback(R0, num_args - 1, R5, R1, R4, &not_smi_or_overflow);
+    __ UpdateRangeFeedback(R0, num_args - 1, R9, R1, R4, &not_smi_or_overflow);
   }
   if (kind != Token::kILLEGAL) {
     EmitFastSmiOp(assembler, kind, num_args, &not_smi_or_overflow);
@@ -1366,24 +1375,24 @@
 
   __ Comment("Extract ICData initial values and receiver cid");
   // Load arguments descriptor into R4.
-  __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset()));
+  __ ldr(R4, FieldAddress(R9, ICData::arguments_descriptor_offset()));
   // Loop that checks if there is an IC data match.
   Label loop, update, test, found;
-  // R5: IC data object (preserved).
-  __ ldr(R6, FieldAddress(R5, ICData::ic_data_offset()));
-  // R6: ic_data_array with check entries: classes and target functions.
-  __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag);
-  // R6: points directly to the first ic data array element.
+  // R9: IC data object (preserved).
+  __ ldr(R8, FieldAddress(R9, ICData::ic_data_offset()));
+  // R8: ic_data_array with check entries: classes and target functions.
+  __ AddImmediate(R8, R8, Array::data_offset() - kHeapObjectTag);
+  // R8: points directly to the first ic data array element.
 
   // Get the receiver's class ID (first read number of arguments from
   // arguments descriptor array and then access the receiver from the stack).
-  __ ldr(R7, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
-  __ sub(R7, R7, Operand(Smi::RawValue(1)));
-  __ ldr(R0, Address(SP, R7, LSL, 1));  // R7 (argument_count - 1) is smi.
+  __ ldr(NOTFP, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
+  __ sub(NOTFP, NOTFP, Operand(Smi::RawValue(1)));
+  __ ldr(R0, Address(SP, NOTFP, LSL, 1));  // NOTFP (argument_count - 1) is smi.
   __ LoadTaggedClassIdMayBeSmi(R0, R0);
-  // R7: argument_count - 1 (smi).
+  // NOTFP: argument_count - 1 (smi).
   // R0: receiver's class ID (smi).
-  __ ldr(R1, Address(R6, 0));  // First class id (smi) to check.
+  __ ldr(R1, Address(R8, 0));  // First class id (smi) to check.
   __ b(&test);
 
   __ Comment("ICData loop");
@@ -1391,11 +1400,11 @@
   for (int i = 0; i < num_args; i++) {
     if (i > 0) {
       // If not the first, load the next argument's class ID.
-      __ AddImmediate(R0, R7, Smi::RawValue(-i));
+      __ AddImmediate(R0, NOTFP, Smi::RawValue(-i));
       __ ldr(R0, Address(SP, R0, LSL, 1));
       __ LoadTaggedClassIdMayBeSmi(R0, R0);
       // R0: next argument class ID (smi).
-      __ LoadFromOffset(kWord, R1, R6, i * kWordSize);
+      __ LoadFromOffset(kWord, R1, R8, i * kWordSize);
       // R1: next class ID to check (smi).
     }
     __ cmp(R0, Operand(R1));  // Class id match?
@@ -1409,13 +1418,13 @@
   __ Bind(&update);
   // Reload receiver class ID.  It has not been destroyed when num_args == 1.
   if (num_args > 1) {
-    __ ldr(R0, Address(SP, R7, LSL, 1));
+    __ ldr(R0, Address(SP, NOTFP, LSL, 1));
     __ LoadTaggedClassIdMayBeSmi(R0, R0);
   }
 
   const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize;
-  __ AddImmediate(R6, entry_size);  // Next entry.
-  __ ldr(R1, Address(R6, 0));  // Next class ID.
+  __ AddImmediate(R8, entry_size);  // Next entry.
+  __ ldr(R1, Address(R8, 0));  // Next class ID.
 
   __ Bind(&test);
   __ CompareImmediate(R1, Smi::RawValue(kIllegalCid));  // Done?
@@ -1423,29 +1432,29 @@
 
   __ Comment("IC miss");
   // Compute address of arguments.
-  // R7: argument_count - 1 (smi).
-  __ add(R7, SP, Operand(R7, LSL, 1));  // R7 is Smi.
-  // R7: address of receiver.
+  // NOTFP: argument_count - 1 (smi).
+  __ add(NOTFP, SP, Operand(NOTFP, LSL, 1));  // NOTFP is Smi.
+  // NOTFP: address of receiver.
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
   __ EnterStubFrame();
   __ LoadObject(R0, Object::null_object());
   // Preserve IC data object and arguments descriptor array and
   // setup space on stack for result (target code object).
-  __ PushList((1 << R0) | (1 << R4) | (1 << R5));
+  __ PushList((1 << R0) | (1 << R4) | (1 << R9));
   // Push call arguments.
   for (intptr_t i = 0; i < num_args; i++) {
-    __ LoadFromOffset(kWord, IP, R7, -i * kWordSize);
+    __ LoadFromOffset(kWord, IP, NOTFP, -i * kWordSize);
     __ Push(IP);
   }
   // Pass IC data object.
-  __ Push(R5);
+  __ Push(R9);
   __ CallRuntime(handle_ic_miss, num_args + 1);
   // Remove the call arguments pushed earlier, including the IC data object.
   __ Drop(num_args + 1);
   // Pop returned function object into R0.
   // Restore arguments descriptor array and IC data array.
-  __ PopList((1 << R0) | (1 << R4) | (1 << R5));
+  __ PopList((1 << R0) | (1 << R4) | (1 << R9));
   if (range_collection_mode == kCollectRanges) {
     __ RestoreCodePointer();
   }
@@ -1458,17 +1467,17 @@
   }
 
   __ Bind(&found);
-  // R6: pointer to an IC data check group.
+  // R8: pointer to an IC data check group.
   const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize;
   const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize;
-  __ LoadFromOffset(kWord, R0, R6, target_offset);
+  __ LoadFromOffset(kWord, R0, R8, target_offset);
 
   if (FLAG_optimization_counter_threshold >= 0) {
     __ Comment("Update caller's counter");
-    __ LoadFromOffset(kWord, R1, R6, count_offset);
+    __ LoadFromOffset(kWord, R1, R8, count_offset);
     __ adds(R1, R1, Operand(Smi::RawValue(1)));
     __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue), VS);  // Overflow.
-    __ StoreIntoSmiField(Address(R6, count_offset), R1);
+    __ StoreIntoSmiField(Address(R8, count_offset), R1);
   }
 
   __ Comment("Call target");
@@ -1482,16 +1491,16 @@
     }
     __ EnterStubFrame();
     if (num_args == 2) {
-      __ PushList((1 << R1) | (1 << R3) | (1 << R5));
+      __ PushList((1 << R1) | (1 << R3) | (1 << R9));
     } else {
-      __ PushList((1 << R1) | (1 << R5));
+      __ PushList((1 << R1) | (1 << R9));
     }
     __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
     __ blx(R2);
 
     Label done;
-    __ ldr(R5, Address(FP, kFirstLocalSlotFromFp * kWordSize));
-    __ UpdateRangeFeedback(R0, 2, R5, R1, R4, &done);
+    __ ldr(R9, Address(FP, kFirstLocalSlotFromFp * kWordSize));
+    __ UpdateRangeFeedback(R0, 2, R9, R1, R4, &done);
     __ Bind(&done);
     __ RestoreCodePointer();
     __ LeaveStubFrame();
@@ -1504,9 +1513,9 @@
   if (FLAG_support_debugger && !optimized) {
     __ Bind(&stepping);
     __ EnterStubFrame();
-    __ Push(R5);  // Preserve IC data.
+    __ Push(R9);  // Preserve IC data.
     __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
-    __ Pop(R5);
+    __ Pop(R9);
     __ RestoreCodePointer();
     __ LeaveStubFrame();
     __ b(&done_stepping);
@@ -1517,7 +1526,7 @@
 // Use inline cache data array to invoke the target or continue in inline
 // cache miss handler. Stub for 1-argument check (receiver class).
 //  LR: return address.
-//  R5: inline cache data object.
+//  R9: inline cache data object.
 // Inline cache data object structure:
 // 0: function-name
 // 1: N, number of arguments checked.
@@ -1525,7 +1534,7 @@
 //   - N classes.
 //   - 1 target function.
 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateUsageCounterIncrement(assembler, R8);
   GenerateNArgsCheckInlineCacheStub(assembler,
       1,
       kInlineCacheMissHandlerOneArgRuntimeEntry,
@@ -1535,7 +1544,7 @@
 
 
 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateUsageCounterIncrement(assembler, R8);
   GenerateNArgsCheckInlineCacheStub(assembler,
       2,
       kInlineCacheMissHandlerTwoArgsRuntimeEntry,
@@ -1545,7 +1554,7 @@
 
 
 void StubCode::GenerateSmiAddInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateUsageCounterIncrement(assembler, R8);
   GenerateNArgsCheckInlineCacheStub(assembler,
       2,
       kInlineCacheMissHandlerTwoArgsRuntimeEntry,
@@ -1555,7 +1564,7 @@
 
 
 void StubCode::GenerateSmiSubInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateUsageCounterIncrement(assembler, R8);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
       kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB,
       kCollectRanges);
@@ -1563,7 +1572,7 @@
 
 
 void StubCode::GenerateSmiEqualInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateUsageCounterIncrement(assembler, R8);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
       kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ,
       kIgnoreRanges);
@@ -1572,7 +1581,7 @@
 
 void StubCode::GenerateUnaryRangeCollectingInlineCacheStub(
     Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateUsageCounterIncrement(assembler, R8);
   GenerateNArgsCheckInlineCacheStub(assembler, 1,
       kInlineCacheMissHandlerOneArgRuntimeEntry,
       Token::kILLEGAL,
@@ -1582,7 +1591,7 @@
 
 void StubCode::GenerateBinaryRangeCollectingInlineCacheStub(
     Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateUsageCounterIncrement(assembler, R8);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
       kInlineCacheMissHandlerTwoArgsRuntimeEntry,
       Token::kILLEGAL,
@@ -1610,17 +1619,17 @@
 
 // Intermediary stub between a static call and its target. ICData contains
 // the target function and the call count.
-// R5: ICData
+// R9: ICData
 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateUsageCounterIncrement(assembler, R8);
 #if defined(DEBUG)
   { Label ok;
     // Check that the IC data array has NumArgsTested() == 0.
     // 'NumArgsTested' is stored in the least significant bits of 'state_bits'.
-    __ ldr(R6, FieldAddress(R5, ICData::state_bits_offset()));
+    __ ldr(R8, FieldAddress(R9, ICData::state_bits_offset()));
     ASSERT(ICData::NumArgsTestedShift() == 0);  // No shift needed.
-    __ and_(R6, R6, Operand(ICData::NumArgsTestedMask()));
-    __ CompareImmediate(R6, 0);
+    __ and_(R8, R8, Operand(ICData::NumArgsTestedMask()));
+    __ CompareImmediate(R8, 0);
     __ b(&ok, EQ);
     __ Stop("Incorrect IC data for unoptimized static call");
     __ Bind(&ok);
@@ -1630,34 +1639,34 @@
   // Check single stepping.
   Label stepping, done_stepping;
   if (FLAG_support_debugger) {
-    __ LoadIsolate(R6);
-    __ ldrb(R6, Address(R6, Isolate::single_step_offset()));
-    __ CompareImmediate(R6, 0);
+    __ LoadIsolate(R8);
+    __ ldrb(R8, Address(R8, Isolate::single_step_offset()));
+    __ CompareImmediate(R8, 0);
     __ b(&stepping, NE);
     __ Bind(&done_stepping);
   }
 
-  // R5: IC data object (preserved).
-  __ ldr(R6, FieldAddress(R5, ICData::ic_data_offset()));
-  // R6: ic_data_array with entries: target functions and count.
-  __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag);
-  // R6: points directly to the first ic data array element.
+  // R9: IC data object (preserved).
+  __ ldr(R8, FieldAddress(R9, ICData::ic_data_offset()));
+  // R8: ic_data_array with entries: target functions and count.
+  __ AddImmediate(R8, R8, Array::data_offset() - kHeapObjectTag);
+  // R8: points directly to the first ic data array element.
   const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize;
   const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize;
 
   if (FLAG_optimization_counter_threshold >= 0) {
     // Increment count for this call.
-    __ LoadFromOffset(kWord, R1, R6, count_offset);
+    __ LoadFromOffset(kWord, R1, R8, count_offset);
     __ adds(R1, R1, Operand(Smi::RawValue(1)));
     __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue), VS);  // Overflow.
-    __ StoreIntoSmiField(Address(R6, count_offset), R1);
+    __ StoreIntoSmiField(Address(R8, count_offset), R1);
   }
 
   // Load arguments descriptor into R4.
-  __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset()));
+  __ ldr(R4, FieldAddress(R9, ICData::arguments_descriptor_offset()));
 
   // Get function and call it, if possible.
-  __ LoadFromOffset(kWord, R0, R6, target_offset);
+  __ LoadFromOffset(kWord, R0, R8, target_offset);
   __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
   __ ldr(R2, FieldAddress(R0, Function::entry_point_offset()));
   __ bx(R2);
@@ -1665,9 +1674,9 @@
   if (FLAG_support_debugger) {
     __ Bind(&stepping);
     __ EnterStubFrame();
-    __ Push(R5);  // Preserve IC data.
+    __ Push(R9);  // Preserve IC data.
     __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
-    __ Pop(R5);
+    __ Pop(R9);
     __ RestoreCodePointer();
     __ LeaveStubFrame();
     __ b(&done_stepping);
@@ -1676,7 +1685,7 @@
 
 
 void StubCode::GenerateOneArgUnoptimizedStaticCallStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateUsageCounterIncrement(assembler, R8);
   GenerateNArgsCheckInlineCacheStub(
       assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL,
       kIgnoreRanges);
@@ -1684,7 +1693,7 @@
 
 
 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateUsageCounterIncrement(assembler, R8);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
       kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL,
       kIgnoreRanges);
@@ -1692,17 +1701,17 @@
 
 
 // Stub for compiling a function and jumping to the compiled code.
-// R5: IC-Data (for methods).
+// R9: IC-Data (for methods).
 // R4: Arguments descriptor.
 // R0: Function.
 void StubCode::GenerateLazyCompileStub(Assembler* assembler) {
   // Preserve arg desc. and IC data object.
   __ EnterStubFrame();
-  __ PushList((1 << R4) | (1 << R5));
+  __ PushList((1 << R4) | (1 << R9));
   __ Push(R0);  // Pass function.
   __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
   __ Pop(R0);  // Restore argument.
-  __ PopList((1 << R4) | (1 << R5));  // Restore arg desc. and IC data.
+  __ PopList((1 << R4) | (1 << R9));  // Restore arg desc. and IC data.
   __ LeaveStubFrame();
 
   __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
@@ -1711,14 +1720,14 @@
 }
 
 
-// R5: Contains an ICData.
+// R9: Contains an ICData.
 void StubCode::GenerateICCallBreakpointStub(Assembler* assembler) {
   __ EnterStubFrame();
   __ LoadObject(R0, Object::null_object());
   // Preserve arguments descriptor and make room for result.
-  __ PushList((1 << R0) | (1 << R5));
+  __ PushList((1 << R0) | (1 << R9));
   __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
-  __ PopList((1 << R0) | (1 << R5));
+  __ PopList((1 << R0) | (1 << R9));
   __ LeaveStubFrame();
   __ mov(CODE_REG, Operand(R0));
   __ ldr(R0, FieldAddress(CODE_REG, Code::entry_point_offset()));
@@ -1773,12 +1782,12 @@
     // Compute instance type arguments into R4.
     Label has_no_type_arguments;
     __ LoadObject(R4, Object::null_object());
-    __ ldr(R5, FieldAddress(R3,
+    __ ldr(R9, FieldAddress(R3,
         Class::type_arguments_field_offset_in_words_offset()));
-    __ CompareImmediate(R5, Class::kNoTypeArguments);
+    __ CompareImmediate(R9, Class::kNoTypeArguments);
     __ b(&has_no_type_arguments, EQ);
-    __ add(R5, R0, Operand(R5, LSL, 2));
-    __ ldr(R4, FieldAddress(R5, 0));
+    __ add(R9, R0, Operand(R9, LSL, 2));
+    __ ldr(R4, FieldAddress(R9, 0));
     __ Bind(&has_no_type_arguments);
   }
   __ LoadClassId(R3, R0);
@@ -1796,24 +1805,24 @@
   // R4: instance type arguments.
   __ SmiTag(R3);
   __ Bind(&loop);
-  __ ldr(R5, Address(R2, kWordSize * SubtypeTestCache::kInstanceClassId));
-  __ CompareObject(R5, Object::null_object());
+  __ ldr(R9, Address(R2, kWordSize * SubtypeTestCache::kInstanceClassId));
+  __ CompareObject(R9, Object::null_object());
   __ b(&not_found, EQ);
-  __ cmp(R5, Operand(R3));
+  __ cmp(R9, Operand(R3));
   if (n == 1) {
     __ b(&found, EQ);
   } else {
     __ b(&next_iteration, NE);
-    __ ldr(R5,
+    __ ldr(R9,
            Address(R2, kWordSize * SubtypeTestCache::kInstanceTypeArguments));
-    __ cmp(R5, Operand(R4));
+    __ cmp(R9, Operand(R4));
     if (n == 2) {
       __ b(&found, EQ);
     } else {
       __ b(&next_iteration, NE);
-      __ ldr(R5, Address(R2, kWordSize *
+      __ ldr(R9, Address(R2, kWordSize *
                              SubtypeTestCache::kInstantiatorTypeArguments));
-      __ cmp(R5, Operand(R1));
+      __ cmp(R9, Operand(R1));
       __ b(&found, EQ);
     }
   }
@@ -1901,14 +1910,14 @@
 
 
 // Calls to the runtime to optimize the given function.
-// R6: function to be reoptimized.
+// R8: function to be reoptimized.
 // R4: argument descriptor (preserved).
 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) {
   __ EnterStubFrame();
   __ Push(R4);
   __ LoadObject(IP, Object::null_object());
   __ Push(IP);  // Setup space on stack for return value.
-  __ Push(R6);
+  __ Push(R8);
   __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
   __ Pop(R0);  // Discard argument.
   __ Pop(R0);  // Get Code object
@@ -2041,18 +2050,18 @@
 }
 
 
-void StubCode::EmitMegamorphicLookup(
-    Assembler* assembler, Register receiver, Register cache, Register target) {
-  ASSERT((cache != R0) && (cache != R2));
-  __ LoadTaggedClassIdMayBeSmi(R0, receiver);
-  // R0: class ID of the receiver (smi).
-  __ ldr(R2, FieldAddress(cache, MegamorphicCache::buckets_offset()));
-  __ ldr(R1, FieldAddress(R1, MegamorphicCache::mask_offset()));
+void StubCode::EmitMegamorphicLookup(Assembler* assembler) {
+  __ LoadTaggedClassIdMayBeSmi(R0, R0);
+  // R0: receiver cid as Smi.
+  __ ldr(R4, FieldAddress(R9, MegamorphicCache::arguments_descriptor_offset()));
+  __ ldr(R2, FieldAddress(R9, MegamorphicCache::buckets_offset()));
+  __ ldr(R1, FieldAddress(R9, MegamorphicCache::mask_offset()));
   // R2: cache buckets array.
   // R1: mask.
   __ mov(R3, Operand(R0));
+  // R3: probe.
 
-  Label loop, update, call_target_function;
+  Label loop, update, load_target_function;
   __ b(&loop);
 
   __ Bind(&update);
@@ -2062,33 +2071,77 @@
   const intptr_t base = Array::data_offset();
   // R3 is smi tagged, but table entries are two words, so LSL 2.
   __ add(IP, R2, Operand(R3, LSL, 2));
-  __ ldr(R4, FieldAddress(IP, base));
+  __ ldr(R6, FieldAddress(IP, base));
 
   ASSERT(kIllegalCid == 0);
-  __ tst(R4, Operand(R4));
-  __ b(&call_target_function, EQ);
-  __ cmp(R4, Operand(R0));
+  __ tst(R6, Operand(R6));
+  __ b(&load_target_function, EQ);
+  __ cmp(R6, Operand(R0));
   __ b(&update, NE);
 
-  __ Bind(&call_target_function);
+  __ Bind(&load_target_function);
   // Call the target found in the cache.  For a class id match, this is a
   // proper target for the given name and arguments descriptor.  If the
   // illegal class id was found, the target is a cache miss handler that can
   // be invoked as a normal Dart function.
   __ add(IP, R2, Operand(R3, LSL, 2));
   __ ldr(R0, FieldAddress(IP, base + kWordSize));
+  __ ldr(R1, FieldAddress(R0, Function::entry_point_offset()));
   __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
-  __ ldr(target, FieldAddress(R0, Function::entry_point_offset()));
 }
 
 
 // Called from megamorphic calls.
-//  R0: receiver.
-//  R1: lookup cache.
+//  R0: receiver
+//  R9: MegamorphicCache (preserved)
 // Result:
-//  R1: entry point.
+//  R1: target entry point
+//  CODE_REG: target Code
+//  R4: arguments descriptor
 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
-  EmitMegamorphicLookup(assembler, R0, R1, R1);
+  EmitMegamorphicLookup(assembler);
+  __ Ret();
+}
+
+
+// Called from switchable IC calls.
+//  R0: receiver
+//  R9: ICData (preserved)
+// Result:
+//  R1: target entry point
+//  CODE_REG: target Code object
+//  R4: arguments descriptor
+void StubCode::GenerateICLookupStub(Assembler* assembler) {
+  Label loop, found, miss;
+  __ ldr(R4, FieldAddress(R9, ICData::arguments_descriptor_offset()));
+  __ ldr(R8, FieldAddress(R9, ICData::ic_data_offset()));
+  __ AddImmediate(R8, R8, Array::data_offset() - kHeapObjectTag);
+  // R8: first IC entry
+  __ LoadTaggedClassIdMayBeSmi(R1, R0);
+  // R1: receiver cid as Smi
+
+  __ Bind(&loop);
+  __ ldr(R2, Address(R8, 0));
+  __ cmp(R1, Operand(R2));
+  __ b(&found, EQ);
+  __ CompareImmediate(R2, Smi::RawValue(kIllegalCid));
+  __ b(&miss, EQ);
+
+  const intptr_t entry_length = ICData::TestEntryLengthFor(1) * kWordSize;
+  __ AddImmediate(R8, entry_length);  // Next entry.
+  __ b(&loop);
+
+  __ Bind(&found);
+  const intptr_t target_offset = ICData::TargetIndexFor(1) * kWordSize;
+  __ LoadFromOffset(kWord, R0, R8, target_offset);
+  __ ldr(R1, FieldAddress(R0, Function::entry_point_offset()));
+  __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
+  __ Ret();
+
+  __ Bind(&miss);
+  __ LoadIsolate(R2);
+  __ ldr(CODE_REG, Address(R2, Isolate::ic_miss_code_offset()));
+  __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset()));
   __ Ret();
 }
 
diff --git a/runtime/vm/stub_code_arm64.cc b/runtime/vm/stub_code_arm64.cc
index facc08c..8c197ae 100644
--- a/runtime/vm/stub_code_arm64.cc
+++ b/runtime/vm/stub_code_arm64.cc
@@ -567,9 +567,9 @@
   __ add(TMP, FP, Operand(R2, LSL, 2));  // R2 is Smi.
   __ LoadFromOffset(R6, TMP, kParamEndSlotFromFp * kWordSize);
   __ PushObject(Object::null_object());
-  __ Push(R6);
-  __ Push(R5);
-  __ Push(R4);
+  __ Push(R6);  // Receiver.
+  __ Push(R5);  // ICData/MegamorphicCache.
+  __ Push(R4);  // Arguments descriptor.
   // R2: Smi-tagged arguments array length.
   PushArgumentsArray(assembler);
   const intptr_t kNumArgs = 4;
@@ -829,7 +829,7 @@
   __ LoadFromOffset(R6, THR, Thread::top_exit_frame_info_offset());
   __ StoreToOffset(ZR, THR, Thread::top_exit_frame_info_offset());
   // kExitLinkSlotFromEntryFp must be kept in sync with the code below.
-  ASSERT(kExitLinkSlotFromEntryFp == -22);
+  ASSERT(kExitLinkSlotFromEntryFp == -21);
   __ Push(R6);
 
   // Load arguments descriptor array into R4, which is passed to Dart code.
@@ -2098,18 +2098,18 @@
 }
 
 
-void StubCode::EmitMegamorphicLookup(
-    Assembler* assembler, Register receiver, Register cache, Register target) {
-  ASSERT((cache != R0) && (cache != R2));
-  __ LoadTaggedClassIdMayBeSmi(R0, receiver);
+void StubCode::EmitMegamorphicLookup(Assembler* assembler) {
+  __ LoadTaggedClassIdMayBeSmi(R0, R0);
   // R0: class ID of the receiver (smi).
-  __ LoadFieldFromOffset(R2, cache, MegamorphicCache::buckets_offset());
-  __ LoadFieldFromOffset(R1, cache, MegamorphicCache::mask_offset());
+  __ ldr(R4, FieldAddress(R5, MegamorphicCache::arguments_descriptor_offset()));
+  __ ldr(R2, FieldAddress(R5, MegamorphicCache::buckets_offset()));
+  __ ldr(R1, FieldAddress(R5, MegamorphicCache::mask_offset()));
   // R2: cache buckets array.
   // R1: mask.
   __ mov(R3, R0);
+  // R3: probe.
 
-  Label loop, update, call_target_function;
+  Label loop, update, load_target_function;
   __ b(&loop);
 
   __ Bind(&update);
@@ -2119,33 +2119,77 @@
   const intptr_t base = Array::data_offset();
   // R3 is smi tagged, but table entries are 16 bytes, so LSL 3.
   __ add(TMP, R2, Operand(R3, LSL, 3));
-  __ LoadFieldFromOffset(R4, TMP, base);
+  __ ldr(R6, FieldAddress(TMP, base));
 
   ASSERT(kIllegalCid == 0);
-  __ tst(R4, Operand(R4));
-  __ b(&call_target_function, EQ);
-  __ CompareRegisters(R4, R0);
+  __ tst(R6, Operand(R6));
+  __ b(&load_target_function, EQ);
+  __ CompareRegisters(R6, R0);
   __ b(&update, NE);
 
-  __ Bind(&call_target_function);
+  __ Bind(&load_target_function);
   // Call the target found in the cache.  For a class id match, this is a
   // proper target for the given name and arguments descriptor.  If the
   // illegal class id was found, the target is a cache miss handler that can
   // be invoked as a normal Dart function.
   __ add(TMP, R2, Operand(R3, LSL, 3));
-  __ LoadFieldFromOffset(R0, TMP, base + kWordSize);
-  __ LoadFieldFromOffset(CODE_REG, R0, Function::code_offset());
-  __ LoadFieldFromOffset(R1, R0, Function::entry_point_offset());
+  __ ldr(R0, FieldAddress(TMP, base + kWordSize));
+  __ ldr(R1, FieldAddress(R0, Function::entry_point_offset()));
+  __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
 }
 
 
 // Called from megamorphic calls.
-//  R0: receiver.
-//  R1: lookup cache.
+//  R0: receiver
+//  R5: MegamorphicCache (preserved)
 // Result:
-//  R1: entry point.
+//  R1: target entry point
+//  CODE_REG: target Code
+//  R4: arguments descriptor
 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
-  EmitMegamorphicLookup(assembler, R0, R1, R1);
+  EmitMegamorphicLookup(assembler);
+  __ ret();
+}
+
+
+// Called from switchable IC calls.
+//  R0: receiver
+//  R5: ICData (preserved)
+// Result:
+//  R1: target entry point
+//  CODE_REG: target Code object
+//  R4: arguments descriptor
+void StubCode::GenerateICLookupStub(Assembler* assembler) {
+  Label loop, found, miss;
+  __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset()));
+  __ ldr(R8, FieldAddress(R5, ICData::ic_data_offset()));
+  __ AddImmediate(R8, R8, Array::data_offset() - kHeapObjectTag);
+  // R8: first IC entry
+  __ LoadTaggedClassIdMayBeSmi(R1, R0);
+  // R1: receiver cid as Smi
+
+  __ Bind(&loop);
+  __ ldr(R2, Address(R8, 0));
+  __ cmp(R1, Operand(R2));
+  __ b(&found, EQ);
+  __ CompareImmediate(R2, Smi::RawValue(kIllegalCid));
+  __ b(&miss, EQ);
+
+  const intptr_t entry_length = ICData::TestEntryLengthFor(1) * kWordSize;
+  __ AddImmediate(R8, R8, entry_length);  // Next entry.
+  __ b(&loop);
+
+  __ Bind(&found);
+  const intptr_t target_offset = ICData::TargetIndexFor(1) * kWordSize;
+  __ ldr(R0, Address(R8, target_offset));
+  __ ldr(R1, FieldAddress(R0, Function::entry_point_offset()));
+  __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
+  __ ret();
+
+  __ Bind(&miss);
+  __ LoadIsolate(R2);
+  __ ldr(CODE_REG, Address(R2, Isolate::ic_miss_code_offset()));
+  __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset()));
   __ ret();
 }
 
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index 8ca11ef..b6302d3 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -481,7 +481,7 @@
       EBP, EDI, TIMES_HALF_WORD_SIZE, kParamEndSlotFromFp * kWordSize));
   __ pushl(raw_null);  // Setup space on stack for result.
   __ pushl(EAX);  // Receiver.
-  __ pushl(ECX);
+  __ pushl(ECX);  // ICData/MegamorphicCache.
   __ pushl(EDX);  // Arguments descriptor array.
   __ movl(EDX, EDI);
   // EDX: Smi-tagged arguments array length.
@@ -2022,19 +2022,18 @@
 }
 
 
-void StubCode::EmitMegamorphicLookup(
-    Assembler* assembler, Register receiver, Register cache, Register target) {
-  ASSERT((cache != EAX) && (cache != EDI));
-  __ LoadTaggedClassIdMayBeSmi(EAX, receiver);
-
+void StubCode::EmitMegamorphicLookup(Assembler* assembler) {
+  __ LoadTaggedClassIdMayBeSmi(EAX, EBX);
   // EAX: class ID of the receiver (smi).
-  __ movl(EDI, FieldAddress(cache, MegamorphicCache::buckets_offset()));
-  __ movl(EBX, FieldAddress(cache, MegamorphicCache::mask_offset()));
+  __ movl(EDI, FieldAddress(ECX, MegamorphicCache::buckets_offset()));
+  __ movl(EBX, FieldAddress(ECX, MegamorphicCache::mask_offset()));
   // EDI: cache buckets array.
   // EBX: mask.
+  __ pushl(ECX);  // Spill MegamorphicCache.
   __ movl(ECX, EAX);
+  // ECX: probe.
 
-  Label loop, update, call_target_function;
+  Label loop, update, load_target_function;
   __ jmp(&loop);
 
   __ Bind(&update);
@@ -2047,31 +2046,45 @@
 
   ASSERT(kIllegalCid == 0);
   __ testl(EDX, EDX);
-  __ j(ZERO, &call_target_function, Assembler::kNearJump);
+  __ j(ZERO, &load_target_function, Assembler::kNearJump);
   __ cmpl(EDX, EAX);
   __ j(NOT_EQUAL, &update, Assembler::kNearJump);
 
-  __ Bind(&call_target_function);
+  __ Bind(&load_target_function);
   // Call the target found in the cache.  For a class id match, this is a
   // proper target for the given name and arguments descriptor.  If the
   // illegal class id was found, the target is a cache miss handler that can
   // be invoked as a normal Dart function.
   __ movl(EAX, FieldAddress(EDI, ECX, TIMES_4, base + kWordSize));
-  __ movl(target, FieldAddress(EAX, Function::entry_point_offset()));
+  __ popl(ECX);  // Restore MegamorphicCache.
+  __ movl(EDX,
+          FieldAddress(ECX, MegamorphicCache::arguments_descriptor_offset()));
+  __ movl(EBX, FieldAddress(EAX, Function::entry_point_offset()));
 }
 
 
 // Called from megamorphic calls.
-//  ECX: receiver.
-//  EBX: lookup cache.
+//  EBX: receiver
+//  ECX: MegamorphicCache (preserved)
 // Result:
-//  EBX: entry point.
+//  EBX: target entry point
+//  EDX: argument descriptor
 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
-  EmitMegamorphicLookup(assembler, ECX, EBX, EBX);
+  EmitMegamorphicLookup(assembler);
   __ ret();
 }
 
 
+// Called from switchable IC calls.
+//  EBX: receiver
+//  ECX: ICData (preserved)
+// Result:
+//  EBX: target entry point
+//  EDX: arguments descriptor
+void StubCode::GenerateICLookupStub(Assembler* assembler) {
+  __ int3();
+}
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_IA32
diff --git a/runtime/vm/stub_code_mips.cc b/runtime/vm/stub_code_mips.cc
index 30a7cdf..58af418 100644
--- a/runtime/vm/stub_code_mips.cc
+++ b/runtime/vm/stub_code_mips.cc
@@ -563,7 +563,7 @@
 
   // Push space for the return value.
   // Push the receiver.
-  // Push IC data object.
+  // Push ICData/MegamorphicCache object.
   // Push arguments descriptor array.
   // Push original arguments array.
   __ addiu(SP, SP, Immediate(-4 * kWordSize));
@@ -2211,16 +2211,16 @@
 }
 
 
-void StubCode::EmitMegamorphicLookup(
-    Assembler* assembler, Register receiver, Register cache, Register target) {
-  ASSERT((cache != T0) && (cache != T2));
-  __ LoadTaggedClassIdMayBeSmi(T0, receiver);
+void StubCode::EmitMegamorphicLookup(Assembler* assembler) {
+  __ LoadTaggedClassIdMayBeSmi(T0, T0);
   // T0: class ID of the receiver (smi).
-  __ lw(T2, FieldAddress(cache, MegamorphicCache::buckets_offset()));
-  __ lw(T1, FieldAddress(cache, MegamorphicCache::mask_offset()));
+  __ lw(S4, FieldAddress(S5, MegamorphicCache::arguments_descriptor_offset()));
+  __ lw(T2, FieldAddress(S5, MegamorphicCache::buckets_offset()));
+  __ lw(T1, FieldAddress(S5, MegamorphicCache::mask_offset()));
   // T2: cache buckets array.
   // T1: mask.
   __ mov(T3, T0);
+  // T3: probe.
 
   Label loop, update, call_target_function;
   __ b(&loop);
@@ -2248,18 +2248,61 @@
   __ addu(T1, T2, T1);
   __ lw(T0, FieldAddress(T1, base + kWordSize));
 
+  __ lw(T1, FieldAddress(T0, Function::entry_point_offset()));
   __ lw(CODE_REG, FieldAddress(T0, Function::code_offset()));
-  __ lw(target, FieldAddress(T0, Function::entry_point_offset()));
 }
 
 
 // Called from megamorphic calls.
-//  T0: receiver.
-//  T1: lookup cache.
+//  T0: receiver
+//  S5: MegamorphicCache (preserved)
 // Result:
-//  T1: entry point.
+//  T1: target entry point
+//  CODE_REG: target Code
+//  S4: arguments descriptor
 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
-  EmitMegamorphicLookup(assembler, T0, T1, T1);
+  EmitMegamorphicLookup(assembler);
+  __ Ret();
+}
+
+
+// Called from switchable IC calls.
+//  T0: receiver
+//  S5: ICData (preserved)
+// Result:
+//  T1: target entry point
+//  CODE_REG: target Code object
+//  S4: arguments descriptor
+void StubCode::GenerateICLookupStub(Assembler* assembler) {
+  Label loop, found, miss;
+  __ lw(T6, FieldAddress(S5, ICData::ic_data_offset()));
+  __ lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset()));
+  __ AddImmediate(T6, T6, Array::data_offset() - kHeapObjectTag);
+  // T6: first IC entry.
+  __ LoadTaggedClassIdMayBeSmi(T1, T0);
+  // T1: receiver cid as Smi
+
+  __ Bind(&loop);
+  __ lw(T2, Address(T6, 0));
+  __ beq(T1, T2, &found);
+  ASSERT(Smi::RawValue(kIllegalCid) == 0);
+  __ beq(T2, ZR, &miss);
+
+  const intptr_t entry_length = ICData::TestEntryLengthFor(1) * kWordSize;
+  __ AddImmediate(T6, entry_length);  // Next entry.
+  __ b(&loop);
+
+  __ Bind(&found);
+  const intptr_t target_offset = ICData::TargetIndexFor(1) * kWordSize;
+  __ lw(T0, Address(T6, target_offset));
+  __ lw(T1, FieldAddress(T0, Function::entry_point_offset()));
+  __ lw(CODE_REG, FieldAddress(T0, Function::code_offset()));
+  __ Ret();
+
+  __ Bind(&miss);
+  __ LoadIsolate(T2);
+  __ lw(CODE_REG, Address(T2, Isolate::ic_miss_code_offset()));
+  __ lw(T1, FieldAddress(CODE_REG, Code::entry_point_offset()));
   __ Ret();
 }
 
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index 44d5f96..39d8dc9 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -510,7 +510,7 @@
       RBP, RDI, TIMES_HALF_WORD_SIZE, kParamEndSlotFromFp * kWordSize));
   __ PushObject(Object::null_object());  // Setup space on stack for result.
   __ pushq(RAX);  // Receiver.
-  __ pushq(RBX);
+  __ pushq(RBX);  // ICData/MegamorphicCache.
   __ pushq(R10);  // Arguments descriptor array.
   __ movq(R10, RDI);
   // EDX: Smi-tagged arguments array length.
@@ -2088,52 +2088,99 @@
 }
 
 
-void StubCode::EmitMegamorphicLookup(
-    Assembler* assembler, Register receiver, Register cache, Register target) {
-  ASSERT((cache != RAX) && (cache != RDI));
-  __ LoadTaggedClassIdMayBeSmi(RAX, receiver);
+void StubCode::EmitMegamorphicLookup(Assembler* assembler) {
+  __ LoadTaggedClassIdMayBeSmi(RAX, RDI);
   // RAX: class ID of the receiver (smi).
-  __ movq(RDI, FieldAddress(cache, MegamorphicCache::buckets_offset()));
-  __ movq(RBX, FieldAddress(cache, MegamorphicCache::mask_offset()));
+  __ movq(R10,
+          FieldAddress(RBX, MegamorphicCache::arguments_descriptor_offset()));
+  __ movq(RDI, FieldAddress(RBX, MegamorphicCache::buckets_offset()));
+  __ movq(R9, FieldAddress(RBX, MegamorphicCache::mask_offset()));
   // RDI: cache buckets array.
   // RBX: mask.
   __ movq(RCX, RAX);
 
-  Label loop, update, call_target_function;
+  Label loop, update, load_target_function;
   __ jmp(&loop);
 
   __ Bind(&update);
   __ AddImmediate(RCX, Immediate(Smi::RawValue(1)));
   __ Bind(&loop);
-  __ andq(RCX, RBX);
+  __ andq(RCX, R9);
   const intptr_t base = Array::data_offset();
   // RCX is smi tagged, but table entries are two words, so TIMES_8.
   __ movq(RDX, FieldAddress(RDI, RCX, TIMES_8, base));
 
   ASSERT(kIllegalCid == 0);
   __ testq(RDX, RDX);
-  __ j(ZERO, &call_target_function, Assembler::kNearJump);
+  __ j(ZERO, &load_target_function, Assembler::kNearJump);
   __ cmpq(RDX, RAX);
   __ j(NOT_EQUAL, &update, Assembler::kNearJump);
 
-  __ Bind(&call_target_function);
+  __ Bind(&load_target_function);
   // Call the target found in the cache.  For a class id match, this is a
   // proper target for the given name and arguments descriptor.  If the
   // illegal class id was found, the target is a cache miss handler that can
   // be invoked as a normal Dart function.
   __ movq(RAX, FieldAddress(RDI, RCX, TIMES_8, base + kWordSize));
+  __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset()));
   __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset()));
-  __ movq(target, FieldAddress(RAX, Function::entry_point_offset()));
 }
 
 
 // Called from megamorphic calls.
-//  RDI: receiver.
-//  RBX: lookup cache.
+//  RDI: receiver
+//  RBX: MegamorphicCache (preserved)
 // Result:
-//  RCX: entry point.
+//  RCX: target entry point
+//  CODE_REG: target Code
+//  R10: arguments descriptor
 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
-  EmitMegamorphicLookup(assembler, RDI, RBX, RCX);
+  EmitMegamorphicLookup(assembler);
+  __ ret();
+}
+
+
+// Called from switchable IC calls.
+//  RDI: receiver
+//  RBX: ICData (preserved)
+// Result:
+//  RCX: target entry point
+//  CODE_REG: target Code object
+//  R10: arguments descriptor
+void StubCode::GenerateICLookupStub(Assembler* assembler) {
+  Label loop, found, miss;
+
+  __ movq(R13, FieldAddress(RBX, ICData::ic_data_offset()));
+  __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset()));
+  __ leaq(R13, FieldAddress(R13, Array::data_offset()));
+  // R13: first IC entry
+  __ LoadTaggedClassIdMayBeSmi(RAX, RDI);
+  // RAX: receiver cid as Smi
+
+  __ Bind(&loop);
+  __ movq(R9, Address(R13, 0));
+  __ cmpq(RAX, R9);
+  __ j(EQUAL, &found, Assembler::kNearJump);
+
+  ASSERT(Smi::RawValue(kIllegalCid) == 0);
+  __ testq(R9, R9);
+  __ j(ZERO, &miss, Assembler::kNearJump);
+
+  const intptr_t entry_length = ICData::TestEntryLengthFor(1) * kWordSize;
+  __ addq(R13, Immediate(entry_length));  // Next entry.
+  __ jmp(&loop);
+
+  __ Bind(&found);
+  const intptr_t target_offset = ICData::TargetIndexFor(1) * kWordSize;
+  __ movq(RAX, Address(R13, target_offset));
+  __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset()));
+  __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset()));
+  __ ret();
+
+  __ Bind(&miss);
+  __ LoadIsolate(RAX);
+  __ movq(CODE_REG, Address(RAX, Isolate::ic_miss_code_offset()));
+  __ movq(RCX, FieldAddress(CODE_REG, Code::entry_point_offset()));
   __ ret();
 }
 
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index 46da230..0d84937 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -101,6 +101,23 @@
 }
 
 
+bool Thread::IsThreadInList(ThreadId join_id) {
+  if (join_id == OSThread::kInvalidThreadJoinId) {
+    return false;
+  }
+  ThreadIterator it;
+  while (it.HasNext()) {
+    Thread* t = it.Next();
+    // An address test is not sufficient because the allocator may recycle
+    // the address for another Thread. Test against the thread's join id.
+    if (t->join_id() == join_id) {
+      return true;
+    }
+  }
+  return false;
+}
+
+
 static void DeleteThread(void* thread) {
   delete reinterpret_cast<Thread*>(thread);
 }
@@ -108,6 +125,24 @@
 
 void Thread::Shutdown() {
   if (thread_list_lock_ != NULL) {
+    // Delete the current thread.
+    Thread* thread = Current();
+    ASSERT(thread != NULL);
+    delete thread;
+    thread = NULL;
+    SetCurrent(NULL);
+
+    // Check that there are no more threads, then delete the lock.
+    {
+      MutexLocker ml(thread_list_lock_);
+      ASSERT(thread_list_head_ == NULL);
+    }
+
+    // Clean up TLS.
+    OSThread::DeleteThreadLocal(thread_key_);
+    thread_key_ = OSThread::kUnsetThreadLocalKey;
+
+    // Delete the thread list lock.
     delete thread_list_lock_;
     thread_list_lock_ = NULL;
   }
@@ -165,16 +200,6 @@
 }
 
 
-#if defined(TARGET_OS_WINDOWS)
-void Thread::CleanUp() {
-  Thread* current = Current();
-  if (current != NULL) {
-    SetCurrent(NULL);
-    delete current;
-  }
-}
-#endif
-
 #if defined(DEBUG)
 #define REUSABLE_HANDLE_SCOPE_INIT(object)                                     \
   reusable_##object##_handle_scope_active_(false),
@@ -188,20 +213,24 @@
 
 Thread::Thread(bool init_vm_constants)
     : id_(OSThread::GetCurrentThreadId()),
-      thread_interrupt_callback_(NULL),
-      thread_interrupt_data_(NULL),
+      join_id_(OSThread::GetCurrentThreadJoinId()),
+      trace_id_(OSThread::GetCurrentThreadTraceId()),
+      thread_interrupt_disabled_(1),  // Thread interrupts disabled by default.
       isolate_(NULL),
       heap_(NULL),
+      timeline_block_(NULL),
       store_buffer_block_(NULL),
       log_(new class Log()),
-      deopt_id_(0),
-      vm_tag_(0),
       REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_INITIALIZERS)
       REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_INIT)
       reusable_handles_(),
       cha_(NULL),
+      deopt_id_(0),
+      vm_tag_(0),
+      pending_functions_(GrowableObjectArray::null()),
       no_callback_scope_depth_(0),
-      thread_list_next_(NULL) {
+      thread_list_next_(NULL),
+      name_(NULL) {
   ClearState();
 
 #define DEFAULT_INIT(type_name, member_name, init_expr, default_init_value)    \
@@ -259,6 +288,20 @@
 }
 
 
+void Thread::ClearState() {
+  memset(&state_, 0, sizeof(state_));
+  pending_functions_ = GrowableObjectArray::null();
+}
+
+
+RawGrowableObjectArray* Thread::pending_functions() {
+  if (pending_functions_ == GrowableObjectArray::null()) {
+    pending_functions_ = GrowableObjectArray::New(Heap::kOld);
+  }
+  return pending_functions_;
+}
+
+
 void Thread::Schedule(Isolate* isolate, bool bypass_safepoint) {
   State st;
   if (isolate->thread_registry()->RestoreStateTo(this, &st, bypass_safepoint)) {
@@ -289,8 +332,7 @@
   ASSERT(isolate->heap() != NULL);
   thread->heap_ = isolate->heap();
   thread->Schedule(isolate);
-  // TODO(koda): Migrate profiler interface to use Thread.
-  Profiler::BeginExecution(isolate);
+  thread->EnableThreadInterrupts();
 }
 
 
@@ -301,10 +343,10 @@
 #if defined(DEBUG)
   ASSERT(!thread->IsAnyReusableHandleScopeActive());
 #endif  // DEBUG
+  thread->DisableThreadInterrupts();
   // Clear since GC will not visit the thread once it is unscheduled.
   thread->ClearReusableHandles();
   Isolate* isolate = thread->isolate();
-  Profiler::EndExecution(isolate);
   thread->Unschedule();
   // TODO(koda): Move store_buffer_block_ into State.
   thread->StoreBufferRelease();
@@ -331,17 +373,17 @@
       thread->isolate()->store_buffer()->PopEmptyBlock();
   ASSERT(isolate->heap() != NULL);
   thread->heap_ = isolate->heap();
-  ASSERT(thread->thread_interrupt_callback_ == NULL);
-  ASSERT(thread->thread_interrupt_data_ == NULL);
   // Do not update isolate->mutator_thread, but perform sanity check:
   // this thread should not be both the main mutator and helper.
-  ASSERT(!isolate->MutatorThreadIsCurrentThread());
+  ASSERT(!thread->IsMutatorThread());
   thread->Schedule(isolate, bypass_safepoint);
+  thread->EnableThreadInterrupts();
 }
 
 
 void Thread::ExitIsolateAsHelper(bool bypass_safepoint) {
   Thread* thread = Thread::Current();
+  thread->DisableThreadInterrupts();
   Isolate* isolate = thread->isolate();
   ASSERT(isolate != NULL);
   thread->Unschedule(bypass_safepoint);
@@ -349,7 +391,7 @@
   thread->StoreBufferRelease();
   thread->isolate_ = NULL;
   thread->heap_ = NULL;
-  ASSERT(!isolate->MutatorThreadIsCurrentThread());
+  ASSERT(!thread->IsMutatorThread());
 }
 
 
@@ -400,6 +442,23 @@
 }
 
 
+bool Thread::IsMutatorThread() const {
+  return ((isolate_ != NULL) && (isolate_->mutator_thread() == this));
+}
+
+
+bool Thread::IsExecutingDartCode() const {
+  return (top_exit_frame_info() == 0) &&
+         (vm_tag() == VMTag::kDartTagId);
+}
+
+
+bool Thread::HasExitedDartCode() const {
+  return (top_exit_frame_info() != 0) &&
+         (vm_tag() != VMTag::kDartTagId);
+}
+
+
 CHA* Thread::cha() const {
   ASSERT(isolate_ != NULL);
   return cha_;
@@ -438,32 +497,39 @@
 
   // Visit objects in thread specific handles area.
   reusable_handles_.VisitObjectPointers(visitor);
+
+  if (pending_functions_ != GrowableObjectArray::null()) {
+    visitor->VisitPointer(
+        reinterpret_cast<RawObject**>(&pending_functions_));
+  }
 }
 
 
-void Thread::SetThreadInterrupter(ThreadInterruptCallback callback,
-                                  void* data) {
+void Thread::DisableThreadInterrupts() {
   ASSERT(Thread::Current() == this);
-  thread_interrupt_callback_ = callback;
-  thread_interrupt_data_ = data;
+  AtomicOperations::FetchAndIncrement(&thread_interrupt_disabled_);
 }
 
 
-bool Thread::IsThreadInterrupterEnabled(ThreadInterruptCallback* callback,
-                                        void** data) const {
-#if defined(TARGET_OS_WINDOWS)
-  // On Windows we expect this to be called from the thread interrupter thread.
-  ASSERT(id() != OSThread::GetCurrentThreadId());
-#else
-  // On posix platforms, we expect this to be called from signal handler.
-  ASSERT(id() == OSThread::GetCurrentThreadId());
-#endif
-  ASSERT(callback != NULL);
-  ASSERT(data != NULL);
-  *callback = thread_interrupt_callback_;
-  *data = thread_interrupt_data_;
-  return (*callback != NULL) &&
-         (*data != NULL);
+void Thread::EnableThreadInterrupts() {
+  ASSERT(Thread::Current() == this);
+  uintptr_t old =
+      AtomicOperations::FetchAndDecrement(&thread_interrupt_disabled_);
+  if (old == 1) {
+    // We just decremented from 1 to 0.
+    // Make sure the thread interrupter is awake.
+    ThreadInterrupter::WakeUp();
+  }
+  if (old == 0) {
+    // We just decremented from 0, this means we've got a mismatched pair
+    // of calls to EnableThreadInterrupts and DisableThreadInterrupts.
+    FATAL("Invalid call to Thread::EnableThreadInterrupts()");
+  }
+}
+
+
+bool Thread::ThreadInterruptsEnabled() {
+  return AtomicOperations::LoadRelaxed(&thread_interrupt_disabled_) == 0;
 }
 
 
@@ -487,6 +553,18 @@
 }
 
 
+bool Thread::ObjectAtOffset(intptr_t offset, Object* object) {
+#define COMPUTE_OFFSET(type_name, member_name, expr, default_init_value)       \
+  if (Thread::member_name##offset() == offset) {                               \
+    *object = expr;                                                            \
+    return true;                                                               \
+  }
+CACHED_VM_OBJECTS_LIST(COMPUTE_OFFSET)
+#undef COMPUTE_OFFSET
+  return false;
+}
+
+
 intptr_t Thread::OffsetFromThread(const RuntimeEntry* runtime_entry) {
 #define COMPUTE_OFFSET(name)                                                   \
   if (runtime_entry->function() == k##name##RuntimeEntry.function())         { \
@@ -538,4 +616,18 @@
 }
 
 
+DisableThreadInterruptsScope::DisableThreadInterruptsScope(Thread* thread)
+    : StackResource(thread) {
+  if (thread != NULL) {
+    thread->DisableThreadInterrupts();
+  }
+}
+
+
+DisableThreadInterruptsScope::~DisableThreadInterruptsScope() {
+  if (thread() != NULL) {
+    thread()->EnableThreadInterrupts();
+  }
+}
+
 }  // namespace dart
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index 210fef1..d4a3ea1 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -35,6 +35,7 @@
 class RawBool;
 class RawObject;
 class RawCode;
+class RawGrowableObjectArray;
 class RawString;
 class RuntimeEntry;
 class StackResource;
@@ -90,26 +91,6 @@
   CACHED_VM_OBJECTS_LIST(V)                                                    \
   CACHED_ADDRESSES_LIST(V)                                                     \
 
-struct InterruptedThreadState {
-  ThreadId tid;
-  uintptr_t pc;
-  uintptr_t csp;
-  uintptr_t dsp;
-  uintptr_t fp;
-  uintptr_t lr;
-};
-
-// When a thread is interrupted the thread specific interrupt callback will be
-// invoked. Each callback is given an InterruptedThreadState and the user data
-// pointer. When inside a thread interrupt callback doing any of the following
-// is forbidden:
-//   * Accessing TLS -- Because on Windows the callback will be running in a
-//                      different thread.
-//   * Allocating memory -- Because this takes locks which may already be held,
-//                          resulting in a dead lock.
-//   * Taking a lock -- See above.
-typedef void (*ThreadInterruptCallback)(const InterruptedThreadState& state,
-                                        void* data);
 
 // A VM thread; may be executing Dart code or performing helper tasks like
 // garbage collection or compilation. The Thread structure associated with
@@ -144,11 +125,6 @@
   // TODO(koda): Always run GC in separate thread.
   static void PrepareForGC();
 
-#if defined(TARGET_OS_WINDOWS)
-  // Clears the state of the current thread and frees the allocation.
-  static void CleanUp();
-#endif
-
   // Called at VM startup.
   static void InitOnceBeforeIsolate();
   static void InitOnceAfterObjectAndStubCode();
@@ -165,6 +141,13 @@
   static intptr_t isolate_offset() {
     return OFFSET_OF(Thread, isolate_);
   }
+  bool IsMutatorThread() const;
+
+  // Is |this| executing Dart code?
+  bool IsExecutingDartCode() const;
+
+  // Has |this| exited Dart code?
+  bool HasExitedDartCode() const;
 
   // The (topmost) CHA for the compilation in this thread.
   CHA* cha() const;
@@ -277,7 +260,6 @@
     Zone* zone;
     uword top_exit_frame_info;
     StackResource* top_resource;
-    TimelineEventBlock* timeline_block;
     LongJumpScope* long_jump_base;
 #if defined(DEBUG)
     HandleScope* top_handle_scope;
@@ -309,6 +291,7 @@
 
   static bool CanLoadFromThread(const Object& object);
   static intptr_t OffsetFromThread(const Object& object);
+  static bool ObjectAtOffset(intptr_t offset, Object* object);
   static intptr_t OffsetFromThread(const RuntimeEntry* runtime_entry);
 
   Mutex* timeline_block_lock() {
@@ -317,12 +300,12 @@
 
   // Only safe to access when holding |timeline_block_lock_|.
   TimelineEventBlock* timeline_block() const {
-    return state_.timeline_block;
+    return timeline_block_;
   }
 
   // Only safe to access when holding |timeline_block_lock_|.
   void set_timeline_block(TimelineEventBlock* block) {
-    state_.timeline_block = block;
+    timeline_block_ = block;
   }
 
   class Log* log() const;
@@ -376,10 +359,30 @@
     return id_;
   }
 
-  void SetThreadInterrupter(ThreadInterruptCallback callback, void* data);
+  ThreadId join_id() const {
+    ASSERT(join_id_ != OSThread::kInvalidThreadJoinId);
+    return join_id_;
+  }
 
-  bool IsThreadInterrupterEnabled(ThreadInterruptCallback* callback,
-                                  void** data) const;
+  ThreadId trace_id() const {
+    ASSERT(trace_id_ != OSThread::kInvalidThreadJoinId);
+    return trace_id_;
+  }
+
+  const char* name() const {
+    return name_;
+  }
+
+  void set_name(const char* name) {
+    ASSERT(Thread::Current() == this);
+    ASSERT(name_ == NULL);
+    name_ = name;
+  }
+
+  // Used to temporarily disable or enable thread interrupts.
+  void DisableThreadInterrupts();
+  void EnableThreadInterrupts();
+  bool ThreadInterruptsEnabled();
 
 #if defined(DEBUG)
 #define REUSABLE_HANDLE_SCOPE_ACCESSORS(object)                                \
@@ -410,24 +413,28 @@
   REUSABLE_HANDLE_LIST(REUSABLE_HANDLE)
 #undef REUSABLE_HANDLE
 
+  RawGrowableObjectArray* pending_functions();
+
   void VisitObjectPointers(ObjectPointerVisitor* visitor);
 
+  static bool IsThreadInList(ThreadId join_id);
+
  private:
   template<class T> T* AllocateReusableHandle();
 
   static ThreadLocalKey thread_key_;
 
   const ThreadId id_;
-  ThreadInterruptCallback thread_interrupt_callback_;
-  void* thread_interrupt_data_;
+  const ThreadId join_id_;
+  const ThreadId trace_id_;
+  uintptr_t thread_interrupt_disabled_;
   Isolate* isolate_;
   Heap* heap_;
   State state_;
   Mutex timeline_block_lock_;
+  TimelineEventBlock* timeline_block_;
   StoreBufferBlock* store_buffer_block_;
   class Log* log_;
-  intptr_t deopt_id_;  // Compilation specific counter.
-  uword vm_tag_;
 #define DECLARE_MEMBERS(type_name, member_name, expr, default_init_value)      \
   type_name member_name;
 CACHED_CONSTANTS_LIST(DECLARE_MEMBERS)
@@ -458,12 +465,20 @@
 
   VMHandles reusable_handles_;
 
+  // Compiler state:
   CHA* cha_;
+  intptr_t deopt_id_;  // Compilation specific counter.
+  uword vm_tag_;
+  RawGrowableObjectArray* pending_functions_;
+
   int32_t no_callback_scope_depth_;
 
   // All |Thread|s are registered in the thread list.
   Thread* thread_list_next_;
 
+  // A name for this thread.
+  const char* name_;
+
   static Thread* thread_list_head_;
   static Mutex* thread_list_lock_;
 
@@ -474,9 +489,7 @@
 
   void InitVMConstants();
 
-  void ClearState() {
-    memset(&state_, 0, sizeof(state_));
-  }
+  void ClearState();
 
   void StoreBufferRelease(
       StoreBuffer::ThresholdPolicy policy = StoreBuffer::kCheckThreshold);
@@ -502,6 +515,7 @@
 
   friend class ApiZone;
   friend class Isolate;
+  friend class Simulator;
   friend class StackZone;
   friend class ThreadIterator;
   friend class ThreadIteratorTestHelper;
@@ -528,6 +542,19 @@
   Thread* next_;
 };
 
+#if defined(TARGET_OS_WINDOWS)
+// Clears the state of the current thread and frees the allocation.
+void WindowsThreadCleanUp();
+#endif
+
+
+// Disable thread interrupts.
+class DisableThreadInterruptsScope : public StackResource {
+ public:
+  explicit DisableThreadInterruptsScope(Thread* thread);
+  ~DisableThreadInterruptsScope();
+};
+
 }  // namespace dart
 
 #endif  // VM_THREAD_H_
diff --git a/runtime/vm/thread_interrupter.cc b/runtime/vm/thread_interrupter.cc
index 58c94be..8a8af04 100644
--- a/runtime/vm/thread_interrupter.cc
+++ b/runtime/vm/thread_interrupter.cc
@@ -51,6 +51,7 @@
 bool ThreadInterrupter::initialized_ = false;
 bool ThreadInterrupter::shutdown_ = false;
 bool ThreadInterrupter::thread_running_ = false;
+bool ThreadInterrupter::woken_up_ = false;
 ThreadJoinId ThreadInterrupter::interrupter_thread_id_ =
     OSThread::kInvalidThreadJoinId;
 Monitor* ThreadInterrupter::monitor_ = NULL;
@@ -112,6 +113,7 @@
   }
 }
 
+
 // Delay between interrupts.
 void ThreadInterrupter::SetInterruptPeriod(intptr_t period) {
   if (shutdown_) {
@@ -124,9 +126,14 @@
 
 
 void ThreadInterrupter::WakeUp() {
+  if (!initialized_) {
+    // Early call.
+    return;
+  }
   ASSERT(initialized_);
   {
     MonitorLocker ml(monitor_);
+    woken_up_ = true;
     if (!InDeepSleep()) {
       // No need to notify, regularly waking up.
       return;
@@ -137,35 +144,6 @@
 }
 
 
-void ThreadInterruptNoOp(const InterruptedThreadState& state, void* data) {
-  // NoOp.
-}
-
-
-class ThreadInterrupterVisitIsolates : public IsolateVisitor {
- public:
-  ThreadInterrupterVisitIsolates() {
-    profiled_thread_count_ = 0;
-  }
-
-  void VisitIsolate(Isolate* isolate) {
-    ASSERT(isolate != NULL);
-    profiled_thread_count_ += isolate->ProfileInterrupt();
-  }
-
-  intptr_t profiled_thread_count() const {
-    return profiled_thread_count_;
-  }
-
-  void set_profiled_thread_count(intptr_t profiled_thread_count) {
-    profiled_thread_count_ = profiled_thread_count;
-  }
-
- private:
-  intptr_t profiled_thread_count_;
-};
-
-
 void ThreadInterrupter::ThreadMain(uword parameters) {
   ASSERT(initialized_);
   InstallSignalHandler();
@@ -180,35 +158,55 @@
     startup_ml.Notify();
   }
   {
-    ThreadInterrupterVisitIsolates visitor;
+    intptr_t interrupted_thread_count = 0;
     current_wait_time_ = interrupt_period_;
     MonitorLocker wait_ml(monitor_);
     while (!shutdown_) {
       intptr_t r = wait_ml.WaitMicros(current_wait_time_);
 
-      if ((r == Monitor::kNotified) && shutdown_) {
+      if (shutdown_) {
         break;
       }
 
       if ((r == Monitor::kNotified) && InDeepSleep()) {
         // Woken up from deep sleep.
-        ASSERT(visitor.profiled_thread_count() == 0);
+        ASSERT(interrupted_thread_count == 0);
         // Return to regular interrupts.
         current_wait_time_ = interrupt_period_;
       }
 
-      // Reset count before visiting isolates.
-      visitor.set_profiled_thread_count(0);
-      Isolate::VisitIsolates(&visitor);
+      // Reset count before interrupting any threads.
+      interrupted_thread_count = 0;
 
-      if (visitor.profiled_thread_count() == 0) {
-        // No isolates were profiled. In order to reduce unnecessary CPU
-        // load, we will wait until we are notified before attempting to
-        // interrupt again.
+      // Temporarily drop the monitor while we interrupt threads.
+      monitor_->Exit();
+
+      {
+        ThreadIterator it;
+        while (it.HasNext()) {
+          Thread* thread = it.Next();
+          if (thread->ThreadInterruptsEnabled()) {
+            interrupted_thread_count++;
+            InterruptThread(thread);
+          }
+        }
+      }
+
+      // Take the monitor lock again.
+      monitor_->Enter();
+
+      // Now that we have the lock, check if we were signaled to wake up while
+      // interrupting threads.
+      if (!woken_up_ && (interrupted_thread_count == 0)) {
+        // No threads were interrupted and we were not signaled to interrupt
+        // new threads. In order to reduce unnecessary CPU load, we will wait
+        // until we are notified before attempting to interrupt again.
         current_wait_time_ = Monitor::kNoTimeout;
         continue;
       }
 
+      woken_up_ = false;
+
       ASSERT(current_wait_time_ != Monitor::kNoTimeout);
     }
   }
diff --git a/runtime/vm/thread_interrupter.h b/runtime/vm/thread_interrupter.h
index 9d3ccab..5357615 100644
--- a/runtime/vm/thread_interrupter.h
+++ b/runtime/vm/thread_interrupter.h
@@ -12,6 +12,15 @@
 
 namespace dart {
 
+struct InterruptedThreadState {
+  uintptr_t pc;
+  uintptr_t csp;
+  uintptr_t dsp;
+  uintptr_t fp;
+  uintptr_t lr;
+};
+
+
 class ThreadInterrupter : public AllStatic {
  public:
   static void InitOnce();
@@ -25,13 +34,6 @@
   // Wake up the thread interrupter thread.
   static void WakeUp();
 
-  // Register the currently running thread for interrupts. If the current thread
-  // is already registered, callback and data will be updated.
-  static void Register(ThreadInterruptCallback callback, void* data);
-
-  // Unregister the currently running thread for interrupts.
-  static void Unregister();
-
   // Interrupt a thread.
   static void InterruptThread(Thread* thread);
 
@@ -40,6 +42,7 @@
   static bool initialized_;
   static bool shutdown_;
   static bool thread_running_;
+  static bool woken_up_;
   static ThreadJoinId interrupter_thread_id_;
   static Monitor* monitor_;
   static intptr_t interrupt_period_;
@@ -49,8 +52,6 @@
     return current_wait_time_ == Monitor::kNoTimeout;
   }
 
-  static void UpdateStateObject(ThreadInterruptCallback callback, void* data);
-
   static void ThreadMain(uword parameters);
 
   static void InstallSignalHandler();
@@ -60,8 +61,6 @@
   friend class ThreadInterrupterVisitIsolates;
 };
 
-void ThreadInterruptNoOp(const InterruptedThreadState& state, void* data);
-
 }  // namespace dart
 
 #endif  // VM_THREAD_INTERRUPTER_H_
diff --git a/runtime/vm/thread_interrupter_android.cc b/runtime/vm/thread_interrupter_android.cc
index 5c4092d..1c780ba 100644
--- a/runtime/vm/thread_interrupter_android.cc
+++ b/runtime/vm/thread_interrupter_android.cc
@@ -6,9 +6,11 @@
 #if defined(TARGET_OS_ANDROID)
 
 #include <sys/syscall.h>  // NOLINT
+#include <errno.h>  // NOLINT
 
 #include "vm/flags.h"
 #include "vm/os.h"
+#include "vm/profiler.h"
 #include "vm/signal_handler.h"
 #include "vm/thread_interrupter.h"
 
@@ -28,22 +30,16 @@
     if (thread == NULL) {
       return;
     }
-    ThreadInterruptCallback callback = NULL;
-    void* callback_data = NULL;
-    if (!thread->IsThreadInterrupterEnabled(&callback, &callback_data)) {
-      return;
-    }
     // Extract thread state.
     ucontext_t* context = reinterpret_cast<ucontext_t*>(context_);
     mcontext_t mcontext = context->uc_mcontext;
     InterruptedThreadState its;
-    its.tid = thread->id();
     its.pc = SignalHandler::GetProgramCounter(mcontext);
     its.fp = SignalHandler::GetFramePointer(mcontext);
     its.csp = SignalHandler::GetCStackPointer(mcontext);
     its.dsp = SignalHandler::GetDartStackPointer(mcontext);
     its.lr = SignalHandler::GetLinkRegister(mcontext);
-    callback(its, callback_data);
+    Profiler::SampleThread(thread, its);
   }
 };
 
@@ -54,7 +50,7 @@
               reinterpret_cast<void*>(thread->id()));
   }
   int result = syscall(__NR_tgkill, getpid(), thread->id(), SIGPROF);
-  ASSERT(result == 0);
+  ASSERT((result == 0) || (result == ESRCH));
 }
 
 
diff --git a/runtime/vm/thread_interrupter_linux.cc b/runtime/vm/thread_interrupter_linux.cc
index d7b9b85..2cb0f55 100644
--- a/runtime/vm/thread_interrupter_linux.cc
+++ b/runtime/vm/thread_interrupter_linux.cc
@@ -5,8 +5,11 @@
 #include "platform/globals.h"
 #if defined(TARGET_OS_LINUX)
 
+#include <errno.h>  // NOLINT
+
 #include "vm/flags.h"
 #include "vm/os.h"
+#include "vm/profiler.h"
 #include "vm/signal_handler.h"
 #include "vm/thread_interrupter.h"
 
@@ -26,22 +29,16 @@
     if (thread == NULL) {
       return;
     }
-    ThreadInterruptCallback callback = NULL;
-    void* callback_data = NULL;
-    if (!thread->IsThreadInterrupterEnabled(&callback, &callback_data)) {
-      return;
-    }
     // Extract thread state.
     ucontext_t* context = reinterpret_cast<ucontext_t*>(context_);
     mcontext_t mcontext = context->uc_mcontext;
     InterruptedThreadState its;
-    its.tid = thread->id();
     its.pc = SignalHandler::GetProgramCounter(mcontext);
     its.fp = SignalHandler::GetFramePointer(mcontext);
     its.csp = SignalHandler::GetCStackPointer(mcontext);
     its.dsp = SignalHandler::GetDartStackPointer(mcontext);
     its.lr = SignalHandler::GetLinkRegister(mcontext);
-    callback(its, callback_data);
+    Profiler::SampleThread(thread, its);
   }
 };
 
@@ -52,7 +49,7 @@
               reinterpret_cast<void*>(thread->id()));
   }
   int result = pthread_kill(thread->id(), SIGPROF);
-  ASSERT(result == 0);
+  ASSERT((result == 0) || (result == ESRCH));
 }
 
 
diff --git a/runtime/vm/thread_interrupter_macos.cc b/runtime/vm/thread_interrupter_macos.cc
index f1ff45e..c53ae13 100644
--- a/runtime/vm/thread_interrupter_macos.cc
+++ b/runtime/vm/thread_interrupter_macos.cc
@@ -5,8 +5,11 @@
 #include "platform/globals.h"
 #if defined(TARGET_OS_MACOS)
 
+#include <errno.h>  // NOLINT
+
 #include "vm/flags.h"
 #include "vm/os.h"
+#include "vm/profiler.h"
 #include "vm/signal_handler.h"
 #include "vm/thread_interrupter.h"
 
@@ -26,22 +29,16 @@
     if (thread == NULL) {
       return;
     }
-    ThreadInterruptCallback callback = NULL;
-    void* callback_data = NULL;
-    if (!thread->IsThreadInterrupterEnabled(&callback, &callback_data)) {
-      return;
-    }
     // Extract thread state.
     ucontext_t* context = reinterpret_cast<ucontext_t*>(context_);
     mcontext_t mcontext = context->uc_mcontext;
     InterruptedThreadState its;
-    its.tid = thread->id();
     its.pc = SignalHandler::GetProgramCounter(mcontext);
     its.fp = SignalHandler::GetFramePointer(mcontext);
     its.csp = SignalHandler::GetCStackPointer(mcontext);
     its.dsp = SignalHandler::GetDartStackPointer(mcontext);
     its.lr = SignalHandler::GetLinkRegister(mcontext);
-    callback(its, callback_data);
+    Profiler::SampleThread(thread, its);
   }
 };
 
@@ -51,7 +48,7 @@
     OS::Print("ThreadInterrupter interrupting %p\n", thread->id());
   }
   int result = pthread_kill(thread->id(), SIGPROF);
-  ASSERT(result == 0);
+  ASSERT((result == 0) || (result == ESRCH));
 }
 
 
diff --git a/runtime/vm/thread_interrupter_test.cc b/runtime/vm/thread_interrupter_test.cc
deleted file mode 100644
index aeb9ff1..0000000
--- a/runtime/vm/thread_interrupter_test.cc
+++ /dev/null
@@ -1,66 +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.
-
-#include "platform/assert.h"
-
-#include "vm/dart_api_impl.h"
-#include "vm/dart_api_state.h"
-#include "vm/globals.h"
-#include "vm/thread_interrupter.h"
-#include "vm/unit_test.h"
-
-namespace dart {
-
-class ThreadInterrupterTestHelper : public AllStatic {
- public:
-  static void InterruptTest(const intptr_t run_time, const intptr_t period) {
-    const double allowed_error = 0.25;  // +/- 25%
-    intptr_t count = 0;
-    Thread::EnsureInit();
-    Thread* thread = Thread::Current();
-    thread->SetThreadInterrupter(IncrementCallback, &count);
-    ThreadInterrupter::SetInterruptPeriod(period);
-    OS::Sleep(run_time * kMillisecondsPerSecond);
-    thread->SetThreadInterrupter(NULL, NULL);
-    intptr_t run_time_micros = run_time * kMicrosecondsPerSecond;
-    intptr_t expected_interrupts = run_time_micros / period;
-    intptr_t error = allowed_error * expected_interrupts;
-    intptr_t low_bar = expected_interrupts - error;
-    intptr_t high_bar = expected_interrupts + error;
-    EXPECT_GE(count, low_bar);
-    EXPECT_LE(count, high_bar);
-  }
-
-  static void IncrementCallback(const InterruptedThreadState& state,
-                                void* data) {
-    ASSERT(data != NULL);
-    intptr_t* counter = reinterpret_cast<intptr_t*>(data);
-    *counter = *counter + 1;
-  }
-};
-
-
-TEST_CASE(ThreadInterrupterHigh) {
-  const intptr_t kRunTimeSeconds = 5;
-  const intptr_t kInterruptPeriodMicros = 250;
-  ThreadInterrupterTestHelper::InterruptTest(kRunTimeSeconds,
-                                             kInterruptPeriodMicros);
-}
-
-TEST_CASE(ThreadInterrupterMedium) {
-  const intptr_t kRunTimeSeconds = 5;
-  const intptr_t kInterruptPeriodMicros = 500;
-  ThreadInterrupterTestHelper::InterruptTest(kRunTimeSeconds,
-                                             kInterruptPeriodMicros);
-}
-
-TEST_CASE(ThreadInterrupterLow) {
-  const intptr_t kRunTimeSeconds = 5;
-  const intptr_t kInterruptPeriodMicros = 1000;
-  ThreadInterrupterTestHelper::InterruptTest(kRunTimeSeconds,
-                                             kInterruptPeriodMicros);
-}
-
-
-}  // namespace dart
diff --git a/runtime/vm/thread_interrupter_win.cc b/runtime/vm/thread_interrupter_win.cc
index 70a5e8c..4231d1e 100644
--- a/runtime/vm/thread_interrupter_win.cc
+++ b/runtime/vm/thread_interrupter_win.cc
@@ -7,6 +7,7 @@
 
 #include "vm/flags.h"
 #include "vm/os.h"
+#include "vm/profiler.h"
 #include "vm/thread_interrupter.h"
 
 namespace dart {
@@ -69,7 +70,6 @@
       return;
     }
     InterruptedThreadState its;
-    its.tid = thread->id();
     if (!GrabRegisters(handle, &its)) {
       // Failed to get thread registers.
       ResumeThread(handle);
@@ -80,11 +80,7 @@
       CloseHandle(handle);
       return;
     }
-    ThreadInterruptCallback callback = NULL;
-    void* callback_data = NULL;
-    if (thread->IsThreadInterrupterEnabled(&callback, &callback_data)) {
-      callback(its, callback_data);
-    }
+    Profiler::SampleThread(thread, its);
     ResumeThread(handle);
     CloseHandle(handle);
   }
diff --git a/runtime/vm/thread_pool.cc b/runtime/vm/thread_pool.cc
index e4453d8..d5472a6 100644
--- a/runtime/vm/thread_pool.cc
+++ b/runtime/vm/thread_pool.cc
@@ -418,6 +418,8 @@
 // static
 void ThreadPool::Worker::Main(uword args) {
   Thread::EnsureInit();
+  Thread* thread = Thread::Current();
+  thread->set_name("Dart ThreadPool Worker");
   Worker* worker = reinterpret_cast<Worker*>(args);
   ThreadId id = OSThread::GetCurrentThreadId();
   ThreadJoinId join_id = OSThread::GetCurrentThreadJoinId();
@@ -471,9 +473,6 @@
     // wait for the thread to exit by joining on it in Shutdown().
     delete worker;
   }
-#if defined(TARGET_OS_WINDOWS)
-  Thread::CleanUp();
-#endif
 }
 
 }  // namespace dart
diff --git a/runtime/vm/thread_registry.cc b/runtime/vm/thread_registry.cc
index 44c0d13..f0f80e3 100644
--- a/runtime/vm/thread_registry.cc
+++ b/runtime/vm/thread_registry.cc
@@ -10,7 +10,6 @@
 namespace dart {
 
 ThreadRegistry::~ThreadRegistry() {
-  ReclaimTimelineBlocks();
   // Delete monitor.
   delete monitor_;
 }
@@ -34,7 +33,7 @@
   // TODO(koda): Rename Thread::PrepareForGC and call it here?
   --remaining_;  // Exclude this thread from the count.
   // Ensure the main mutator will reach a safepoint (could be running Dart).
-  if (!isolate->MutatorThreadIsCurrentThread()) {
+  if (!Thread::Current()->IsMutatorThread()) {
     isolate->ScheduleInterrupts(Isolate::kVMInterrupt);
   }
   while (remaining_ > 0) {
@@ -67,54 +66,7 @@
   if (found_index < 0) {
     return;
   }
-  {
-    TimelineEventRecorder* recorder = Timeline::recorder();
-    if (recorder != NULL) {
-      // Cleanup entry.
-      Entry& entry_to_remove = entries_[found_index];
-      ReclaimTimelineBlockLocked(&entry_to_remove);
-    }
-  }
-  if (found_index != (length - 1)) {
-    // Swap with last entry.
-    entries_.Swap(found_index, length - 1);
-  }
-  entries_.RemoveLast();
-}
-
-
-void ThreadRegistry::ReclaimTimelineBlocks() {
-  // Each thread that is scheduled in this isolate may have a cached timeline
-  // block. Mark these timeline blocks as finished.
-  MonitorLocker ml(monitor_);
-  TimelineEventRecorder* recorder = Timeline::recorder();
-  if (recorder != NULL) {
-    for (intptr_t i = 0; i < entries_.length(); i++) {
-      // NOTE: It is only safe to access |entry.state| here.
-      Entry& entry = entries_[i];
-      ReclaimTimelineBlockLocked(&entry);
-    }
-  }
-}
-
-
-void ThreadRegistry::ReclaimTimelineBlockLocked(Entry* entry) {
-  if (entry == NULL) {
-    return;
-  }
-  TimelineEventRecorder* recorder = Timeline::recorder();
-  if (!entry->scheduled && (entry->state.timeline_block != NULL)) {
-    // Currently unscheduled thread.
-    recorder->FinishBlock(entry->state.timeline_block);
-    entry->state.timeline_block = NULL;
-  } else if (entry->scheduled) {
-    // Currently scheduled thread.
-    Thread* thread = entry->thread;
-    // Take |Thread| lock.
-    MutexLocker thread_lock(thread->timeline_block_lock());
-    recorder->FinishBlock(thread->timeline_block());
-    thread->set_timeline_block(NULL);
-  }
+  entries_.RemoveAt(found_index);
 }
 
 
diff --git a/runtime/vm/thread_registry.h b/runtime/vm/thread_registry.h
index 90d83f0..b78a761 100644
--- a/runtime/vm/thread_registry.h
+++ b/runtime/vm/thread_registry.h
@@ -48,6 +48,8 @@
     CheckSafepointLocked();
   }
 
+  bool AtSafepoint() const { return in_rendezvous_; }
+
   bool RestoreStateTo(Thread* thread, Thread::State* state,
                       bool bypass_safepoint) {
     MonitorLocker ml(monitor_);
@@ -188,9 +190,6 @@
     return NULL;
   }
 
-  // NOTE: Lock should be taken before this function is called.
-  void ReclaimTimelineBlockLocked(Entry* entry);
-
   // Note: Lock should be taken before this function is called.
   void CheckSafepointLocked();
 
diff --git a/runtime/vm/thread_test.cc b/runtime/vm/thread_test.cc
index 8e78dca..7eb5849 100644
--- a/runtime/vm/thread_test.cc
+++ b/runtime/vm/thread_test.cc
@@ -39,10 +39,8 @@
   Dart_CreateIsolate(
       NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL, NULL);
   Thread* thread = Thread::Current();
-  Isolate* isolate = thread->isolate();
   // Thread interrupter interferes with this test, disable interrupts.
-  thread->SetThreadInterrupter(NULL, NULL);
-  Profiler::EndExecution(isolate);
+  thread->DisableThreadInterrupts();
   Monitor* monitor = new Monitor();
   monitor->Enter();
   monitor->Exit();
@@ -435,28 +433,14 @@
 }
 
 
-static bool ThreadInList(Thread* thread) {
-  ThreadIterator it;
-  while (it.HasNext()) {
-    Thread* t = it.Next();
-    if (t == thread) {
-      return true;
-    }
-  }
-  return false;
-}
-
-
 TEST_CASE(ThreadIterator_FindSelf) {
   Thread* current = Thread::Current();
-  EXPECT(ThreadInList(current));
+  EXPECT(Thread::IsThreadInList(current->join_id()));
 }
 
 
 struct ThreadIteratorTestParams {
-  Isolate* isolate;
-  Thread* spawned_thread;
-  ThreadJoinId spawned_thread_join_id;
+  ThreadId spawned_thread_join_id;
   Monitor* monitor;
 };
 
@@ -465,52 +449,38 @@
   Thread::EnsureInit();
   ThreadIteratorTestParams* params =
       reinterpret_cast<ThreadIteratorTestParams*>(parameter);
-  Isolate* isolate = params->isolate;
-  EXPECT(isolate != NULL);
   Thread* thread = Thread::Current();
   EXPECT(thread != NULL);
 
   MonitorLocker ml(params->monitor);
-  params->spawned_thread = thread;
-  params->spawned_thread_join_id = OSThread::GetCurrentThreadJoinId();
+  params->spawned_thread_join_id = thread->join_id();
   EXPECT(params->spawned_thread_join_id != OSThread::kInvalidThreadJoinId);
-  EXPECT(ThreadInList(thread));
+  EXPECT(Thread::IsThreadInList(thread->join_id()));
   ml.Notify();
 }
 
 
+// NOTE: This test case also verifies that known TLS destructors are called
+// on Windows. See |OnDartThreadExit| in os_thread_win.cc for more details.
 TEST_CASE(ThreadIterator_AddFindRemove) {
-  Isolate* isolate = thread->isolate();
   ThreadIteratorTestParams params;
-  params.isolate = isolate;
-  params.spawned_thread = NULL;
   params.spawned_thread_join_id = OSThread::kInvalidThreadJoinId;
   params.monitor = new Monitor();
 
   {
     MonitorLocker ml(params.monitor);
     EXPECT(params.spawned_thread_join_id == OSThread::kInvalidThreadJoinId);
-    EXPECT(params.spawned_thread == NULL);
     // Spawn thread and wait to receive the thread join id.
     OSThread::Start(ThreadIteratorTestMain, reinterpret_cast<uword>(&params));
     while (params.spawned_thread_join_id == OSThread::kInvalidThreadJoinId) {
       ml.Wait();
     }
     EXPECT(params.spawned_thread_join_id != OSThread::kInvalidThreadJoinId);
-    EXPECT(params.spawned_thread != NULL);
     // Join thread.
     OSThread::Join(params.spawned_thread_join_id);
   }
 
-  for (intptr_t i = 0; i < 10; i++) {
-    // Sleep for 10 milliseconds.
-    OS::Sleep(10);
-    if (!ThreadInList(params.spawned_thread)) {
-      break;
-    }
-  }
-
-  EXPECT(!ThreadInList(params.spawned_thread))
+  EXPECT(!Thread::IsThreadInList(params.spawned_thread_join_id))
 
   delete params.monitor;
 }
diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc
index 6b96b16..d840767 100644
--- a/runtime/vm/timeline.cc
+++ b/runtime/vm/timeline.cc
@@ -30,7 +30,7 @@
 //
 // Writing events:
 // |TimelineEvent|s are written into |TimelineEventBlock|s. Each |Thread| caches
-// a |TimelineEventBlock| in TLS so that it can write events without
+// a |TimelineEventBlock| object so that it can write events without
 // synchronizing with other threads in the system. Even though the |Thread| owns
 // the |TimelineEventBlock| the block may need to be reclaimed by the reporting
 // system. To support that, a |Thread| must hold its |timeline_block_lock_|
@@ -41,30 +41,17 @@
 // When requested, the timeline is serialized in the trace-event format
 // (https://goo.gl/hDZw5M). The request can be for a VM-wide timeline or an
 // isolate specific timeline. In both cases it may be that a thread has
-// a |TimelineEventBlock| cached in TLS. In order to report a complete timeline
-// the cached |TimelineEventBlock|s need to be reclaimed.
+// a |TimelineEventBlock| cached in TLS partially filled with events. In order
+// to report a complete timeline the cached |TimelineEventBlock|s need to be
+// reclaimed.
 //
-// Reclaiming open |TimelineEventBlock|s for an isolate:
+// Reclaiming open |TimelineEventBlock|s from threads:
 //
-// Cached |TimelineEventBlock|s can be in two places:
-// 1) In a |Thread| (Thread currently in an |Isolate|)
-// 2) In a |Thread::State| (Thread not currently in an |Isolate|).
+// Each |Thread| can have one |TimelineEventBlock| cached in it.
 //
-// As a |Thread| enters and exits an |Isolate|, a |TimelineEventBlock|
-// will move between (1) and (2).
-//
-// The first case occurs for |Thread|s that are currently running inside an
-// isolate. The second case occurs for |Thread|s that are not currently
-// running inside an isolate.
-//
-// To reclaim the first case, we take the |Thread|'s |timeline_block_lock_|
-// and reclaim the cached block.
-//
-// To reclaim the second case, we can take the |ThreadRegistry| lock and
-// reclaim these blocks.
-//
-// |Timeline::ReclaimIsolateBlocks| and |Timeline::ReclaimAllBlocks| are
-// the two utility methods used to reclaim blocks before reporting.
+// To reclaim blocks, we iterate over all threads and remove the cached
+// |TimelineEventBlock| from each thread. This is safe because we hold the
+// |Thread|'s |timeline_block_lock_| meaning the block can't be being modified.
 //
 // Locking notes:
 // The following locks are used by the timeline system:
@@ -72,14 +59,11 @@
 // |TimelineEventBlock| is being requested or reclaimed.
 // - |Thread::timeline_block_lock_| This lock is held whenever a |Thread|'s
 // cached block is being operated on.
-// - |ThreadRegistry::monitor_| This lock protects the cached block for
-// unscheduled threads of an isolate.
-// - |Isolate::isolates_list_monitor_| This lock protects the list of
-// isolates in the system.
+// - |Thread::thread_list_lock_| This lock is held when iterating over
+// |Thread|s.
 //
 // Locks must always be taken in the following order:
-// |Isolate::isolates_list_monitor_|
-//   |ThreadRegistry::monitor_|
+//   |Thread::thread_list_lock_|
 //     |Thread::timeline_block_lock_|
 //       |TimelineEventRecorder::lock_|
 //
@@ -90,7 +74,7 @@
   const bool use_ring_recorder = true;
   // Some flags require that we use the endless recorder.
   const bool use_endless_recorder =
-      (FLAG_timeline_dir != NULL) || FLAG_timing;
+      (FLAG_timeline_dir != NULL) || FLAG_timing || FLAG_complete_timeline;
   if (use_endless_recorder) {
     recorder_ = new TimelineEventEndlessRecorder();
   } else if (use_ring_recorder) {
@@ -100,7 +84,7 @@
   vm_stream_->Init("VM", EnableStreamByDefault("VM"), NULL);
   // Global overrides.
 #define ISOLATE_TIMELINE_STREAM_FLAG_DEFAULT(name, not_used)                   \
-  stream_##name##_enabled_ = false;
+  stream_##name##_enabled_ = EnableStreamByDefault(#name);
   ISOLATE_TIMELINE_STREAM_LIST(ISOLATE_TIMELINE_STREAM_FLAG_DEFAULT)
 #undef ISOLATE_TIMELINE_STREAM_FLAG_DEFAULT
 }
@@ -125,7 +109,7 @@
 
 bool Timeline::EnableStreamByDefault(const char* stream_name) {
   // TODO(johnmccutchan): Allow for command line control over streams.
-  return (FLAG_timeline_dir != NULL) || FLAG_timing;
+  return (FLAG_timeline_dir != NULL) || FLAG_timing || FLAG_complete_timeline;
 }
 
 
@@ -135,41 +119,35 @@
 }
 
 
-void Timeline::ReclaimIsolateBlocks() {
-  ReclaimBlocksForIsolate(Isolate::Current());
+void Timeline::ReclaimCachedBlocksFromThreads() {
+  TimelineEventRecorder* recorder = Timeline::recorder();
+  if (recorder == NULL) {
+    return;
+  }
+
+  // Iterate over threads.
+  ThreadIterator it;
+  while (it.HasNext()) {
+    Thread* thread = it.Next();
+    MutexLocker ml(thread->timeline_block_lock());
+    // Grab block and clear it.
+    TimelineEventBlock* block = thread->timeline_block();
+    thread->set_timeline_block(NULL);
+    // TODO(johnmccutchan): Consider dropping the timeline_block_lock here
+    // if we can do it everywhere. This would simplify the lock ordering
+    // requirements.
+    recorder->FinishBlock(block);
+  }
 }
 
 
-class ReclaimBlocksIsolateVisitor : public IsolateVisitor {
- public:
-  ReclaimBlocksIsolateVisitor() {}
-
-  virtual void VisitIsolate(Isolate* isolate) {
-    Timeline::ReclaimBlocksForIsolate(isolate);
-  }
-
- private:
-};
-
-
-void Timeline::ReclaimAllBlocks() {
-  if (recorder() == NULL) {
+void Timeline::Clear() {
+  TimelineEventRecorder* recorder = Timeline::recorder();
+  if (recorder == NULL) {
     return;
   }
-  // Reclaim all blocks cached for all isolates.
-  ReclaimBlocksIsolateVisitor visitor;
-  Isolate::VisitIsolates(&visitor);
-  // Reclaim the global VM block.
-  recorder()->ReclaimGlobalBlock();
-}
-
-
-void Timeline::ReclaimBlocksForIsolate(Isolate* isolate) {
-  if (recorder() == NULL) {
-    return;
-  }
-  ASSERT(isolate != NULL);
-  isolate->ReclaimTimelineBlocks();
+  ReclaimCachedBlocksFromThreads();
+  recorder->Clear();
 }
 
 
@@ -177,7 +155,7 @@
 TimelineStream* Timeline::vm_stream_ = NULL;
 
 #define ISOLATE_TIMELINE_STREAM_DEFINE_FLAG(name, enabled_by_default)          \
-  bool Timeline::stream_##name##_enabled_ = false;
+  bool Timeline::stream_##name##_enabled_ = enabled_by_default;
   ISOLATE_TIMELINE_STREAM_LIST(ISOLATE_TIMELINE_STREAM_DEFINE_FLAG)
 #undef ISOLATE_TIMELINE_STREAM_DEFINE_FLAG
 
@@ -189,7 +167,8 @@
       state_(0),
       label_(NULL),
       category_(""),
-      thread_(OSThread::kInvalidThreadId) {
+      thread_(OSThread::kInvalidThreadId),
+      isolate_id_(ILLEGAL_PORT) {
 }
 
 
@@ -201,7 +180,7 @@
 void TimelineEvent::Reset() {
   set_event_type(kNone);
   thread_ = OSThread::kInvalidThreadId;
-  isolate_ = NULL;
+  isolate_id_ = ILLEGAL_PORT;
   category_ = "";
   label_ = NULL;
   FreeArguments();
@@ -274,6 +253,13 @@
 }
 
 
+void TimelineEvent::SerializedJSON(const char* json) {
+  Init(kSerializedJSON, "Dart");
+  SetNumArguments(1);
+  CopyArgument(0, "Dart", json);
+}
+
+
 void TimelineEvent::SetNumArguments(intptr_t length) {
   // Cannot call this twice.
   ASSERT(arguments_ == NULL);
@@ -365,13 +351,32 @@
   timestamp0_ = 0;
   timestamp1_ = 0;
   thread_ = OSThread::GetCurrentThreadTraceId();
-  isolate_ = Isolate::Current();
+  Isolate* isolate = Isolate::Current();
+  if (isolate != NULL) {
+    isolate_id_ = isolate->main_port();
+  } else {
+    isolate_id_ = ILLEGAL_PORT;
+  }
   label_ = label;
   FreeArguments();
 }
 
 
+const char* TimelineEvent::GetSerializedJSON() const {
+  ASSERT(event_type() == kSerializedJSON);
+  ASSERT(arguments_length_ == 1);
+  ASSERT(arguments_ != NULL);
+  return arguments_[0].value;
+}
+
+
 void TimelineEvent::PrintJSON(JSONStream* stream) const {
+  if (event_type() == kSerializedJSON) {
+    // Event has already been serialized into JSON- just append the
+    // raw data.
+    stream->AppendSerializedObject(GetSerializedJSON());
+    return;
+  }
   JSONObject obj(stream);
   int64_t pid = OS::ProcessId();
   int64_t tid = OSThread::ThreadIdToIntPtr(thread_);
@@ -424,6 +429,11 @@
       const TimelineEventArgument& arg = arguments_[i];
       args.AddProperty(arg.name, arg.value);
     }
+    if (isolate_id_ != ILLEGAL_PORT) {
+      // If we have one, append the isolate id.
+      args.AddPropertyF("isolateNumber", "%" Pd64 "",
+                        static_cast<int64_t>(isolate_id_));
+    }
   }
 }
 
@@ -511,6 +521,11 @@
     return;
   }
   TimelineEvent* event = stream_->StartEvent();
+  if (event == NULL) {
+    // Stream is now disabled.
+    FreeArguments();
+    return;
+  }
   ASSERT(event != NULL);
   event->Duration(label_, timestamp_, OS::GetCurrentTraceMicros());
   event->StealArguments(arguments_length_, arguments_);
@@ -615,48 +630,37 @@
 }
 
 
-IsolateTimelineEventFilter::IsolateTimelineEventFilter(Isolate* isolate)
-    : isolate_(isolate) {
-}
-
-
-DartTimelineEvent::DartTimelineEvent()
-    : isolate_(NULL),
-      event_as_json_(NULL) {
-}
-
-
-DartTimelineEvent::~DartTimelineEvent() {
-  Clear();
-}
-
-
-void DartTimelineEvent::Clear() {
-  if (isolate_ != NULL) {
-    isolate_ = NULL;
-  }
-  if (event_as_json_ != NULL) {
-    free(event_as_json_);
-    event_as_json_ = NULL;
-  }
-}
-
-
-void DartTimelineEvent::Init(Isolate* isolate, const char* event) {
-  ASSERT(isolate_ == NULL);
-  ASSERT(event != NULL);
-  isolate_ = isolate;
-  event_as_json_ = strdup(event);
+IsolateTimelineEventFilter::IsolateTimelineEventFilter(Dart_Port isolate_id)
+    : isolate_id_(isolate_id) {
 }
 
 
 TimelineEventRecorder::TimelineEventRecorder()
-    : global_block_(NULL),
-      async_id_(0) {
+    : async_id_(0) {
 }
 
 
 void TimelineEventRecorder::PrintJSONMeta(JSONArray* events) const {
+  ThreadIterator it;
+  while (it.HasNext()) {
+    Thread* thread = it.Next();
+    const char* thread_name = thread->name();
+    if (thread_name == NULL) {
+      // Only emit a thread name if one was set.
+      continue;
+    }
+    JSONObject obj(events);
+    int64_t pid = OS::ProcessId();
+    int64_t tid = OSThread::ThreadIdToIntPtr(thread->trace_id());
+    obj.AddProperty("name", "thread_name");
+    obj.AddProperty("ph", "M");
+    obj.AddProperty64("pid", pid);
+    obj.AddProperty64("tid", tid);
+    {
+      JSONObject args(&obj, "args");
+      args.AddPropertyF("name", "%s (%" Pd64 ")", thread_name, tid);
+    }
+  }
 }
 
 
@@ -664,7 +668,6 @@
   // Grab the current thread.
   Thread* thread = Thread::Current();
   ASSERT(thread != NULL);
-  ASSERT(thread->isolate() != NULL);
   Mutex* thread_block_lock = thread->timeline_block_lock();
   ASSERT(thread_block_lock != NULL);
   // We are accessing the thread's timeline block- so take the lock here.
@@ -679,21 +682,18 @@
     // 1) Mark it as finished.
     thread_block->Finish();
     // 2) Allocate a new block.
-    thread_block = GetNewBlockLocked(thread->isolate());
+    thread_block = GetNewBlockLocked();
     thread->set_timeline_block(thread_block);
   } else if (thread_block == NULL) {
     MutexLocker ml(&lock_);
     // Thread has no block. Attempt to allocate one.
-    thread_block = GetNewBlockLocked(thread->isolate());
+    thread_block = GetNewBlockLocked();
     thread->set_timeline_block(thread_block);
   }
   if (thread_block != NULL) {
     // NOTE: We are exiting this function with the thread's block lock held.
     ASSERT(!thread_block->IsFull());
     TimelineEvent* event = thread_block->StartEvent();
-    if (event != NULL) {
-      event->set_global_block(false);
-    }
     return event;
   }
   // Drop lock here as no event is being handed out.
@@ -702,82 +702,20 @@
 }
 
 
-TimelineEvent* TimelineEventRecorder::GlobalBlockStartEvent() {
-  // Take recorder lock. This lock will be held until the call to
-  // |CompleteEvent| is made.
-  lock_.Lock();
-  if (FLAG_trace_timeline) {
-    OS::Print("GlobalBlockStartEvent in block %p for thread %" Px "\n",
-              global_block_, OSThread::CurrentCurrentThreadIdAsIntPtr());
-  }
-  if ((global_block_ != NULL) && global_block_->IsFull()) {
-    // Global block is full.
-    global_block_->Finish();
-    global_block_ = NULL;
-  }
-  if (global_block_ == NULL) {
-    // Allocate a new block.
-    global_block_ = GetNewBlockLocked(NULL);
-    ASSERT(global_block_ != NULL);
-  }
-  if (global_block_ != NULL) {
-    // NOTE: We are exiting this function with the recorder's lock held.
-    ASSERT(!global_block_->IsFull());
-    TimelineEvent* event = global_block_->StartEvent();
-    if (event != NULL) {
-      event->set_global_block(true);
-    }
-    return event;
-  }
-  // Drop lock here as no event is being handed out.
-  lock_.Unlock();
-  return NULL;
-}
-
-
 void TimelineEventRecorder::ThreadBlockCompleteEvent(TimelineEvent* event) {
   if (event == NULL) {
     return;
   }
-  ASSERT(!event->global_block());
   // Grab the current thread.
   Thread* thread = Thread::Current();
   ASSERT(thread != NULL);
-  ASSERT(thread->isolate() != NULL);
-  // This event came from the isolate's thread local block. Unlock the
-  // thread's block lock.
+  // Unlock the thread's block lock.
   Mutex* thread_block_lock = thread->timeline_block_lock();
   ASSERT(thread_block_lock != NULL);
   thread_block_lock->Unlock();
 }
 
 
-void TimelineEventRecorder::GlobalBlockCompleteEvent(TimelineEvent* event) {
-  if (event == NULL) {
-    return;
-  }
-  ASSERT(event->global_block());
-  // This event came from the global block, unlock the recorder's lock now
-  // that the event is filled.
-  lock_.Unlock();
-}
-
-
-// Trims the ']' character.
-static void TrimOutput(char* output,
-                       intptr_t* output_length) {
-  ASSERT(output != NULL);
-  ASSERT(output_length != NULL);
-  ASSERT(*output_length >= 2);
-  // We expect the first character to be the opening of an array.
-  ASSERT(output[0] == '[');
-  // We expect the last character to be the closing of an array.
-  ASSERT(output[*output_length - 1] == ']');
-  // Skip the ].
-  *output_length -= 1;
-}
-
-
 void TimelineEventRecorder::WriteTo(const char* directory) {
   Dart_FileOpenCallback file_open = Isolate::file_open_callback();
   Dart_FileWriteCallback file_write = Isolate::file_write_callback();
@@ -788,7 +726,7 @@
   Thread* T = Thread::Current();
   StackZone zone(T);
 
-  Timeline::ReclaimAllBlocks();
+  Timeline::ReclaimCachedBlocksFromThreads();
 
   intptr_t pid = OS::ProcessId();
   char* filename = OS::SCreate(NULL,
@@ -808,47 +746,15 @@
   char* output = NULL;
   intptr_t output_length = 0;
   js.Steal(const_cast<const char**>(&output), &output_length);
-  TrimOutput(output, &output_length);
-  ASSERT(output_length >= 1);
   (*file_write)(output, output_length, file);
   // Free the stolen output.
   free(output);
-
-  const char* dart_events =
-      DartTimelineEventIterator::PrintTraceEvents(this,
-                                                  zone.GetZone(),
-                                                  NULL);
-
-  // If we wrote out vm events and have dart events, write out the comma.
-  if ((output_length > 1) && (dart_events != NULL)) {
-    // Write out the ',' character.
-    const char* comma = ",";
-    (*file_write)(comma, 1, file);
-  }
-
-  // Write out the Dart events.
-  if (dart_events != NULL) {
-    (*file_write)(dart_events, strlen(dart_events), file);
-  }
-
-  // Write out the ']' character.
-  const char* array_close = "]";
-  (*file_write)(array_close, 1, file);
   (*file_close)(file);
 
   return;
 }
 
 
-void TimelineEventRecorder::ReclaimGlobalBlock() {
-  MutexLocker ml(&lock_);
-  if (global_block_ != NULL) {
-    global_block_->Finish();
-    global_block_ = NULL;
-  }
-}
-
-
 int64_t TimelineEventRecorder::GetNextAsyncId() {
   // TODO(johnmccutchan): Gracefully handle wrap around.
   uint32_t next = static_cast<uint32_t>(
@@ -868,7 +774,7 @@
 
 TimelineEventBlock* TimelineEventRecorder::GetNewBlock() {
   MutexLocker ml(&lock_);
-  return GetNewBlockLocked(Isolate::Current());
+  return GetNewBlockLocked();
 }
 
 
@@ -876,10 +782,7 @@
     : blocks_(NULL),
       capacity_(capacity),
       num_blocks_(0),
-      block_cursor_(0),
-      dart_events_(NULL),
-      dart_events_capacity_(capacity),
-      dart_events_cursor_(0) {
+      block_cursor_(0) {
   // Capacity must be a multiple of TimelineEventBlock::kBlockSize
   ASSERT((capacity % TimelineEventBlock::kBlockSize) == 0);
   // Allocate blocks array.
@@ -895,13 +798,6 @@
   for (intptr_t i = 0; i < num_blocks_ - 1; i++) {
     blocks_[i]->set_next(blocks_[i + 1]);
   }
-  // Pre-allocate DartTimelineEvents.
-  dart_events_ =
-      reinterpret_cast<DartTimelineEvent**>(
-          calloc(dart_events_capacity_, sizeof(DartTimelineEvent*)));
-  for (intptr_t i = 0; i < dart_events_capacity_; i++) {
-    dart_events_[i] = new DartTimelineEvent();
-  }
 }
 
 
@@ -912,18 +808,13 @@
     delete block;
   }
   free(blocks_);
-  // Delete all DartTimelineEvents.
-  for (intptr_t i = 0; i < dart_events_capacity_; i++) {
-    DartTimelineEvent* event = dart_events_[i];
-    delete event;
-  }
-  free(dart_events_);
 }
 
 
 void TimelineEventRingRecorder::PrintJSONEvents(
     JSONArray* events,
-    TimelineEventFilter* filter) const {
+    TimelineEventFilter* filter) {
+  MutexLocker ml(&lock_);
   intptr_t block_offset = FindOldestBlockIndex();
   if (block_offset == -1) {
     // All blocks are empty.
@@ -947,7 +838,6 @@
 
 void TimelineEventRingRecorder::PrintJSON(JSONStream* js,
                                           TimelineEventFilter* filter) {
-  MutexLocker ml(&lock_);
   JSONObject topLevel(js);
   topLevel.AddProperty("type", "_Timeline");
   {
@@ -958,33 +848,6 @@
 }
 
 
-void TimelineEventRingRecorder::AppendDartEvent(Isolate* isolate,
-                                                const char* event) {
-  MutexLocker ml(&lock_);
-  // TODO(johnmccutchan): If locking becomes an issue, use the Isolate to store
-  // the events.
-  if (dart_events_cursor_ == dart_events_capacity_) {
-    dart_events_cursor_ = 0;
-  }
-  ASSERT(dart_events_[dart_events_cursor_] != NULL);
-  dart_events_[dart_events_cursor_]->Clear();
-  dart_events_[dart_events_cursor_]->Init(isolate, event);
-  dart_events_cursor_++;
-}
-
-
-intptr_t TimelineEventRingRecorder::NumDartEventsLocked() {
-  return dart_events_capacity_;
-}
-
-
-DartTimelineEvent* TimelineEventRingRecorder::DartEventAtLocked(intptr_t i) {
-  ASSERT(i >= 0);
-  ASSERT(i < dart_events_capacity_);
-  return dart_events_[i];
-}
-
-
 void TimelineEventRingRecorder::PrintTraceEvent(JSONStream* js,
                                                 TimelineEventFilter* filter) {
   JSONArray events(js);
@@ -997,8 +860,7 @@
 }
 
 
-TimelineEventBlock* TimelineEventRingRecorder::GetNewBlockLocked(
-    Isolate* isolate) {
+TimelineEventBlock* TimelineEventRingRecorder::GetNewBlockLocked() {
   // TODO(johnmccutchan): This function should only hand out blocks
   // which have been marked as finished.
   if (block_cursor_ == num_blocks_) {
@@ -1006,11 +868,20 @@
   }
   TimelineEventBlock* block = blocks_[block_cursor_++];
   block->Reset();
-  block->Open(isolate);
+  block->Open();
   return block;
 }
 
 
+void TimelineEventRingRecorder::Clear() {
+  MutexLocker ml(&lock_);
+  for (intptr_t i = 0; i < num_blocks_; i++) {
+    TimelineEventBlock* block = blocks_[i];
+    block->Reset();
+  }
+}
+
+
 intptr_t TimelineEventRingRecorder::FindOldestBlockIndex() const {
   int64_t earliest_time = kMaxInt64;
   intptr_t earliest_index = -1;
@@ -1033,10 +904,6 @@
   // Grab the current thread.
   Thread* thread = Thread::Current();
   ASSERT(thread != NULL);
-  if (thread->isolate() == NULL) {
-    // Non-isolate thread case. This should be infrequent.
-    return GlobalBlockStartEvent();
-  }
   return ThreadBlockStartEvent();
 }
 
@@ -1045,11 +912,7 @@
   if (event == NULL) {
     return;
   }
-  if (event->global_block()) {
-    GlobalBlockCompleteEvent(event);
-  } else {
-    ThreadBlockCompleteEvent(event);
-  }
+  ThreadBlockCompleteEvent(event);
 }
 
 
@@ -1079,25 +942,6 @@
 }
 
 
-void TimelineEventStreamingRecorder::AppendDartEvent(Isolate* isolate,
-                                                     const char* event) {
-  if (event != NULL) {
-    StreamDartEvent(event);
-  }
-}
-
-
-intptr_t TimelineEventStreamingRecorder::NumDartEventsLocked() {
-  return 0;
-}
-
-
-DartTimelineEvent* TimelineEventStreamingRecorder::DartEventAtLocked(
-    intptr_t i) {
-  return NULL;
-}
-
-
 TimelineEvent* TimelineEventStreamingRecorder::StartEvent() {
   TimelineEvent* event = new TimelineEvent();
   return event;
@@ -1112,16 +956,12 @@
 
 TimelineEventEndlessRecorder::TimelineEventEndlessRecorder()
     : head_(NULL),
-      block_index_(0),
-      dart_events_(NULL),
-      dart_events_capacity_(0),
-      dart_events_cursor_(0) {
+      block_index_(0) {
 }
 
 
 void TimelineEventEndlessRecorder::PrintJSON(JSONStream* js,
                                              TimelineEventFilter* filter) {
-  MutexLocker ml(&lock_);
   JSONObject topLevel(js);
   topLevel.AddProperty("type", "_Timeline");
   {
@@ -1140,31 +980,6 @@
 }
 
 
-void TimelineEventEndlessRecorder::AppendDartEvent(Isolate* isolate,
-                                                   const char* event) {
-  MutexLocker ml(&lock_);
-  // TODO(johnmccutchan): If locking becomes an issue, use the Isolate to store
-  // the events.
-  if (dart_events_cursor_ == dart_events_capacity_) {
-    // Grow.
-    intptr_t new_capacity =
-        (dart_events_capacity_ == 0) ? 16 : dart_events_capacity_ * 2;
-    dart_events_ = reinterpret_cast<DartTimelineEvent**>(
-        realloc(dart_events_, new_capacity * sizeof(DartTimelineEvent*)));
-    for (intptr_t i = dart_events_capacity_; i < new_capacity; i++) {
-      // Fill with NULLs.
-      dart_events_[i] = NULL;
-    }
-    dart_events_capacity_ = new_capacity;
-  }
-  ASSERT(dart_events_cursor_ < dart_events_capacity_);
-  DartTimelineEvent* dart_event = new DartTimelineEvent();
-  dart_event->Init(isolate, event);
-  ASSERT(dart_events_[dart_events_cursor_] == NULL);
-  dart_events_[dart_events_cursor_++] = dart_event;
-}
-
-
 TimelineEventBlock* TimelineEventEndlessRecorder::GetHeadBlockLocked() {
   return head_;
 }
@@ -1174,10 +989,6 @@
   // Grab the current thread.
   Thread* thread = Thread::Current();
   ASSERT(thread != NULL);
-  if (thread->isolate() == NULL) {
-    // Non-isolate thread case. This should be infrequent.
-    return GlobalBlockStartEvent();
-  }
   return ThreadBlockStartEvent();
 }
 
@@ -1186,50 +997,27 @@
   if (event == NULL) {
     return;
   }
-  if (event->global_block()) {
-    GlobalBlockCompleteEvent(event);
-  } else {
-    ThreadBlockCompleteEvent(event);
-  }
+  ThreadBlockCompleteEvent(event);
 }
 
 
-TimelineEventBlock* TimelineEventEndlessRecorder::GetNewBlockLocked(
-    Isolate* isolate) {
+TimelineEventBlock* TimelineEventEndlessRecorder::GetNewBlockLocked() {
   TimelineEventBlock* block = new TimelineEventBlock(block_index_++);
   block->set_next(head_);
-  block->Open(isolate);
+  block->Open();
   head_ = block;
   if (FLAG_trace_timeline) {
-    if (isolate != NULL) {
-      OS::Print("Created new isolate block %p for %s\n",
-                block, isolate->name());
-    } else {
-      OS::Print("Created new global block %p\n", block);
-    }
+    OS::Print("Created new block %p\n", block);
   }
   return head_;
 }
 
 
-intptr_t TimelineEventEndlessRecorder::NumDartEventsLocked() {
-  return dart_events_cursor_;
-}
-
-
-DartTimelineEvent* TimelineEventEndlessRecorder::DartEventAtLocked(
-    intptr_t i) {
-  ASSERT(i >= 0);
-  ASSERT(i < dart_events_cursor_);
-  return dart_events_[i];
-}
-
-
 void TimelineEventEndlessRecorder::PrintJSONEvents(
     JSONArray* events,
-    TimelineEventFilter* filter) const {
+    TimelineEventFilter* filter) {
+  MutexLocker ml(&lock_);
   TimelineEventBlock* current = head_;
-
   while (current != NULL) {
     if (!filter->IncludeBlock(current)) {
       current = current->next();
@@ -1266,7 +1054,7 @@
     : next_(NULL),
       length_(0),
       block_index_(block_index),
-      isolate_(NULL),
+      thread_id_(OSThread::kInvalidThreadId),
       in_use_(false) {
 }
 
@@ -1286,13 +1074,10 @@
 }
 
 
-ThreadId TimelineEventBlock::thread() const {
-  ASSERT(length_ > 0);
-  return events_[0].thread();
-}
-
-
 int64_t TimelineEventBlock::LowerTimeBound() const {
+  if (length_ == 0) {
+    return kMaxInt64;
+  }
   ASSERT(length_ > 0);
   return events_[0].TimeOrigin();
 }
@@ -1303,10 +1088,8 @@
     return true;
   }
 
-  // - events in the block come from one thread.
-  ThreadId tid = thread();
   for (intptr_t i = 0; i < length(); i++) {
-    if (At(i)->thread() != tid) {
+    if (At(i)->thread() != thread_id()) {
       return false;
     }
   }
@@ -1330,13 +1113,13 @@
     events_[i].Reset();
   }
   length_ = 0;
-  isolate_ = NULL;
+  thread_id_ = OSThread::kInvalidThreadId;
   in_use_ = false;
 }
 
 
-void TimelineEventBlock::Open(Isolate* isolate) {
-  isolate_ = isolate;
+void TimelineEventBlock::Open() {
+  thread_id_ = OSThread::GetCurrentThreadTraceId();
   in_use_ = true;
 }
 
@@ -1392,80 +1175,4 @@
   return r;
 }
 
-
-DartTimelineEventIterator::DartTimelineEventIterator(
-    TimelineEventRecorder* recorder)
-    : cursor_(0),
-      num_events_(0),
-      recorder_(NULL) {
-  Reset(recorder);
-}
-
-
-DartTimelineEventIterator::~DartTimelineEventIterator() {
-  Reset(NULL);
-}
-
-
-void DartTimelineEventIterator::Reset(TimelineEventRecorder* recorder) {
-  // Clear state.
-  cursor_ = 0;
-  num_events_ = 0;
-  if (recorder_ != NULL) {
-    // Unlock old recorder.
-    recorder_->lock_.Unlock();
-  }
-  recorder_ = recorder;
-  if (recorder_ == NULL) {
-    return;
-  }
-  // Lock new recorder.
-  recorder_->lock_.Lock();
-  cursor_ = 0;
-  num_events_ = recorder_->NumDartEventsLocked();
-}
-
-
-bool DartTimelineEventIterator::HasNext() const {
-  return cursor_ < num_events_;
-}
-
-
-DartTimelineEvent* DartTimelineEventIterator::Next() {
-  ASSERT(cursor_ < num_events_);
-  DartTimelineEvent* r = recorder_->DartEventAtLocked(cursor_);
-  cursor_++;
-  return r;
-}
-
-const char* DartTimelineEventIterator::PrintTraceEvents(
-    TimelineEventRecorder* recorder,
-    Zone* zone,
-    Isolate* isolate) {
-  if (recorder == NULL) {
-    return NULL;
-  }
-
-  if (zone == NULL) {
-    return NULL;
-  }
-
-  char* result = NULL;
-  DartTimelineEventIterator iterator(recorder);
-  while (iterator.HasNext()) {
-    DartTimelineEvent* event = iterator.Next();
-    if (!event->IsValid()) {
-      // Skip invalid
-      continue;
-    }
-    if ((isolate != NULL) && (isolate != event->isolate())) {
-      // If an isolate was specified, skip events from other isolates.
-      continue;
-    }
-    ASSERT(event->event_as_json() != NULL);
-    result = zone->ConcatStrings(result, event->event_as_json());
-  }
-  return result;
-}
-
 }  // namespace dart
diff --git a/runtime/vm/timeline.h b/runtime/vm/timeline.h
index 82ceb18..1c61814 100644
--- a/runtime/vm/timeline.h
+++ b/runtime/vm/timeline.h
@@ -30,6 +30,7 @@
   V(API, false)                                                                \
   V(Compiler, false)                                                           \
   V(Dart, false)                                                               \
+  V(Debugger, false)                                                           \
   V(Embedder, false)                                                           \
   V(GC, false)                                                                 \
   V(Isolate, false)                                                            \
@@ -49,12 +50,10 @@
 
   static TimelineStream* GetVMStream();
 
-  // Reclaim all |TimelineEventBlock|s that are owned by the current isolate.
-  static void ReclaimIsolateBlocks();
+  // Reclaim all |TimelineEventBlocks|s that are cached by threads.
+  static void ReclaimCachedBlocksFromThreads();
 
-  // Reclaim all |TimelineEventBlocks|s that are owned by all isolates and
-  // the global block owned by the VM.
-  static void ReclaimAllBlocks();
+  static void Clear();
 
 #define ISOLATE_TIMELINE_STREAM_FLAGS(name, not_used)                          \
   static const bool* Stream##name##EnabledFlag() {                             \
@@ -67,8 +66,6 @@
 #undef ISOLATE_TIMELINE_STREAM_FLAGS
 
  private:
-  static void ReclaimBlocksForIsolate(Isolate* isolate);
-
   static TimelineEventRecorder* recorder_;
   static TimelineStream* vm_stream_;
 
@@ -94,6 +91,7 @@
   // Keep in sync with StateBits below.
   enum EventType {
     kNone,
+    kSerializedJSON,  // Events from Dart code.
     kBegin,
     kEnd,
     kDuration,
@@ -136,9 +134,11 @@
   void End(const char* label,
            int64_t micros = OS::GetCurrentTraceMicros());
 
+  void SerializedJSON(const char* json);
+
   // Set the number of arguments in the event.
   void SetNumArguments(intptr_t length);
-  // |name| must be a compile time constant. Takes ownership of |argumentp|.
+  // |name| must be a compile time constant. Takes ownership of |argument|.
   void SetArgument(intptr_t i, const char* name, char* argument);
   // |name| must be a compile time constant. Copies |argument|.
   void CopyArgument(intptr_t i, const char* name, const char* argument);
@@ -174,6 +174,10 @@
     return thread_;
   }
 
+  Dart_Port isolate_id() const {
+    return isolate_id_;
+  }
+
   const char* label() const {
     return label_;
   }
@@ -229,6 +233,8 @@
     }
   }
 
+  const char* GetSerializedJSON() const;
+
  private:
   int64_t timestamp0_;
   int64_t timestamp1_;
@@ -238,7 +244,7 @@
   const char* label_;
   const char* category_;
   ThreadId thread_;
-  Isolate* isolate_;
+  Dart_Port isolate_id_;
 
   void FreeArguments();
 
@@ -251,23 +257,12 @@
     state_ = EventTypeField::update(event_type, state_);
   }
 
-  void set_global_block(bool global_block) {
-    state_ = GlobalBlockField::update(global_block, state_);
-  }
-
-  bool global_block() const {
-    return GlobalBlockField::decode(state_);
-  }
-
   enum StateBits {
     kEventTypeBit = 0,  // reserve 4 bits for type.
-    // Was this event allocated from the global block?
-    kGlobalBlockBit = 4,
-    kNextBit = 5,
+    kNextBit = 4,
   };
 
   class EventTypeField : public BitField<EventType, kEventTypeBit, 4> {};
-  class GlobalBlockField : public BitField<bool, kGlobalBlockBit, 1> {};
 
   friend class TimelineEventRecorder;
   friend class TimelineEventEndlessRecorder;
@@ -413,8 +408,6 @@
     return &events_[index];
   }
 
-  // Attempt to sniff a thread id from the first event.
-  ThreadId thread() const;
   // Attempt to sniff the timestamp from the first event.
   int64_t LowerTimeBound() const;
 
@@ -432,8 +425,8 @@
   }
 
   // Only safe to access under the recorder's lock.
-  Isolate* isolate() const {
-    return isolate_;
+  ThreadId thread_id() const {
+    return thread_id_;
   }
 
  protected:
@@ -445,10 +438,10 @@
   intptr_t block_index_;
 
   // Only accessed under the recorder's lock.
-  Isolate* isolate_;
+  ThreadId thread_id_;
   bool in_use_;
 
-  void Open(Isolate* isolate);
+  void Open();
   void Finish();
 
   friend class Thread;
@@ -489,52 +482,23 @@
 
 class IsolateTimelineEventFilter : public TimelineEventFilter {
  public:
-  explicit IsolateTimelineEventFilter(Isolate* isolate);
+  explicit IsolateTimelineEventFilter(Dart_Port isolate_id);
 
   bool IncludeBlock(TimelineEventBlock* block) {
     if (block == NULL) {
       return false;
     }
     // Not empty, not in use, and isolate match.
-    return !block->IsEmpty() && !block->in_use() &&
-           (block->isolate() == isolate_);
+    return !block->IsEmpty() && !block->in_use();
+  }
+
+  bool IncludeEvent(TimelineEvent* event) {
+    return event->IsValid() &&
+           (event->isolate_id() == isolate_id_);
   }
 
  private:
-  Isolate* isolate_;
-};
-
-
-// Timeline events from Dart code are eagerly converted to JSON and stored
-// as a C string.
-class DartTimelineEvent {
- public:
-  DartTimelineEvent();
-  ~DartTimelineEvent();
-
-  void Clear();
-
-  // This function makes a copy of |event|.
-  void Init(Isolate* isolate, const char* event);
-
-  bool IsValid() const {
-    return (isolate_ != NULL) &&
-           (event_as_json_ != NULL);
-  }
-
-  Isolate* isolate() const {
-    return isolate_;
-  }
-
-  char* event_as_json() const {
-    return event_as_json_;
-  }
-
- private:
-  Isolate* isolate_;
-  char* event_as_json_;
-
-  DISALLOW_COPY_AND_ASSIGN(DartTimelineEvent);
+  Dart_Port isolate_id_;
 };
 
 
@@ -554,9 +518,6 @@
 
   void FinishBlock(TimelineEventBlock* block);
 
-  // Interface method(s) which must be implemented.
-  virtual void AppendDartEvent(Isolate* isolate, const char* event) = 0;
-
  protected:
   void WriteTo(const char* directory);
 
@@ -564,25 +525,17 @@
   virtual TimelineEvent* StartEvent() = 0;
   virtual void CompleteEvent(TimelineEvent* event) = 0;
   virtual TimelineEventBlock* GetHeadBlockLocked() = 0;
-  virtual TimelineEventBlock* GetNewBlockLocked(Isolate* isolate) = 0;
-  virtual intptr_t NumDartEventsLocked() = 0;
-  virtual DartTimelineEvent* DartEventAtLocked(intptr_t i) = 0;
+  virtual TimelineEventBlock* GetNewBlockLocked() = 0;
+  virtual void Clear() = 0;
 
   // Utility method(s).
   void PrintJSONMeta(JSONArray* array) const;
   TimelineEvent* ThreadBlockStartEvent();
-  TimelineEvent* GlobalBlockStartEvent();
   void ThreadBlockCompleteEvent(TimelineEvent* event);
-  void GlobalBlockCompleteEvent(TimelineEvent* event);
 
   Mutex lock_;
-  // Only accessed under |lock_|.
-  TimelineEventBlock* global_block_;
-  void ReclaimGlobalBlock();
-
   uintptr_t async_id_;
 
-  friend class DartTimelineEventIterator;
   friend class TimelineEvent;
   friend class TimelineEventBlockIterator;
   friend class TimelineStream;
@@ -605,27 +558,20 @@
   void PrintJSON(JSONStream* js, TimelineEventFilter* filter);
   void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter);
 
-  void AppendDartEvent(Isolate* isolate, const char* event);
-
  protected:
   TimelineEvent* StartEvent();
   void CompleteEvent(TimelineEvent* event);
   TimelineEventBlock* GetHeadBlockLocked();
   intptr_t FindOldestBlockIndex() const;
-  TimelineEventBlock* GetNewBlockLocked(Isolate* isolate);
-  intptr_t NumDartEventsLocked();
-  DartTimelineEvent* DartEventAtLocked(intptr_t i);
+  TimelineEventBlock* GetNewBlockLocked();
+  void Clear();
 
-  void PrintJSONEvents(JSONArray* array, TimelineEventFilter* filter) const;
+  void PrintJSONEvents(JSONArray* array, TimelineEventFilter* filter);
 
   TimelineEventBlock** blocks_;
   intptr_t capacity_;
   intptr_t num_blocks_;
   intptr_t block_cursor_;
-
-  DartTimelineEvent** dart_events_;
-  intptr_t dart_events_capacity_;
-  intptr_t dart_events_cursor_;
 };
 
 
@@ -638,22 +584,19 @@
   void PrintJSON(JSONStream* js, TimelineEventFilter* filter);
   void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter);
 
-  void AppendDartEvent(Isolate* isolate, const char* event);
-
   // Called when |event| is ready to be streamed. It is unsafe to keep a
   // reference to |event| as it may be freed as soon as this function returns.
   virtual void StreamEvent(TimelineEvent* event) = 0;
-  virtual void StreamDartEvent(const char* event) = 0;
 
  protected:
-  TimelineEventBlock* GetNewBlockLocked(Isolate* isolate) {
+  TimelineEventBlock* GetNewBlockLocked() {
     return NULL;
   }
   TimelineEventBlock* GetHeadBlockLocked() {
     return NULL;
   }
-  intptr_t NumDartEventsLocked();
-  DartTimelineEvent* DartEventAtLocked(intptr_t i);
+  void Clear() {
+  }
   TimelineEvent* StartEvent();
   void CompleteEvent(TimelineEvent* event);
 };
@@ -669,28 +612,18 @@
   void PrintJSON(JSONStream* js, TimelineEventFilter* filter);
   void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter);
 
-  void AppendDartEvent(Isolate* isolate, const char* event);
-
  protected:
   TimelineEvent* StartEvent();
   void CompleteEvent(TimelineEvent* event);
-  TimelineEventBlock* GetNewBlockLocked(Isolate* isolate);
+  TimelineEventBlock* GetNewBlockLocked();
   TimelineEventBlock* GetHeadBlockLocked();
-  intptr_t NumDartEventsLocked();
-  DartTimelineEvent* DartEventAtLocked(intptr_t i);
-
-  void PrintJSONEvents(JSONArray* array, TimelineEventFilter* filter) const;
-
-  // Useful only for testing. Only works for one thread.
   void Clear();
 
+  void PrintJSONEvents(JSONArray* array, TimelineEventFilter* filter);
+
   TimelineEventBlock* head_;
   intptr_t block_index_;
 
-  DartTimelineEvent** dart_events_;
-  intptr_t dart_events_capacity_;
-  intptr_t dart_events_cursor_;
-
   friend class TimelineTestHelper;
 };
 
@@ -715,32 +648,6 @@
 };
 
 
-// An iterator for timeline events.
-class DartTimelineEventIterator {
- public:
-  explicit DartTimelineEventIterator(TimelineEventRecorder* recorder);
-  ~DartTimelineEventIterator();
-
-  void Reset(TimelineEventRecorder* recorder);
-
-  // Returns true if there is another event.
-  bool HasNext() const;
-
-  // Returns the next event and moves forward.
-  DartTimelineEvent* Next();
-
-  // Returns a zone allocated string of all trace events for isolate.
-  // If isolate is NULL, all isolates' events will be included.
-  static const char* PrintTraceEvents(TimelineEventRecorder* recorder,
-                                      Zone* zone,
-                                      Isolate* isolate);
-
- private:
-  intptr_t cursor_;
-  intptr_t num_events_;
-  TimelineEventRecorder* recorder_;
-};
-
 }  // namespace dart
 
 #endif  // VM_TIMELINE_H_
diff --git a/runtime/vm/timeline_analysis.cc b/runtime/vm/timeline_analysis.cc
index faf2f5e..8a7c6fb 100644
--- a/runtime/vm/timeline_analysis.cc
+++ b/runtime/vm/timeline_analysis.cc
@@ -162,10 +162,6 @@
       // Skip empty blocks.
       continue;
     }
-    if (block->isolate() != isolate_) {
-      // Skip blocks for other isolates.
-      continue;
-    }
     if (!block->CheckBlock()) {
       if (FLAG_trace_timeline_analysis) {
         THR_Print("DiscoverThreads block %" Pd " "
@@ -175,7 +171,7 @@
                "TimelineEventBlock::CheckBlock", block->block_index());
       return;
     }
-    TimelineAnalysisThread* thread = GetOrAddThread(block->thread());
+    TimelineAnalysisThread* thread = GetOrAddThread(block->thread_id());
     ASSERT(thread != NULL);
     thread->AddBlock(block);
   }
@@ -347,6 +343,10 @@
   intptr_t event_count = 0;
   while (!has_error() && it.HasNext()) {
     TimelineEvent* event = it.Next();
+    if (event->isolate_id() != isolate_->main_port()) {
+      // Skip events that do not belong to the isolate.
+      continue;
+    }
     if (event->IsFinishedDuration()) {
       int64_t start = event->TimeOrigin();
       PopFinishedDurations(start);
diff --git a/runtime/vm/timeline_test.cc b/runtime/vm/timeline_test.cc
index 17fea5d..00fc839 100644
--- a/runtime/vm/timeline_test.cc
+++ b/runtime/vm/timeline_test.cc
@@ -51,6 +51,11 @@
     }
   }
 
+  static void SetBlockThread(TimelineEventBlock* block,
+                             intptr_t ftid) {
+    block->thread_id_ = OSThread::ThreadIdFromIntPtr(ftid);
+  }
+
   static void FakeDuration(
       TimelineEventRecorder* recorder,
       const char* label,
@@ -242,10 +247,6 @@
     counts_[event->event_type()]++;
   }
 
-  void StreamDartEvent(const char* event) {
-    // NOOP.
-  }
-
   intptr_t CountFor(TimelineEvent::EventType type) {
     return counts_[type];
   }
@@ -324,12 +325,17 @@
   ASSERT(recorder != NULL);
   // Blocks owned by thread "1".
   TimelineEventBlock* block_1_0 = recorder->GetNewBlock();
+  TimelineTestHelper::SetBlockThread(block_1_0, 1);
   TimelineEventBlock* block_1_1 = recorder->GetNewBlock();
+  TimelineTestHelper::SetBlockThread(block_1_1, 1);
   TimelineEventBlock* block_1_2 = recorder->GetNewBlock();
+  TimelineTestHelper::SetBlockThread(block_1_2, 1);
   // Blocks owned by thread "2".
   TimelineEventBlock* block_2_0 = recorder->GetNewBlock();
+  TimelineTestHelper::SetBlockThread(block_2_0, 2);
   // Blocks owned by thread "3".
   TimelineEventBlock* block_3_0 = recorder->GetNewBlock();
+  TimelineTestHelper::SetBlockThread(block_3_0, 3);
   USE(block_3_0);
 
   // Add events to each block for thread 1.
@@ -358,6 +364,7 @@
   // Discover threads in recorder.
   TimelineAnalysis ta(zone, isolate, recorder);
   ta.BuildThreads();
+  EXPECT(!ta.has_error());
   // block_3_0 is never used by a thread, so we only have two threads.
   EXPECT_EQ(2, ta.NumThreads());
 
diff --git a/runtime/vm/timer.h b/runtime/vm/timer.h
index 4738efa..e4ee890 100644
--- a/runtime/vm/timer.h
+++ b/runtime/vm/timer.h
@@ -108,13 +108,6 @@
     Init();
   }
 
-  TimerScope(bool flag, Timer* timer, Isolate* isolate = NULL)
-      : StackResource(isolate),
-        nested_(false),
-        timer_(flag ? timer : NULL) {
-    Init();
-  }
-
   void Init() {
     if (timer_ != NULL) {
       if (!timer_->running()) {
diff --git a/runtime/vm/virtual_memory.cc b/runtime/vm/virtual_memory.cc
index 2f2c1bc..1ad6c06 100644
--- a/runtime/vm/virtual_memory.cc
+++ b/runtime/vm/virtual_memory.cc
@@ -33,7 +33,9 @@
   // Memory for precompilated instructions was allocated by the embedder, so
   // create a VirtualMemory without allocating.
   MemoryRegion region(pointer, size);
-  return new VirtualMemory(region);
+  VirtualMemory* memory = new VirtualMemory(region);
+  memory->embedder_allocated_ = true;
+  return memory;
 }
 
 }  // namespace dart
diff --git a/runtime/vm/virtual_memory.h b/runtime/vm/virtual_memory.h
index 44f3491..53ba57d 100644
--- a/runtime/vm/virtual_memory.h
+++ b/runtime/vm/virtual_memory.h
@@ -69,6 +69,8 @@
   // Commit a reserved memory area, so that the memory can be accessed.
   bool Commit(uword addr, intptr_t size, bool is_executable);
 
+  bool embedder_allocated() const { return embedder_allocated_; }
+
   static VirtualMemory* ForInstructionsSnapshot(void* pointer, uword size);
 
  private:
@@ -82,7 +84,8 @@
   // It does not reserve any virtual address space on its own.
   explicit VirtualMemory(const MemoryRegion& region) :
       region_(region.pointer(), region.size()),
-      reserved_size_(region.size()) { }
+      reserved_size_(region.size()),
+      embedder_allocated_(false) { }
 
   MemoryRegion region_;
 
@@ -92,6 +95,9 @@
 
   static uword page_size_;
 
+  // True for a region provided by the embedder.
+  bool embedder_allocated_;
+
   DISALLOW_IMPLICIT_CONSTRUCTORS(VirtualMemory);
 };
 
diff --git a/runtime/vm/virtual_memory_android.cc b/runtime/vm/virtual_memory_android.cc
index b7de39b..0e0c1b2 100644
--- a/runtime/vm/virtual_memory_android.cc
+++ b/runtime/vm/virtual_memory_android.cc
@@ -53,7 +53,9 @@
 
 
 VirtualMemory::~VirtualMemory() {
-  unmap(address(), reserved_size_);
+  if (!embedder_allocated()) {
+    unmap(address(), reserved_size_);
+  }
 }
 
 
diff --git a/runtime/vm/virtual_memory_linux.cc b/runtime/vm/virtual_memory_linux.cc
index 3661fb5..275c0c6 100644
--- a/runtime/vm/virtual_memory_linux.cc
+++ b/runtime/vm/virtual_memory_linux.cc
@@ -8,7 +8,6 @@
 #include "vm/virtual_memory.h"
 
 #include <sys/mman.h>  // NOLINT
-#include <sys/unistd.h>  // NOLINT
 #include <unistd.h>  // NOLINT
 
 #include "platform/assert.h"
@@ -53,7 +52,9 @@
 
 
 VirtualMemory::~VirtualMemory() {
-  unmap(address(), reserved_size_);
+  if (!embedder_allocated()) {
+    unmap(address(), reserved_size_);
+  }
 }
 
 
diff --git a/runtime/vm/virtual_memory_macos.cc b/runtime/vm/virtual_memory_macos.cc
index 331ac4b..f28da35 100644
--- a/runtime/vm/virtual_memory_macos.cc
+++ b/runtime/vm/virtual_memory_macos.cc
@@ -53,7 +53,9 @@
 
 
 VirtualMemory::~VirtualMemory() {
-  unmap(address(), reserved_size_);
+  if (!embedder_allocated()) {
+    unmap(address(), reserved_size_);
+  }
 }
 
 
diff --git a/runtime/vm/virtual_memory_win.cc b/runtime/vm/virtual_memory_win.cc
index 1000417..dd154ac 100644
--- a/runtime/vm/virtual_memory_win.cc
+++ b/runtime/vm/virtual_memory_win.cc
@@ -33,7 +33,7 @@
 
 
 VirtualMemory::~VirtualMemory() {
-  if (reserved_size_ == 0) {
+  if (embedder_allocated() || (reserved_size_ == 0)) {
     return;
   }
   if (VirtualFree(address(), 0, MEM_RELEASE) == 0) {
diff --git a/runtime/vm/vm_sources.gypi b/runtime/vm/vm_sources.gypi
index 5f5fc57..228abcb 100644
--- a/runtime/vm/vm_sources.gypi
+++ b/runtime/vm/vm_sources.gypi
@@ -451,7 +451,6 @@
     'thread_interrupter_android.cc',
     'thread_interrupter_linux.cc',
     'thread_interrupter_macos.cc',
-    'thread_interrupter_test.cc',
     'thread_interrupter_win.cc',
     'thread_pool.cc',
     'thread_pool.h',
diff --git a/runtime/vm/weak_code.cc b/runtime/vm/weak_code.cc
index cf1e132..e642204 100644
--- a/runtime/vm/weak_code.cc
+++ b/runtime/vm/weak_code.cc
@@ -57,6 +57,7 @@
 
 
 void WeakCodeReferences::DisableCode() {
+  IncrementInvalidationGen();
   const Array& code_objects = Array::Handle(array_.raw());
   if (code_objects.IsNull()) {
     return;
diff --git a/runtime/vm/weak_code.h b/runtime/vm/weak_code.h
index 809d3f8..4529806 100644
--- a/runtime/vm/weak_code.h
+++ b/runtime/vm/weak_code.h
@@ -25,6 +25,7 @@
   virtual void UpdateArrayTo(const Array& array) = 0;
   virtual void ReportDeoptimization(const Code& code) = 0;
   virtual void ReportSwitchingCode(const Code& code) = 0;
+  virtual void IncrementInvalidationGen() = 0;
 
   static bool IsOptimizedCode(const Array& dependent_code, const Code& code);
 
diff --git a/runtime/vm/zone.cc b/runtime/vm/zone.cc
index 7cb7977..4f9a484 100644
--- a/runtime/vm/zone.cc
+++ b/runtime/vm/zone.cc
@@ -9,7 +9,6 @@
 #include "vm/flags.h"
 #include "vm/handles_impl.h"
 #include "vm/heap.h"
-#include "vm/isolate.h"
 #include "vm/os.h"
 
 namespace dart {
diff --git a/sdk/lib/_internal/js_runtime/lib/async_patch.dart b/sdk/lib/_internal/js_runtime/lib/async_patch.dart
index 1155e79..4d91d79 100644
--- a/sdk/lib/_internal/js_runtime/lib/async_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/async_patch.dart
@@ -11,6 +11,7 @@
     convertDartClosureToJS,
     getTraceFromException,
     requiresPreamble,
+    wrapException,
     unwrapException;
 import 'dart:_isolate_helper' show
     IsolateNatives,
@@ -27,11 +28,11 @@
 class _AsyncRun {
   @patch
   static void _scheduleImmediate(void callback()) {
-    scheduleImmediateClosure(callback);
+    _scheduleImmediateClosure(callback);
   }
 
   // Lazily initialized.
-  static final Function scheduleImmediateClosure =
+  static final Function _scheduleImmediateClosure =
       _initializeScheduleImmediate();
 
   static Function _initializeScheduleImmediate() {
@@ -195,22 +196,28 @@
 typedef void _WrappedAsyncBody(int errorCode, dynamic result);
 
 _WrappedAsyncBody _wrapJsFunctionForAsync(dynamic /* js function */ function) {
-  var protected = JS('', """
-    // Invokes [function] with [errorCode] and [result].
-    //
-    // If (and as long as) the invocation throws, calls [function] again,
-    // with an error-code.
-    function(errorCode, result) {
-      while (true) {
-        try {
-          #(errorCode, result);
-          break;
-        } catch (error) {
-          result = error;
-          errorCode = #;
-        }
-      }
-    }""", function, async_error_codes.ERROR);
+  var protected = JS(
+      '',
+      """
+        (function (fn, ERROR) {
+          // Invokes [function] with [errorCode] and [result].
+          //
+          // If (and as long as) the invocation throws, calls [function] again,
+          // with an error-code.
+          return function(errorCode, result) {
+            while (true) {
+              try {
+                fn(errorCode, result);
+                break;
+              } catch (error) {
+                result = error;
+                errorCode = ERROR;
+              }
+            }
+          }
+        })(#, #)""",
+      function, async_error_codes.ERROR);
+
   return Zone.current.registerBinaryCallback((int errorCode, dynamic result) {
     JS('', '#(#, #)', protected, errorCode, result);
   });
@@ -444,22 +451,25 @@
   _SyncStarIterator(this._body);
 
   _runBody() {
-    return JS('', '''
-// Invokes [body] with [errorCode] and [result].
-//
-// If (and as long as) the invocation throws, calls [function] again,
-// with an error-code.
-(function(body) {
-  var errorValue, errorCode = #;
-  while (true) {
-    try {
-      return body(errorCode, errorValue);
-    } catch (error) {
-      errorValue = error;
-      errorCode = #
-    }
-  }
-})(#)''', async_error_codes.SUCCESS, async_error_codes.ERROR, _body);
+    // TODO(sra): Find a way to hard-wire SUCCESS and ERROR codes.
+    return JS('',
+        '''
+        // Invokes [body] with [errorCode] and [result].
+        //
+        // If (and as long as) the invocation throws, calls [function] again,
+        // with an error-code.
+        (function(body, SUCCESS, ERROR) {
+          var errorValue, errorCode = SUCCESS;
+          while (true) {
+            try {
+              return body(errorCode, errorValue);
+            } catch (error) {
+              errorValue = error;
+              errorCode = ERROR;
+            }
+          }
+        })(#, #, #)''',
+        _body, async_error_codes.SUCCESS, async_error_codes.ERROR);
   }
 
 
@@ -509,5 +519,7 @@
 
 @patch
 void _rethrow(Object error, StackTrace stackTrace) {
-  throw new AsyncError(error, stackTrace);
+  error = wrapException(error);
+  JS("void", "#.stack = #", error, stackTrace.toString());
+  JS("void", "throw #", error);
 }
diff --git a/sdk/lib/_internal/js_runtime/lib/collection_patch.dart b/sdk/lib/_internal/js_runtime/lib/collection_patch.dart
index 74582ba..7d15ab8 100644
--- a/sdk/lib/_internal/js_runtime/lib/collection_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/collection_patch.dart
@@ -76,7 +76,7 @@
   bool get isNotEmpty => !isEmpty;
 
   Iterable<K> get keys {
-    return new HashMapKeyIterable<K>(this);
+    return new _HashMapKeyIterable<K>(this);
   }
 
   Iterable<V> get values {
@@ -431,16 +431,16 @@
   String toString() => Maps.mapToString(this);
 }
 
-class HashMapKeyIterable<E> extends Iterable<E>
-                            implements EfficientLength {
+class _HashMapKeyIterable<E> extends Iterable<E>
+                             implements EfficientLength {
   final _map;
-  HashMapKeyIterable(this._map);
+  _HashMapKeyIterable(this._map);
 
   int get length => _map._length;
   bool get isEmpty => _map._length == 0;
 
   Iterator<E> get iterator {
-    return new HashMapKeyIterator<E>(_map, _map._computeKeys());
+    return new _HashMapKeyIterator<E>(_map, _map._computeKeys());
   }
 
   bool contains(Object element) {
@@ -458,13 +458,13 @@
   }
 }
 
-class HashMapKeyIterator<E> implements Iterator<E> {
+class _HashMapKeyIterator<E> implements Iterator<E> {
   final _map;
   final List _keys;
   int _offset = 0;
   E _current;
 
-  HashMapKeyIterator(this._map, this._keys);
+  _HashMapKeyIterator(this._map, this._keys);
 
   E get current => _current;
 
@@ -849,7 +849,7 @@
 
   // Iterable.
   Iterator<E> get iterator {
-    return new HashSetIterator<E>(this, _computeElements());
+    return new _HashSetIterator<E>(this, _computeElements());
   }
 
   int get length => _length;
@@ -1160,14 +1160,14 @@
   }
 }
 
-// TODO(kasperl): Share this code with HashMapKeyIterator<E>?
-class HashSetIterator<E> implements Iterator<E> {
+// TODO(kasperl): Share this code with _HashMapKeyIterator<E>?
+class _HashSetIterator<E> implements Iterator<E> {
   final _set;
   final List _elements;
   int _offset = 0;
   E _current;
 
-  HashSetIterator(this._set, this._elements);
+  _HashSetIterator(this._set, this._elements);
 
   E get current => _current;
 
@@ -1244,8 +1244,8 @@
 
   // The elements are stored in cells that are linked together
   // to form a double linked list.
-  LinkedHashSetCell _first;
-  LinkedHashSetCell _last;
+  _LinkedHashSetCell _first;
+  _LinkedHashSetCell _last;
 
   // We track the number of modifications done to the element set to
   // be able to throw when the set is modified while being iterated
@@ -1262,7 +1262,7 @@
 
   // Iterable.
   Iterator<E> get iterator {
-    return new LinkedHashSetIterator(this, _modifications);
+    return new _LinkedHashSetIterator(this, _modifications);
   }
 
   int get length => _length;
@@ -1273,12 +1273,12 @@
     if (_isStringElement(object)) {
       var strings = _strings;
       if (strings == null) return false;
-      LinkedHashSetCell cell = _getTableEntry(strings, object);
+      _LinkedHashSetCell cell = _getTableEntry(strings, object);
       return cell != null;
     } else if (_isNumericElement(object)) {
       var nums = _nums;
       if (nums == null) return false;
-      LinkedHashSetCell cell = _getTableEntry(nums, object);
+      _LinkedHashSetCell cell = _getTableEntry(nums, object);
       return cell != null;
     } else {
       return _contains(object);
@@ -1310,7 +1310,7 @@
   }
 
   void forEach(void action(E element)) {
-    LinkedHashSetCell cell = _first;
+    _LinkedHashSetCell cell = _first;
     int modifications = _modifications;
     while (cell != null) {
       action(cell._element);
@@ -1352,12 +1352,12 @@
     var hash = _computeHashCode(element);
     var bucket = JS('var', '#[#]', rest, hash);
     if (bucket == null) {
-      LinkedHashSetCell cell = _newLinkedCell(element);
+      _LinkedHashSetCell cell = _newLinkedCell(element);
       _setTableEntry(rest, hash, JS('var', '[#]', cell));
     } else {
       int index = _findBucketIndex(bucket, element);
       if (index >= 0) return false;
-      LinkedHashSetCell cell = _newLinkedCell(element);
+      _LinkedHashSetCell cell = _newLinkedCell(element);
       JS('void', '#.push(#)', bucket, cell);
     }
     return true;
@@ -1381,7 +1381,7 @@
     if (index < 0) return false;
     // Use splice to remove the [cell] element at the index and
     // unlink it.
-    LinkedHashSetCell cell = JS('var', '#.splice(#, 1)[0]', bucket, index);
+    _LinkedHashSetCell cell = JS('var', '#.splice(#, 1)[0]', bucket, index);
     _unlinkCell(cell);
     return true;
   }
@@ -1395,10 +1395,10 @@
   }
 
   void _filterWhere(bool test(E element), bool removeMatching) {
-    LinkedHashSetCell cell = _first;
+    _LinkedHashSetCell cell = _first;
     while (cell != null) {
       E element = cell._element;
-      LinkedHashSetCell next = cell._next;
+      _LinkedHashSetCell next = cell._next;
       int modifications = _modifications;
       bool shouldRemove = (removeMatching == test(element));
       if (modifications != _modifications) {
@@ -1418,7 +1418,7 @@
   }
 
   bool _addHashTableEntry(var table, E element) {
-    LinkedHashSetCell cell = _getTableEntry(table, element);
+    _LinkedHashSetCell cell = _getTableEntry(table, element);
     if (cell != null) return false;
     _setTableEntry(table, element, _newLinkedCell(element));
     return true;
@@ -1426,7 +1426,7 @@
 
   bool _removeHashTableEntry(var table, Object element) {
     if (table == null) return false;
-    LinkedHashSetCell cell = _getTableEntry(table, element);
+    _LinkedHashSetCell cell = _getTableEntry(table, element);
     if (cell == null) return false;
     _unlinkCell(cell);
     _deleteTableEntry(table, element);
@@ -1441,12 +1441,12 @@
   }
 
   // Create a new cell and link it in as the last one in the list.
-  LinkedHashSetCell _newLinkedCell(E element) {
-    LinkedHashSetCell cell = new LinkedHashSetCell(element);
+  _LinkedHashSetCell _newLinkedCell(E element) {
+    _LinkedHashSetCell cell = new _LinkedHashSetCell(element);
     if (_first == null) {
       _first = _last = cell;
     } else {
-      LinkedHashSetCell last = _last;
+      _LinkedHashSetCell last = _last;
       cell._previous = last;
       _last = last._next = cell;
     }
@@ -1456,9 +1456,9 @@
   }
 
   // Unlink the given cell from the linked list of cells.
-  void _unlinkCell(LinkedHashSetCell cell) {
-    LinkedHashSetCell previous = cell._previous;
-    LinkedHashSetCell next = cell._next;
+  void _unlinkCell(_LinkedHashSetCell cell) {
+    _LinkedHashSetCell previous = cell._previous;
+    _LinkedHashSetCell next = cell._next;
     if (previous == null) {
       assert(cell == _first);
       _first = next;
@@ -1517,7 +1517,7 @@
     if (bucket == null) return -1;
     int length = JS('int', '#.length', bucket);
     for (int i = 0; i < length; i++) {
-      LinkedHashSetCell cell = JS('var', '#[#]', bucket, i);
+      _LinkedHashSetCell cell = JS('var', '#[#]', bucket, i);
       if (cell._element == element) return i;
     }
     return -1;
@@ -1551,7 +1551,7 @@
     if (bucket == null) return -1;
     int length = JS('int', '#.length', bucket);
     for (int i = 0; i < length; i++) {
-      LinkedHashSetCell cell = JS('var', '#[#]', bucket, i);
+      _LinkedHashSetCell cell = JS('var', '#[#]', bucket, i);
       if (identical(cell._element, element)) return i;
     }
     return -1;
@@ -1573,7 +1573,7 @@
     if (bucket == null) return -1;
     int length = JS('int', '#.length', bucket);
     for (int i = 0; i < length; i++) {
-      LinkedHashSetCell cell = JS('var', '#[#]', bucket, i);
+      _LinkedHashSetCell cell = JS('var', '#[#]', bucket, i);
       if (_equality(cell._element, element)) return i;
     }
     return -1;
@@ -1620,23 +1620,23 @@
   }
 }
 
-class LinkedHashSetCell {
+class _LinkedHashSetCell {
   final _element;
 
-  LinkedHashSetCell _next;
-  LinkedHashSetCell _previous;
+  _LinkedHashSetCell _next;
+  _LinkedHashSetCell _previous;
 
-  LinkedHashSetCell(this._element);
+  _LinkedHashSetCell(this._element);
 }
 
 // TODO(kasperl): Share this code with LinkedHashMapKeyIterator<E>?
-class LinkedHashSetIterator<E> implements Iterator<E> {
+class _LinkedHashSetIterator<E> implements Iterator<E> {
   final _set;
   final int _modifications;
-  LinkedHashSetCell _cell;
+  _LinkedHashSetCell _cell;
   E _current;
 
-  LinkedHashSetIterator(this._set, this._modifications) {
+  _LinkedHashSetIterator(this._set, this._modifications) {
     _cell = _set._first;
   }
 
diff --git a/sdk/lib/_internal/js_runtime/lib/core_patch.dart b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
index 7d6ad7c..301517e 100644
--- a/sdk/lib/_internal/js_runtime/lib/core_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
@@ -281,8 +281,9 @@
   }
 
   @patch
-  factory List.filled(int length, E fill) {
-    List result = new JSArray<E>.fixed(length);
+  factory List.filled(int length, E fill, {bool growable: false}) {
+    List result = growable ? new JSArray<E>.growable(length)
+                           : new JSArray<E>.fixed(length);
     if (length != 0 && fill != null) {
       for (int i = 0; i < result.length; i++) {
         result[i] = fill;
@@ -527,6 +528,47 @@
     if (uri != null) return Uri.parse(uri);
     throw new UnsupportedError("'Uri.base' is not supported");
   }
+
+
+  // Matches a String that _uriEncodes to itself regardless of the kind of
+  // component.  This corresponds to [_unreservedTable], i.e. characters that
+  // are not encoded by any encoding table.
+  static final RegExp _needsNoEncoding = new RegExp(r'^[\-\.0-9A-Z_a-z~]*$');
+
+  /**
+   * This is the internal implementation of JavaScript's encodeURI function.
+   * It encodes all characters in the string [text] except for those
+   * that appear in [canonicalTable], and returns the escaped string.
+   */
+  @patch
+  static String _uriEncode(List<int> canonicalTable,
+                           String text,
+                           Encoding encoding,
+                           bool spaceToPlus) {
+    if (identical(encoding, UTF8) && _needsNoEncoding.hasMatch(text)) {
+      return text;
+    }
+
+    // Encode the string into bytes then generate an ASCII only string
+    // by percent encoding selected bytes.
+    StringBuffer result = new StringBuffer();
+    var bytes = encoding.encode(text);
+    for (int i = 0; i < bytes.length; i++) {
+      int byte = bytes[i];
+      if (byte < 128 &&
+          ((canonicalTable[byte >> 4] & (1 << (byte & 0x0f))) != 0)) {
+        result.writeCharCode(byte);
+      } else if (spaceToPlus && byte == _SPACE) {
+        result.write('+');
+      } else {
+        const String hexDigits = '0123456789ABCDEF';
+        result.write('%');
+        result.write(hexDigits[(byte >> 4) & 0x0f]);
+        result.write(hexDigits[byte & 0x0f]);
+      }
+    }
+    return result.toString();
+  }
 }
 
 @patch
diff --git a/sdk/lib/_internal/js_runtime/lib/developer_patch.dart b/sdk/lib/_internal/js_runtime/lib/developer_patch.dart
index e13f580..003f2696 100644
--- a/sdk/lib/_internal/js_runtime/lib/developer_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/developer_patch.dart
@@ -62,11 +62,24 @@
 }
 
 @patch
+void _reportInstantEvent(int start,
+                         String category,
+                         String name,
+                         String argumentsAsJson) {
+  // TODO.
+}
+
+@patch
 int _getNextAsyncId() {
   return 0;
 }
 
 @patch
+int _getIsolateNum() {
+  return 0;
+}
+
+@patch
 void _reportTaskEvent(int start,
                       int taskId,
                       String phase,
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index 8b3020a..fdc1ee2 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -1017,13 +1017,15 @@
   static String stringFromCharCode(charCode) {
     if (0 <= charCode) {
       if (charCode <= 0xffff) {
-        return JS('String', 'String.fromCharCode(#)', charCode);
+        return JS('returns:String;effects:none;depends:none',
+                  'String.fromCharCode(#)', charCode);
       }
       if (charCode <= 0x10ffff) {
         var bits = charCode - 0x10000;
         var low = 0xDC00 | (bits & 0x3ff);
         var high = 0xD800 | (bits >> 10);
-        return  JS('String', 'String.fromCharCode(#, #)', high, low);
+        return JS('returns:String;effects:none;depends:none',
+                  'String.fromCharCode(#, #)', high, low);
       }
     }
     throw new RangeError.range(charCode, 0, 0x10ffff);
@@ -2568,9 +2570,9 @@
       // captured variable `functionType` isn't reused.
       signatureFunction =
           JS('',
-             '''(function(t) {
-                    return function(){ return #(t); };
-                })(#)''',
+             '''(function(getType, t) {
+                    return function(){ return getType(t); };
+                })(#, #)''',
              RAW_DART_FUNCTION_REF(getType),
              functionType);
     } else if (!isStatic
@@ -3751,7 +3753,7 @@
   bool get _hasReturnType => JS('bool', '"ret" in #', _typeData);
   get _returnType => JS('', '#.ret', _typeData);
 
-  bool get _isVoid => JS('bool', '!!#.void', _typeData);
+  bool get _isVoid => JS('bool', '!!#.v', _typeData);
 
   bool get _hasArguments => JS('bool', '"args" in #', _typeData);
   List get _arguments => JS('JSExtendableArray', '#.args', _typeData);
diff --git a/sdk/lib/_internal/js_runtime/lib/js_mirrors.dart b/sdk/lib/_internal/js_runtime/lib/js_mirrors.dart
index fc78e72..4cbb163 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_mirrors.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_mirrors.dart
@@ -2245,19 +2245,25 @@
     disableTreeShaking();
     // TODO(ahe): What about optional parameters (named or not).
     String callPrefix = "${JS_GET_NAME(JsGetName.CALL_PREFIX)}\$";
-    var extractCallName = JS('', r'''
-function(reflectee) {
-  var properties = Object.keys(reflectee.constructor.prototype);
-  for (var i = 0; i < properties.length; i++) {
-    var property = properties[i];
-    if (# == property.substring(0, #) &&
-        property[#] >= '0' &&
-        property[#] <= '9') return property;
-  }
-  return null;
-}
-''', callPrefix, callPrefix.length, callPrefix.length, callPrefix.length);
-    String callName = JS('String|Null', '#(#)', extractCallName, reflectee);
+
+    String callName = JS(
+        'String|Null',
+        r'''
+          (function(reflectee, callPrefix) {
+            var properties = Object.keys(reflectee.constructor.prototype);
+            var callPrefixLength = callPrefix.length;
+            for (var i = 0; i < properties.length; i++) {
+              var property = properties[i];
+              if (callPrefix == property.substring(0, callPrefixLength) &&
+                  property[callPrefixLength] >= "0" &&
+                  property[callPrefixLength] <= "9") {
+                return property;
+              }
+            }
+            return null;
+          })(#, #)''',
+        reflectee, callPrefix);
+
     if (callName == null) {
       throw new RuntimeError('Cannot find callName on "$reflectee"');
     }
diff --git a/sdk/lib/_internal/js_runtime/lib/js_names.dart b/sdk/lib/_internal/js_runtime/lib/js_names.dart
index 708b873..a0fe67f 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_names.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_names.dart
@@ -165,9 +165,14 @@
 }
 
 String unmangleAllIdentifiersIfPreservedAnyways(String str) {
-  return JS("String",
-            r"(#).replace(/[^<,> ]+/g,"
-            r"function(m) { return #[m] || m; })",
-            str,
-            JS_EMBEDDED_GLOBAL('', MANGLED_GLOBAL_NAMES));
-}
\ No newline at end of file
+  return JS(
+      'String',
+      r'''
+        (function(str, names) {
+          return str.replace(
+              /[^<,> ]+/g,
+              function(m) { return names[m] || m; });
+        })(#, #)''',
+      str,
+      JS_EMBEDDED_GLOBAL('', MANGLED_GLOBAL_NAMES));
+}
diff --git a/sdk/lib/_internal/js_runtime/lib/math_patch.dart b/sdk/lib/_internal/js_runtime/lib/math_patch.dart
index 34476f2..fc54f63 100644
--- a/sdk/lib/_internal/js_runtime/lib/math_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/math_patch.dart
@@ -5,6 +5,7 @@
 // Patch file for dart:math library.
 import 'dart:_foreign_helper' show JS;
 import 'dart:_js_helper' show patch, checkNum;
+import 'dart:typed_data' show ByteData;
 
 @patch
 double sqrt(num x)
@@ -57,9 +58,14 @@
 
 @patch
 class Random {
+  static final _secureRandom = new _JSSecureRandom();
+
   @patch
   factory Random([int seed]) =>
       (seed == null) ? const _JSRandom() : new _Random(seed);
+
+  @patch
+  factory Random.secure() => _secureRandom;
 }
 
 class _JSRandom implements Random {
@@ -236,3 +242,89 @@
     return (_lo & 1) == 0;
   }
 }
+
+
+class _JSSecureRandom implements Random {
+  // Reused buffer with room enough for a double.
+  final _buffer = new ByteData(8);
+
+  _JSSecureRandom() {
+    var crypto = JS("", "self.crypto");
+    if (crypto != null) {
+      var getRandomValues = JS("", "#.getRandomValues", crypto);
+      if (getRandomValues != null) {
+        return;
+      }
+    }
+    throw new UnsupportedError(
+        "No source of cryptographically secure random numbers available.");
+  }
+
+  /// Fill _buffer from [start] to `start + length` with random bytes.
+  void _getRandomBytes(int start, int length) {
+    JS("void", "crypto.getRandomValues(#)",
+       _buffer.buffer.asUint8List(start, length));
+  }
+
+  bool nextBool() {
+    _getRandomBytes(0, 1);
+    return _buffer.getUint8(0).isOdd;
+  }
+
+  double nextDouble() {
+    _getRandomBytes(1, 7);
+    // Set top bits 12 of double to 0x3FF which is the exponent for numbers
+    // between 1.0 and 2.0.
+    _buffer.setUint8(0, 0x3F);
+    int highByte = _buffer.getUint8(1);
+    _buffer.setUint8(1, highByte | 0xF0);
+
+    // Buffer now contains double in the range [1.0-2.0)
+    // with 52 bits of entropy (not 53).
+    // To get 53 bits, we extract the 53rd bit from higthByte before
+    // overwriting it, and add that as a least significant bit.
+    // The getFloat64 method is big-endian as default.
+    double result = _buffer.getFloat64(0) - 1.0;
+    if (highByte & 0x10 != 0) {
+      result += 1.1102230246251565e-16;  // pow(2,-53).
+    }
+    return result;
+  }
+
+  int nextInt(int max) {
+    if (max <= 0 || max > _POW2_32) {
+      throw new RangeError("max must be in range 0 < max ≤ 2^32, was $max");
+    }
+    int byteCount = 1;
+    if (max > 0xFF) {
+      byteCount++;
+      if (max > 0xFFFF) {
+        byteCount++;
+        if (max > 0xFFFFFF) {
+          byteCount++;
+        }
+      }
+    }
+    _buffer.setUint32(0, 0);
+    int start = 4 - byteCount;
+    int randomLimit = pow(256, byteCount);
+    while (true) {
+      _getRandomBytes(start, byteCount);
+      // The getUint32 method is big-endian as default.
+      int random = _buffer.getUint32(0);
+      if (max & (max - 1) == 0) {
+        // Max is power of 2.
+        return random & (max - 1);
+      }
+      int result = random.remainder(max);
+      // Ensure results have equal probability by rejecting values in the
+      // last range of k*max .. 256**byteCount.
+      // TODO: Consider picking a higher byte count if the last range is a
+      // significant portion of the entire range - a 50% chance of having
+      // to use two more bytes is no worse than always using one more.
+      if (random - result + max < randomLimit) {
+        return result;
+      }
+    }
+  }
+}
diff --git a/sdk/lib/_internal/js_runtime/lib/native_helper.dart b/sdk/lib/_internal/js_runtime/lib/native_helper.dart
index e87ace9..30d3ba7 100644
--- a/sdk/lib/_internal/js_runtime/lib/native_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/native_helper.dart
@@ -164,6 +164,7 @@
  * A dispatch record is cached according to the specification of the dispatch
  * tag for [obj].
  */
+@NoInline()
 lookupAndCacheInterceptor(obj) {
   assert(!isDartObject(obj));
   String tag = getTagFunction(obj);
@@ -288,12 +289,14 @@
 
 var initNativeDispatchFlag;  // null or true
 
+@NoInline()
 void initNativeDispatch() {
   if (true == initNativeDispatchFlag) return;
   initNativeDispatchFlag = true;
   initNativeDispatchContinue();
 }
 
+@NoInline()
 void initNativeDispatchContinue() {
 
   dispatchRecordsForInstanceTags = JS('', 'Object.create(null)');
diff --git a/sdk/lib/_internal/js_runtime/lib/preambles/d8.js b/sdk/lib/_internal/js_runtime/lib/preambles/d8.js
index 18823e1..b67593a 100644
--- a/sdk/lib/_internal/js_runtime/lib/preambles/d8.js
+++ b/sdk/lib/_internal/js_runtime/lib/preambles/d8.js
@@ -327,4 +327,11 @@
       errorCallback(error);
     }
   };
+
+  // Mock cryptographically secure random by using plain random.
+  self.crypto = {getRandomValues: function(array) {
+    for (var i = 0; i < array.length; i++) {
+      array[i] = Math.random() * 256;
+    }
+  }};
 })(self);
diff --git a/sdk/lib/_internal/js_runtime/lib/preambles/jsshell.js b/sdk/lib/_internal/js_runtime/lib/preambles/jsshell.js
index a33a58f..9f136c2 100644
--- a/sdk/lib/_internal/js_runtime/lib/preambles/jsshell.js
+++ b/sdk/lib/_internal/js_runtime/lib/preambles/jsshell.js
@@ -67,6 +67,13 @@
       errorCallback(error);
     }
   };
+
+  // Mock cryptographically secure random by using plain random.
+  self.crypto = {getRandomValues: function(array) {
+    for (var i = 0; i < array.length; i++) {
+      array[i] = Math.random() * 256;
+    }
+  }};
 })(this)
 
 var getKeys = function(obj){
diff --git a/sdk/lib/_internal/js_runtime/lib/regexp_helper.dart b/sdk/lib/_internal/js_runtime/lib/regexp_helper.dart
index 9b44116c..35a42d1c 100644
--- a/sdk/lib/_internal/js_runtime/lib/regexp_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/regexp_helper.dart
@@ -85,23 +85,24 @@
     String m = multiLine == true ? 'm' : '';
     String i = caseSensitive == true ? '' : 'i';
     String g = global ? 'g' : '';
-    // We're using the JavaScript's try catch instead of the Dart one
-    // to avoid dragging in Dart runtime support just because of using
-    // RegExp.
+    // We're using the JavaScript's try catch instead of the Dart one to avoid
+    // dragging in Dart runtime support just because of using RegExp.
     var regexp = JS('',
-        '(function() {'
-         'try {'
-          'return new RegExp(#, # + # + #);'
-         '} catch (e) {'
-           'return e;'
-         '}'
-        '})()', source, m, i, g);
+        r'''
+          (function(source, modifiers) {
+            try {
+              return new RegExp(source, modifiers);
+            } catch (e) {
+              return e;
+            }
+          })(#, # + # + #)''',
+        source, m, i, g);
     if (JS('bool', '# instanceof RegExp', regexp)) return regexp;
     // The returned value is the JavaScript exception. Turn it into a
     // Dart exception.
     String errorMessage = JS('String', r'String(#)', regexp);
     throw new FormatException(
-        "Illegal RegExp pattern ($errorMessage)", source);
+        'Illegal RegExp pattern ($errorMessage)', source);
   }
 
   Match firstMatch(String string) {
diff --git a/sdk/lib/async/async.dart b/sdk/lib/async/async.dart
index ac205be..5d1e2c7 100644
--- a/sdk/lib/async/async.dart
+++ b/sdk/lib/async/async.dart
@@ -67,26 +67,27 @@
  *
  * ## Other resources
  *
- * * The [dart:async section of the library tour]
- * (https://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-asynchronous-programming):
- * A brief overview of asynchronous programming.
+ * * The [dart:async section of the library tour][asynchronous-programming]:
+ *   A brief overview of asynchronous programming.
  *
- * * [Use Future-Based APIs]
- * (https://www.dartlang.org/docs/tutorials/futures/): A closer look at
- * Futures and how to use them to write asynchronous Dart code.
+ * * [Use Future-Based APIs][futures-tutorial]: A closer look at Futures and
+ *   how to use them to write asynchronous Dart code.
  *
- * * [Futures and Error Handling]
- * (https://www.dartlang.org/articles/futures-and-error-handling/): Everything
- * you wanted to know about handling errors and exceptions when working with
- * Futures (but were afraid to ask).
+ * * [Futures and Error Handling][futures-error-handling]: Everything you
+ *   wanted to know about handling errors and exceptions when working with
+ *   Futures (but were afraid to ask).
  *
  * * [The Event Loop and Dart](https://www.dartlang.org/articles/event-loop/):
- * Learn how Dart handles the event queue and microtask queue, so you can write
- * better asynchronous code with fewer surprises.
+ *   Learn how Dart handles the event queue and microtask queue, so you can
+ *   write better asynchronous code with fewer surprises.
  *
- * * [Asynchronous Unit Testing with Dart]
- * (https://www.dartlang.org/articles/dart-unit-tests/#asynchronous-tests): How
- * to test asynchronous code.
+ * * [test package: Asynchronous Tests][test-readme]: How to test asynchronous
+ *   code.
+ *
+ * [asynchronous-programming]: https://www.dartlang.org/docs/dart-up-and-running/ch03.html#dartasync---asynchronous-programming
+ * [futures-tutorial]: https://www.dartlang.org/docs/tutorials/futures/
+ * [futures-error-handling]: https://www.dartlang.org/articles/futures-and-error-handling/
+ * [test-readme]: https://pub.dartlang.org/packages/test
  */
 library dart.async;
 
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index 232d8db..7766c81a 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -139,8 +139,6 @@
    */
   factory Stream.periodic(Duration period,
                           [T computation(int computationCount)]) {
-    if (computation == null) computation = ((i) => null);
-
     Timer timer;
     int computationCount = 0;
     StreamController<T> controller;
@@ -149,7 +147,15 @@
 
     void sendEvent() {
       watch.reset();
-      T data = computation(computationCount++);
+      T data;
+      if (computation != null) {
+        try {
+          data = computation(computationCount++);
+        } catch (e, s) {
+          controller.addError(e, s);
+          return;
+        }
+      }
       controller.add(data);
     }
 
@@ -1622,9 +1628,9 @@
    *                 onDone: controller.close,
    *                 cancelOnError: cancelOnError);
    *             },
-   *             onPause: () => subscription.pause(),
-   *             onResume: () => subscription.resume(),
-   *             onCancel: () => subscription.cancel(),
+   *             onPause: () { subscription.pause(); },
+   *             onResume: () { subscription.resume(); },
+   *             onCancel: () { subscription.cancel(); },
    *             sync: true);
    *           return controller.stream.listen(null);
    *         });
diff --git a/sdk/lib/convert/base64.dart b/sdk/lib/convert/base64.dart
index 77f7158..66c1f0c 100644
--- a/sdk/lib/convert/base64.dart
+++ b/sdk/lib/convert/base64.dart
@@ -307,12 +307,12 @@
 class Base64Decoder extends Converter<String, List<int>> {
   const Base64Decoder();
 
-  List<int> convert(String input) {
-    if (input.isEmpty) return new Uint8List(0);
-    int length = input.length;
+  List<int> convert(String input, [int start = 0, int end]) {
+    end = RangeError.checkValidRange(start, end, input.length);
+    if (start == end) return new Uint8List(0);
     var decoder = new _Base64Decoder();
-    Uint8List buffer = decoder.decode(input, 0, input.length);
-    decoder.close(input, input.length);
+    Uint8List buffer = decoder.decode(input, start, end);
+    decoder.close(input, end);
     return buffer;
   }
 
diff --git a/sdk/lib/convert/utf.dart b/sdk/lib/convert/utf.dart
index 8b1a1e0..287d8ec 100644
--- a/sdk/lib/convert/utf.dart
+++ b/sdk/lib/convert/utf.dart
@@ -335,7 +335,7 @@
     // of codeUnits.
     String result = _convertIntercepted(_allowMalformed, codeUnits, start, end);
     if (result != null) {
-      return null;
+      return result;
     }
 
     int length = codeUnits.length;
diff --git a/sdk/lib/core/core.dart b/sdk/lib/core/core.dart
index a33c8fa..3bd3dab 100644
--- a/sdk/lib/core/core.dart
+++ b/sdk/lib/core/core.dart
@@ -137,13 +137,13 @@
  *
  * ## Other documentation
  *
- * For more information about how to use the built-in types, refer to
- * [Built-in Types](http://www.dartlang.org/docs/dart-up-and-running/contents/ch02.html#built-in-types)
+ * For more information about how to use the built-in types, refer to [Built-in
+ * Types](http://www.dartlang.org/docs/dart-up-and-running/contents/ch02.html#built-in-types)
  * in Chapter 2 of
  * [Dart: Up and Running](http://www.dartlang.org/docs/dart-up-and-running/).
  *
- * Also, see
- * [dart:core - Numbers, Collections, Strings, and More](http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-dartcore---strings-collections-and-more)
+ * Also, see [dart:core - Numbers, Collections, Strings, and
+ * More](https://www.dartlang.org/docs/dart-up-and-running/ch03.html#dartcore---numbers-collections-strings-and-more)
  * for more coverage of classes in this package.
  *
  * The
@@ -155,9 +155,12 @@
 import "dart:collection";
 import "dart:_internal" hide Symbol;
 import "dart:_internal" as internal show Symbol;
-import "dart:convert" show UTF8, LATIN1, Encoding;
+import "dart:convert" show
+  Encoding, ASCII, LATIN1, UTF8,
+  BASE64, StringConversionSink, ChunkedConversionSink;
 import "dart:math" show Random;  // Used by List.shuffle.
 import "dart:async" show Stream, Future;  // Used by Resource.
+import "dart:typed_data" show Uint8List;
 
 part "annotations.dart";
 part "bool.dart";
diff --git a/sdk/lib/core/iterable.dart b/sdk/lib/core/iterable.dart
index 78efa1b..a327b6d 100644
--- a/sdk/lib/core/iterable.dart
+++ b/sdk/lib/core/iterable.dart
@@ -174,7 +174,7 @@
   Iterable<E> where(bool f(E element)) => new WhereIterable<E>(this, f);
 
   /**
-   * Expands each element of this [Iterable]into zero or more elements.
+   * Expands each element of this [Iterable] into zero or more elements.
    *
    * The resulting Iterable runs through the elements returned
    * by [f] for each element of this, in iteration order.
diff --git a/sdk/lib/core/iterator.dart b/sdk/lib/core/iterator.dart
index 34a7f49..cd0ad32 100644
--- a/sdk/lib/core/iterator.dart
+++ b/sdk/lib/core/iterator.dart
@@ -26,10 +26,9 @@
  *       use(it.current);
  *     }
  *
- * **See also:** [Iteration]
- * (http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-iteration)
- * in the [library tour]
- * (http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html)
+ * **See also:**
+ * [Iteration](http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#iteration)
+ * in the [library tour](http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html)
  */
 abstract class Iterator<E> {
   /**
diff --git a/sdk/lib/core/list.dart b/sdk/lib/core/list.dart
index 50a5f58..7f4ab18 100644
--- a/sdk/lib/core/list.dart
+++ b/sdk/lib/core/list.dart
@@ -82,9 +82,14 @@
    *
    *     new List<int>.filled(3, 0); // [0, 0, 0]
    *
-   * The [length] must not be negative or null.
+   * The [length] must be a non-negative integer.
+   *
+   * If the list is growable, changing its length will not initialize new
+   * entries with [fill]. After being created and filled, the list is
+   * no different from any other growable or fixed-length list
+   * created using [List].
    */
-  external factory List.filled(int length, E fill);
+  external factory List.filled(int length, E fill, {bool growable: false});
 
   /**
    * Creates a list containing all [elements].
diff --git a/sdk/lib/core/object.dart b/sdk/lib/core/object.dart
index 2951a73..ae0431e 100644
--- a/sdk/lib/core/object.dart
+++ b/sdk/lib/core/object.dart
@@ -13,10 +13,10 @@
  * When you define a class, you should override [toString]
  * to return a string describing an instance of that class.
  * You might also need to define [hashCode] and [==], as described in the
- * [Implementing map keys]
- * (http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-implementing-map-keys)
- * section of the [library tour]
- * (http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html).
+ * [Implementing map
+ * keys](https://www.dartlang.org/docs/dart-up-and-running/ch03.html#implementing-map-keys)
+ * section of the [library
+ * tour](http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html).
  */
 class Object {
   /**
@@ -78,14 +78,13 @@
   external String toString();
 
   /**
-   * [noSuchMethod] is invoked when users invoke a non-existent method
-   * on an object. The name of the method and the arguments of the
-   * invocation are passed to [noSuchMethod] in an [Invocation].
-   * If [noSuchMethod] returns a value, that value becomes the result of
-   * the original invocation.
+   * Invoked when a non-existent method or property is accessed.
    *
-   * The default behavior of [noSuchMethod] is to throw a
-   * [NoSuchMethodError].
+   * Classes can override [noSuchMethod] to provide custom behavior.
+   *
+   * If a value is returned, it becomes the result of the original invocation.
+   *
+   * The default behavior is to throw a [NoSuchMethodError].
    */
   external dynamic noSuchMethod(Invocation invocation);
 
diff --git a/sdk/lib/core/string.dart b/sdk/lib/core/string.dart
index 599ad0f..39641df 100644
--- a/sdk/lib/core/string.dart
+++ b/sdk/lib/core/string.dart
@@ -86,9 +86,8 @@
  * Also see:
 
  * * [Dart Cookbook](https://www.dartlang.org/docs/cookbook/#strings)
- * for String examples and recipes.
- * * [Dart Up and Running]
- * (https://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-strings-and-regular-expressions)
+ *   for String examples and recipes.
+ * * [Dart Up and Running](https://www.dartlang.org/docs/dart-up-and-running/ch03.html#strings-and-regular-expressions)
  */
 abstract class String implements Comparable<String>, Pattern {
   /**
diff --git a/sdk/lib/core/uri.dart b/sdk/lib/core/uri.dart
index 2cd5f8a..e4a31aa 100644
--- a/sdk/lib/core/uri.dart
+++ b/sdk/lib/core/uri.dart
@@ -12,8 +12,8 @@
  * * [URIs][uris] in the [library tour][libtour]
  * * [RFC-3986](http://tools.ietf.org/html/rfc3986)
  *
- * [uris]: http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-uri
- * [libtour]: http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html
+ * [uris]: https://www.dartlang.org/docs/dart-up-and-running/ch03.html#uris
+ * [libtour]: https://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html
  */
 class Uri {
   /**
@@ -386,9 +386,6 @@
     // query         = *( pchar / "/" / "?" )
     //
     // fragment      = *( pchar / "/" / "?" )
-    bool isRegName(int ch) {
-      return ch < 128 && ((_regNameTable[ch >> 4] & (1 << (ch & 0x0f))) != 0);
-    }
     const int EOI = -1;
 
     String scheme = "";
@@ -748,6 +745,74 @@
   }
 
   /**
+   * Creates a `data:` URI containing the [content] string.
+   *
+   * Converts the content to a bytes using [encoding] or the charset specified
+   * in [parameters] (defaulting to US-ASCII if not specified or unrecognized),
+   * then encodes the bytes into the resulting data URI.
+   *
+   * Defaults to encoding using percent-encoding (any non-ASCII or non-URI-valid
+   * bytes is replaced by a percent encoding). If [base64] is true, the bytes
+   * are instead encoded using [BASE64].
+   *
+   * If [encoding] is not provided and [parameters] has a `charset` entry,
+   * that name is looked up using [Encoding.getByName],
+   * and if the lookup returns an encoding, that encoding is used to convert
+   * [content] to bytes.
+   * If providing both an [encoding] and a charset [parameter], they should
+   * agree, otherwise decoding won't be able to use the charset parameter
+   * to determine the encoding.
+   *
+   * If [mimeType] and/or [parameters] are supplied, they are added to the
+   * created URI. If any of these contain characters that are not allowed
+   * in the data URI, the character is percent-escaped. If the character is
+   * non-ASCII, it is first UTF-8 encoded and then the bytes are percent
+   * encoded. An omitted [mimeType] in a data URI means `text/plain`, just
+   * as an omitted `charset` parameter defaults to meaning `US-ASCII`.
+   *
+   * To read the content back, use [UriData.contentAsString].
+   */
+  factory Uri.dataFromString(String content,
+                             {String mimeType,
+                              Encoding encoding,
+                              Map<String, String> parameters,
+                              bool base64: false}) {
+    UriData data =  new UriData.fromString(content,
+                                           mimeType: mimeType,
+                                           encoding: encoding,
+                                           parameters: parameters,
+                                           base64: base64);
+    return data.uri;
+  }
+
+  /**
+   * Creates a `data:` URI containing an encoding of [bytes].
+   *
+   * Defaults to Base64 encoding the bytes, but if [percentEncoded]
+   * is `true`, the bytes will instead be percent encoded (any non-ASCII
+   * or non-valid-ASCII-character byte is replaced by a percent encoding).
+   *
+   * To read the bytes back, use [UriData.contentAsBytes].
+   *
+   * It defaults to having the mime-type `application/octet-stream`.
+   * The [mimeType] and [parameters] are added to the created URI.
+   * If any of these contain characters that are not allowed
+   * in the data URI, the character is percent-escaped. If the character is
+   * non-ASCII, it is first UTF-8 encoded and then the bytes are percent
+   * encoded.
+   */
+  factory Uri.dataFromBytes(List<int> bytes,
+                            {mimeType: "application/octet-stream",
+                             Map<String, String> parameters,
+                             percentEncoded: false}) {
+    UriData data = new UriData.fromBytes(bytes,
+                                         mimeType: mimeType,
+                                         parameters: parameters,
+                                         percentEncoded: percentEncoded);
+    return data.uri;
+  }
+
+  /**
    * Returns the natural base URI for the current platform.
    *
    * When running in a browser this is the current URL (from
@@ -1012,34 +1077,35 @@
   }
 
   /**
-   * Returns the URI path split into its segments. Each of the
-   * segments in the returned list have been decoded. If the path is
-   * empty the empty list will be returned. A leading slash `/` does
-   * not affect the segments returned.
+   * Returns the URI path split into its segments. Each of the segments in the
+   * returned list have been decoded. If the path is empty the empty list will
+   * be returned. A leading slash `/` does not affect the segments returned.
    *
    * The returned list is unmodifiable and will throw [UnsupportedError] on any
    * calls that would mutate it.
    */
   List<String> get pathSegments {
-    if (_pathSegments == null) {
-      var pathToSplit = !path.isEmpty && path.codeUnitAt(0) == _SLASH
-                        ? path.substring(1)
-                        : path;
-      _pathSegments = new UnmodifiableListView(
-        pathToSplit == "" ? const<String>[]
-                          : pathToSplit.split("/")
-                                       .map(Uri.decodeComponent)
-                                       .toList(growable: false));
+    var result = _pathSegments;
+    if (result != null) return result;
+
+    var pathToSplit = path;
+    if (pathToSplit.isNotEmpty && pathToSplit.codeUnitAt(0) == _SLASH) {
+      pathToSplit = pathToSplit.substring(1);
     }
-    return _pathSegments;
+    result = (pathToSplit == "")
+        ? const<String>[]
+        : new List<String>.unmodifiable(
+              pathToSplit.split("/").map(Uri.decodeComponent));
+    _pathSegments = result;
+    return result;
   }
 
   /**
    * Returns the URI query split into a map according to the rules
-   * specified for FORM post in the [HTML 4.01 specification section 17.13.4]
-   * (http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4
-   * "HTML 4.01 section 17.13.4"). Each key and value in the returned map
-   * has been decoded. If there is no query the empty map is returned.
+   * specified for FORM post in the [HTML 4.01 specification section
+   * 17.13.4](http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4 "HTML 4.01 section 17.13.4").
+   * Each key and value in the returned map has been decoded. If there is no
+   * query the empty map is returned.
    *
    * Keys in the query string that have no value are mapped to the
    * empty string.
@@ -1245,7 +1311,8 @@
     if (path != null) {
       result = _normalize(path, start, end, _pathCharOrSlashTable);
     } else {
-      result = pathSegments.map((s) => _uriEncode(_pathCharTable, s)).join("/");
+      result = pathSegments.map((s) =>
+          _uriEncode(_pathCharTable, s, UTF8, false)).join("/");
     }
     if (result.isEmpty) {
       if (isFile) return "/";
@@ -1299,19 +1366,6 @@
 
   static int _stringOrNullLength(String s) => (s == null) ? 0 : s.length;
 
-  static bool _isHexDigit(int char) {
-    if (_NINE >= char) return _ZERO <= char;
-    char |= 0x20;
-    return _LOWER_CASE_A <= char && _LOWER_CASE_F >= char;
-  }
-
-  static int _hexValue(int char) {
-    assert(_isHexDigit(char));
-    if (_NINE >= char) return char - _ZERO;
-    char |= 0x20;
-    return char - (_LOWER_CASE_A - 10);
-  }
-
   /**
    * Performs RFC 3986 Percent-Encoding Normalization.
    *
@@ -1332,10 +1386,12 @@
     }
     int firstDigit = source.codeUnitAt(index + 1);
     int secondDigit = source.codeUnitAt(index + 2);
-    if (!_isHexDigit(firstDigit) || !_isHexDigit(secondDigit)) {
+    int firstDigitValue = _parseHexDigit(firstDigit);
+    int secondDigitValue = _parseHexDigit(secondDigit);
+    if (firstDigitValue < 0 || secondDigitValue < 0) {
       return "%";  // Marks the escape as invalid.
     }
-    int value = _hexValue(firstDigit) * 16 + _hexValue(secondDigit);
+    int value = firstDigitValue * 16 + secondDigitValue;
     if (_isUnreservedChar(value)) {
       if (lowerCase && _UPPER_CASE_A <= value && _UPPER_CASE_Z >= value) {
         value |= 0x20;
@@ -1351,21 +1407,27 @@
     return null;
   }
 
-  static bool _isUnreservedChar(int ch) {
-    return ch < 127 &&
-           ((_unreservedTable[ch >> 4] & (1 << (ch & 0x0f))) != 0);
+  // Converts a UTF-16 code-unit to its value as a hex digit.
+  // Returns -1 for non-hex digits.
+  static int _parseHexDigit(int char) {
+    int digit = char ^ Uri._ZERO;
+    if (digit <= 9) return digit;
+    int lowerCase = char | 0x20;
+    if (Uri._LOWER_CASE_A <= lowerCase && lowerCase <= _LOWER_CASE_F) {
+      return lowerCase - (_LOWER_CASE_A - 10);
+    }
+    return -1;
   }
 
-  static String _escapeChar(char) {
+  static String _escapeChar(int char) {
     assert(char <= 0x10ffff);  // It's a valid unicode code point.
-    const hexDigits = "0123456789ABCDEF";
     List codeUnits;
     if (char < 0x80) {
       // ASCII, a single percent encoded sequence.
       codeUnits = new List(3);
       codeUnits[0] = _PERCENT;
-      codeUnits[1] = hexDigits.codeUnitAt(char >> 4);
-      codeUnits[2] = hexDigits.codeUnitAt(char & 0xf);
+      codeUnits[1] = _hexDigits.codeUnitAt(char >> 4);
+      codeUnits[2] = _hexDigits.codeUnitAt(char & 0xf);
     } else {
       // Do UTF-8 encoding of character, then percent encode bytes.
       int flag = 0xc0;  // The high-bit markers on the first byte of UTF-8.
@@ -1383,8 +1445,8 @@
       while (--encodedBytes >= 0) {
         int byte = ((char >> (6 * encodedBytes)) & 0x3f) | flag;
         codeUnits[index] = _PERCENT;
-        codeUnits[index + 1] = hexDigits.codeUnitAt(byte >> 4);
-        codeUnits[index + 2] = hexDigits.codeUnitAt(byte & 0xf);
+        codeUnits[index + 1] = _hexDigits.codeUnitAt(byte >> 4);
+        codeUnits[index + 2] = _hexDigits.codeUnitAt(byte & 0xf);
         index += 3;
         flag = 0x80;  // Following bytes have only high bit set.
       }
@@ -1605,9 +1667,8 @@
    *
    * Returns the resolved URI.
    *
-   * The algorithm "Transform Reference" for resolving a reference is
-   * described in [RFC-3986 Section 5]
-   * (http://tools.ietf.org/html/rfc3986#section-5 "RFC-1123").
+   * The algorithm "Transform Reference" for resolving a reference is described
+   * in [RFC-3986 Section 5](http://tools.ietf.org/html/rfc3986#section-5 "RFC-1123").
    *
    * Updated to handle the case where the base URI is just a relative path -
    * that is: when it has no scheme or authority and the path does not start
@@ -1887,6 +1948,16 @@
     }
   }
 
+  /**
+   * Access the structure of a `data:` URI.
+   *
+   * Returns a [UriData] object for `data:` URIs and `null` for all other
+   * URIs.
+   * The [UriData] object can be used to access the media type and data
+   * of a `data:` URI.
+   */
+  UriData get data => (scheme == "data") ? new UriData.fromUri(this) : null;
+
   String toString() {
     StringBuffer sb = new StringBuffer();
     _addIfNonEmpty(sb, scheme, scheme, ':');
@@ -1905,16 +1976,16 @@
   bool operator==(other) {
     if (other is! Uri) return false;
     Uri uri = other;
-    return scheme == uri.scheme &&
-        hasAuthority == uri.hasAuthority &&
-        userInfo == uri.userInfo &&
-        host == uri.host &&
-        port == uri.port &&
-        path == uri.path &&
-        hasQuery == uri.hasQuery &&
-        query == uri.query &&
-        hasFragment == uri.hasFragment &&
-        fragment == uri.fragment;
+    return scheme       == uri.scheme       &&
+           hasAuthority == uri.hasAuthority &&
+           userInfo     == uri.userInfo     &&
+           host         == uri.host         &&
+           port         == uri.port         &&
+           path         == uri.path         &&
+           hasQuery     == uri.hasQuery     &&
+           query        == uri.query        &&
+           hasFragment  == uri.hasFragment  &&
+           fragment     == uri.fragment;
   }
 
   int get hashCode {
@@ -1955,7 +2026,7 @@
    * a [Uri].
    */
   static String encodeComponent(String component) {
-    return _uriEncode(_unreserved2396Table, component);
+    return _uriEncode(_unreserved2396Table, component, UTF8, false);
   }
 
   /**
@@ -1993,8 +2064,7 @@
    */
   static String encodeQueryComponent(String component,
                                      {Encoding encoding: UTF8}) {
-    return _uriEncode(
-        _unreservedTable, component, encoding: encoding, spaceToPlus: true);
+    return _uriEncode(_unreservedTable, component, encoding, true);
   }
 
   /**
@@ -2011,7 +2081,8 @@
    * decoded component.
    */
   static String decodeComponent(String encodedComponent) {
-    return _uriDecode(encodedComponent);
+    return _uriDecode(encodedComponent, 0, encodedComponent.length,
+                      UTF8, false);
   }
 
   /**
@@ -2025,7 +2096,8 @@
   static String decodeQueryComponent(
       String encodedComponent,
       {Encoding encoding: UTF8}) {
-    return _uriDecode(encodedComponent, plusToSpace: true, encoding: encoding);
+    return _uriDecode(encodedComponent, 0, encodedComponent.length,
+                      encoding, true);
   }
 
   /**
@@ -2038,7 +2110,7 @@
    * the encodeURI function .
    */
   static String encodeFull(String uri) {
-    return _uriEncode(_encodeFullTable, uri);
+    return _uriEncode(_encodeFullTable, uri, UTF8, false);
   }
 
   /**
@@ -2050,16 +2122,14 @@
    * [Uri.parse] before decoding the separate components.
    */
   static String decodeFull(String uri) {
-    return _uriDecode(uri);
+    return _uriDecode(uri, 0, uri.length, UTF8, false);
   }
 
   /**
    * Returns the [query] split into a map according to the rules
-   * specified for FORM post in the
-   * [HTML 4.01 specification section 17.13.4]
-   * (http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4
-   * "HTML 4.01 section 17.13.4"). Each key and value in the returned
-   * map has been decoded. If the [query]
+   * specified for FORM post in the [HTML 4.01 specification section
+   * 17.13.4](http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4 "HTML 4.01 section 17.13.4").
+   * Each key and value in the returned map has been decoded. If the [query]
    * is the empty string an empty map is returned.
    *
    * Keys in the query string that have no value are mapped to the
@@ -2254,39 +2324,12 @@
   static const int _LOWER_CASE_Z = 0x7A;
   static const int _BAR = 0x7C;
 
-  /**
-   * This is the internal implementation of JavaScript's encodeURI function.
-   * It encodes all characters in the string [text] except for those
-   * that appear in [canonicalTable], and returns the escaped string.
-   */
-  static String _uriEncode(List<int> canonicalTable,
-                           String text,
-                           {Encoding encoding: UTF8,
-                            bool spaceToPlus: false}) {
-    byteToHex(byte, buffer) {
-      const String hex = '0123456789ABCDEF';
-      buffer.writeCharCode(hex.codeUnitAt(byte >> 4));
-      buffer.writeCharCode(hex.codeUnitAt(byte & 0x0f));
-    }
+  static const String _hexDigits = "0123456789ABCDEF";
 
-    // Encode the string into bytes then generate an ASCII only string
-    // by percent encoding selected bytes.
-    StringBuffer result = new StringBuffer();
-    var bytes = encoding.encode(text);
-    for (int i = 0; i < bytes.length; i++) {
-      int byte = bytes[i];
-      if (byte < 128 &&
-          ((canonicalTable[byte >> 4] & (1 << (byte & 0x0f))) != 0)) {
-        result.writeCharCode(byte);
-      } else if (spaceToPlus && byte == _SPACE) {
-        result.writeCharCode(_PLUS);
-      } else {
-        result.writeCharCode(_PERCENT);
-        byteToHex(byte, result);
-      }
-    }
-    return result.toString();
-  }
+  external static String _uriEncode(List<int> canonicalTable,
+                                    String text,
+                                    Encoding encoding,
+                                    bool spaceToPlus);
 
   /**
    * Convert a byte (2 character hex sequence) in string [s] starting
@@ -2324,24 +2367,35 @@
    * decode the byte-list using [encoding]. The default encodingis UTF-8.
    */
   static String _uriDecode(String text,
-                           {bool plusToSpace: false,
-                            Encoding encoding: UTF8}) {
+                           int start,
+                           int end,
+                           Encoding encoding,
+                           bool plusToSpace) {
+    assert(0 <= start);
+    assert(start <= end);
+    assert(end <= text.length);
+    assert(encoding != null);
     // First check whether there is any characters which need special handling.
     bool simple = true;
-    for (int i = 0; i < text.length && simple; i++) {
+    for (int i = start; i < end; i++) {
       var codeUnit = text.codeUnitAt(i);
-      simple = codeUnit != _PERCENT && codeUnit != _PLUS;
+      if (codeUnit > 127 ||
+          codeUnit == _PERCENT ||
+          (plusToSpace && codeUnit == _PLUS)) {
+        simple = false;
+        break;
+      }
     }
     List<int> bytes;
     if (simple) {
-      if (encoding == UTF8 || encoding == LATIN1) {
-        return text;
+      if (UTF8 == encoding || LATIN1 == encoding || ASCII == encoding) {
+        return text.substring(start, end);
       } else {
-        bytes = text.codeUnits;
+        bytes = text.substring(start, end).codeUnits;
       }
     } else {
       bytes = new List();
-      for (int i = 0; i < text.length; i++) {
+      for (int i = start; i < end; i++) {
         var codeUnit = text.codeUnitAt(i);
         if (codeUnit > 127) {
           throw new ArgumentError("Illegal percent encoding in URI");
@@ -2362,9 +2416,15 @@
     return encoding.decode(bytes);
   }
 
-  static bool _isAlphabeticCharacter(int codeUnit)
-    => (codeUnit >= _LOWER_CASE_A && codeUnit <= _LOWER_CASE_Z) ||
-       (codeUnit >= _UPPER_CASE_A && codeUnit <= _UPPER_CASE_Z);
+  static bool _isAlphabeticCharacter(int codeUnit) {
+    var lowerCase = codeUnit | 0x20;
+    return (_LOWER_CASE_A <= lowerCase && lowerCase <= _LOWER_CASE_Z);
+  }
+
+  static bool _isUnreservedChar(int char) {
+    return char < 127 &&
+           ((_unreservedTable[char >> 4] & (1 << (char & 0x0f))) != 0);
+  }
 
   // Tables of char-codes organized as a bit vector of 128 bits where
   // each bit indicate whether a character code on the 0-127 needs to
@@ -2613,4 +2673,594 @@
       0xfffe,   // 0x60 - 0x6f  0111111111111111
                 //              pqrstuvwxyz   ~
       0x47ff];  // 0x70 - 0x7f  1111111111100010
+
+}
+
+// --------------------------------------------------------------------
+// Data URI
+// --------------------------------------------------------------------
+
+/**
+ * A way to access the structure of a `data:` URI.
+ *
+ * Data URIs are non-hierarchical URIs that can contain any binary data.
+ * They are defined by [RFC 2397](https://tools.ietf.org/html/rfc2397).
+ *
+ * This class allows parsing the URI text and extracting individual parts of the
+ * URI, as well as building the URI text from structured parts.
+ */
+class UriData {
+  static const int _noScheme = -1;
+  /**
+   * Contains the text content of a `data:` URI, with or without a
+   * leading `data:`.
+   *
+   * If [_separatorIndices] starts with `4` (the index of the `:`), then
+   * there is a leading `data:`, otherwise [_separatorIndices] starts with
+   * `-1`.
+   */
+  final String _text;
+
+  /**
+   * List of the separators (';', '=' and ',') in the text.
+   *
+   * Starts with the index of the `:` in `data:` of the mimeType.
+   * That is always either -1 or 4, depending on whether `_text` includes the
+   * `data:` scheme or not.
+   *
+   * The first speparator ends the mime type. We don't bother with finding
+   * the '/' inside the mime type.
+   *
+   * Each two separators after that marks a parameter key and value.
+   *
+   * If there is a single separator left, it ends the "base64" marker.
+   *
+   * So the following separators are found for a text:
+   *
+   *     data:text/plain;foo=bar;base64,ARGLEBARGLE=
+   *         ^          ^   ^   ^      ^
+   *
+   */
+  final List<int> _separatorIndices;
+
+  /**
+   * Cache of the result returned by [uri].
+   */
+  Uri _uriCache;
+
+  UriData._(this._text, this._separatorIndices, this._uriCache);
+
+  /**
+   * Creates a `data:` URI containing the [content] string.
+   *
+   * Equivalent to `new Uri.dataFromString(...).data`, but may
+   * be more efficient if the [uri] itself isn't used.
+   */
+  factory UriData.fromString(String content,
+                             {String mimeType,
+                              Encoding encoding,
+                              Map<String, String> parameters,
+                              bool base64: false}) {
+    StringBuffer buffer = new StringBuffer();
+    List indices = [_noScheme];
+    String charsetName;
+    String encodingName;
+    if (parameters != null) charsetName = parameters["charset"];
+    if (encoding == null) {
+      if (charsetName != null) {
+        encoding = Encoding.getByName(charsetName);
+      }
+    } else if (charsetName == null) {
+      // Non-null only if parameters does not contain "charset".
+      encodingName = encoding.name;
+    }
+    encoding ??= ASCII;
+    _writeUri(mimeType, encodingName, parameters, buffer, indices);
+    indices.add(buffer.length);
+    if (base64) {
+      buffer.write(';base64,');
+      indices.add(buffer.length - 1);
+      buffer.write(encoding.fuse(BASE64).encode(content));
+    } else {
+      buffer.write(',');
+      _uriEncodeBytes(_uricTable, encoding.encode(content), buffer);
+    }
+    return new UriData._(buffer.toString(), indices, null);
+  }
+
+  /**
+   * Creates a `data:` URI containing an encoding of [bytes].
+   *
+   * Equivalent to `new Uri.dataFromBytes(...).data`, but may
+   * be more efficient if the [uri] itself isn't used.
+   */
+  factory UriData.fromBytes(List<int> bytes,
+                            {mimeType: "application/octet-stream",
+                             Map<String, String> parameters,
+                             percentEncoded: false}) {
+    StringBuffer buffer = new StringBuffer();
+    List indices = [_noScheme];
+    _writeUri(mimeType, null, parameters, buffer, indices);
+    indices.add(buffer.length);
+    if (percentEncoded) {
+      buffer.write(',');
+      _uriEncodeBytes(_uricTable, bytes, buffer);
+    } else {
+      buffer.write(';base64,');
+      indices.add(buffer.length - 1);
+      BASE64.encoder
+            .startChunkedConversion(
+                new StringConversionSink.fromStringSink(buffer))
+            .addSlice(bytes, 0, bytes.length, true);
+    }
+
+    return new UriData._(buffer.toString(), indices, null);
+  }
+
+  /**
+   * Creates a `DataUri` from a [Uri] which must have `data` as [Uri.scheme].
+   *
+   * The [uri] must have scheme `data` and no authority or fragment,
+   * and the path (concatenated with the query, if there is one) must be valid
+   * as data URI content with the same rules as [parse].
+   */
+  factory UriData.fromUri(Uri uri) {
+    if (uri.scheme != "data") {
+      throw new ArgumentError.value(uri, "uri",
+                                    "Scheme must be 'data'");
+    }
+    if (uri.hasAuthority) {
+      throw new ArgumentError.value(uri, "uri",
+                                    "Data uri must not have authority");
+    }
+    if (uri.hasFragment) {
+      throw new ArgumentError.value(uri, "uri",
+                                    "Data uri must not have a fragment part");
+    }
+    if (!uri.hasQuery) {
+      return _parse(uri.path, 0, uri);
+    }
+    // Includes path and query (and leading "data:").
+    return _parse("$uri", 5, uri);
+  }
+
+  /**
+   * Writes the initial part of a `data:` uri, from after the "data:"
+   * until just before the ',' before the data, or before a `;base64,`
+   * marker.
+   *
+   * Of an [indices] list is passed, separator indices are stored in that
+   * list.
+   */
+  static void _writeUri(String mimeType,
+                        String charsetName,
+                        Map<String, String> parameters,
+                        StringBuffer buffer, List indices) {
+    if (mimeType == null || mimeType == "text/plain") {
+      mimeType = "";
+    }
+    if (mimeType.isEmpty || identical(mimeType, "application/octet-stream")) {
+      buffer.write(mimeType);  // Common cases need no escaping.
+    } else {
+      int slashIndex = _validateMimeType(mimeType);
+      if (slashIndex < 0) {
+        throw new ArgumentError.value(mimeType, "mimeType",
+                                      "Invalid MIME type");
+      }
+      buffer.write(Uri._uriEncode(_tokenCharTable,
+                                  mimeType.substring(0, slashIndex),
+                                  UTF8, false));
+      buffer.write("/");
+      buffer.write(Uri._uriEncode(_tokenCharTable,
+                                  mimeType.substring(slashIndex + 1),
+                                  UTF8, false));
+    }
+    if (charsetName != null) {
+      if (indices != null) {
+        indices..add(buffer.length)
+               ..add(buffer.length + 8);
+      }
+      buffer.write(";charset=");
+      buffer.write(Uri._uriEncode(_tokenCharTable, charsetName, UTF8, false));
+    }
+    parameters?.forEach((var key, var value) {
+      if (key.isEmpty) {
+        throw new ArgumentError.value("", "Parameter names must not be empty");
+      }
+      if (value.isEmpty) {
+        throw new ArgumentError.value("", "Parameter values must not be empty",
+                                      'parameters["$key"]');
+      }
+      if (indices != null) indices.add(buffer.length);
+      buffer.write(';');
+      // Encode any non-RFC2045-token character and both '%' and '#'.
+      buffer.write(Uri._uriEncode(_tokenCharTable, key, UTF8, false));
+      if (indices != null) indices.add(buffer.length);
+      buffer.write('=');
+      buffer.write(Uri._uriEncode(_tokenCharTable, value, UTF8, false));
+    });
+  }
+
+  /**
+   * Checks mimeType is valid-ish (`token '/' token`).
+   *
+   * Returns the index of the slash, or -1 if the mime type is not
+   * considered valid.
+   *
+   * Currently only looks for slashes, all other characters will be
+   * percent-encoded as UTF-8 if necessary.
+   */
+  static int _validateMimeType(String mimeType) {
+    int slashIndex = -1;
+    for (int i = 0; i < mimeType.length; i++) {
+      var char = mimeType.codeUnitAt(i);
+      if (char != Uri._SLASH) continue;
+      if (slashIndex < 0) {
+        slashIndex = i;
+        continue;
+      }
+      return -1;
+    }
+    return slashIndex;
+  }
+
+  /**
+   * Parses a string as a `data` URI.
+   *
+   * The string must have the format:
+   *
+   * ```
+   * 'data:' (type '/' subtype)? (';' attribute '=' value)* (';base64')? ',' data
+   * ````
+   *
+   * where `type`, `subtype`, `attribute` and `value` are specified in RFC-2045,
+   * and `data` is a sequnce of URI-characters (RFC-2396 `uric`).
+   *
+   * This means that all the characters must be ASCII, but the URI may contain
+   * percent-escapes for non-ASCII byte values that need an interpretation
+   * to be converted to the corresponding string.
+   *
+   * Parsing doesn't check the validity of any part, it just checks that the
+   * input has the correct structure with the correct sequence of `/`, `;`, `=`
+   * and `,` delimiters.
+   *
+   * Accessing the individual parts may fail later if they turn out to have
+   * content that can't be decoded sucessfully as a string.
+   */
+  static UriData parse(String uri) {
+    if (!uri.startsWith("data:")) {
+      throw new FormatException("Does not start with 'data:'", uri, 0);
+    }
+    return _parse(uri, 5, null);
+  }
+
+  /**
+   * The [Uri] that this `UriData` is giving access to.
+   *
+   * Returns a `Uri` with scheme `data` and the remainder of the data URI
+   * as path.
+   */
+  Uri get uri {
+    if (_uriCache != null) return _uriCache;
+    String path = _text;
+    String query = null;
+    int colonIndex = _separatorIndices[0];
+    int queryIndex = _text.indexOf('?', colonIndex + 1);
+    int end = null;
+    if (queryIndex >= 0) {
+      query = _text.substring(queryIndex + 1);
+      end = queryIndex;
+    }
+    path = _text.substring(colonIndex + 1, end);
+    // TODO(lrn): This is probably too simple. We should ensure URI
+    // normalization before passing in the raw strings, maybe using
+    // Uri._makePath, Uri._makeQuery.
+    _uriCache = new Uri._internal("data", "", null, null, path, query, null);
+    return _uriCache;
+  }
+
+  /**
+   * The MIME type of the data URI.
+   *
+   * A data URI consists of a "media type" followed by data.
+   * The media type starts with a MIME type and can be followed by
+   * extra parameters.
+   *
+   * Example:
+   *
+   *     data:text/plain;charset=utf-8,Hello%20World!
+   *
+   * This data URI has the media type `text/plain;charset=utf-8`, which is the
+   * MIME type `text/plain` with the parameter `charset` with value `utf-8`.
+   * See [RFC 2045](https://tools.ietf.org/html/rfc2045) for more detail.
+   *
+   * If the first part of the data URI is empty, it defaults to `text/plain`.
+   */
+  String get mimeType {
+    int start = _separatorIndices[0] + 1;
+    int end = _separatorIndices[1];
+    if (start == end) return "text/plain";
+    return Uri._uriDecode(_text, start, end, UTF8, false);
+  }
+
+  /**
+   * The charset parameter of the media type.
+   *
+   * If the parameters of the media type contains a `charset` parameter
+   * then this returns its value, otherwise it returns `US-ASCII`,
+   * which is the default charset for data URIs.
+   */
+  String get charset {
+    int parameterStart = 1;
+    int parameterEnd = _separatorIndices.length - 1;  // The ',' before data.
+    if (isBase64) {
+      // There is a ";base64" separator, so subtract one for that as well.
+      parameterEnd -= 1;
+    }
+    for (int i = parameterStart; i < parameterEnd; i += 2) {
+      var keyStart = _separatorIndices[i] + 1;
+      var keyEnd = _separatorIndices[i + 1];
+      if (keyEnd == keyStart + 7 && _text.startsWith("charset", keyStart)) {
+        return Uri._uriDecode(_text, keyEnd + 1, _separatorIndices[i + 2],
+                              UTF8, false);
+      }
+    }
+    return "US-ASCII";
+  }
+
+  /**
+   * Whether the data is Base64 encoded or not.
+   */
+  bool get isBase64 => _separatorIndices.length.isOdd;
+
+  /**
+   * The content part of the data URI, as its actual representation.
+   *
+   * This string may contain percent escapes.
+   */
+  String get contentText => _text.substring(_separatorIndices.last + 1);
+
+  /**
+   * The content part of the data URI as bytes.
+   *
+   * If the data is Base64 encoded, it will be decoded to bytes.
+   *
+   * If the data is not Base64 encoded, it will be decoded by unescaping
+   * percent-escaped characters and returning byte values of each unescaped
+   * character. The bytes will not be, e.g., UTF-8 decoded.
+   */
+  List<int> contentAsBytes() {
+    String text = _text;
+    int start = _separatorIndices.last + 1;
+    if (isBase64) {
+      return BASE64.decoder.convert(text, start);
+    }
+
+    // Not base64, do percent-decoding and return the remaining bytes.
+    // Compute result size.
+    const int percent = 0x25;
+    int length = text.length - start;
+    for (int i = start; i < text.length; i++) {
+      var codeUnit = text.codeUnitAt(i);
+      if (codeUnit == percent) {
+        i += 2;
+        length -= 2;
+      }
+    }
+    // Fill result array.
+    Uint8List result = new Uint8List(length);
+    if (length == text.length) {
+      result.setRange(0, length, text.codeUnits, start);
+      return result;
+    }
+    int index = 0;
+    for (int i = start; i < text.length; i++) {
+      var codeUnit = text.codeUnitAt(i);
+      if (codeUnit != percent) {
+        result[index++] = codeUnit;
+      } else {
+        if (i + 2 < text.length) {
+          var digit1 = Uri._parseHexDigit(text.codeUnitAt(i + 1));
+          var digit2 = Uri._parseHexDigit(text.codeUnitAt(i + 2));
+          if (digit1 >= 0 && digit2 >= 0) {
+            int byte = digit1 * 16 + digit2;
+            result[index++] = byte;
+            i += 2;
+            continue;
+          }
+        }
+        throw new FormatException("Invalid percent escape", text, i);
+      }
+    }
+    assert(index == result.length);
+    return result;
+  }
+
+  /**
+   * Returns a string created from the content of the data URI.
+   *
+   * If the content is Base64 encoded, it will be decoded to bytes and then
+   * decoded to a string using [encoding].
+   * If encoding is omitted, the value of a `charset` parameter is used
+   * if it is recongized by [Encoding.getByName], otherwise it defaults to
+   * the [ASCII] encoding, which is the default encoding for data URIs
+   * that do not specify an encoding.
+   *
+   * If the content is not Base64 encoded, it will first have percent-escapes
+   * converted to bytes and then the character codes and byte values are
+   * decoded using [encoding].
+   */
+  String contentAsString({Encoding encoding}) {
+    if (encoding == null) {
+      var charset = this.charset;  // Returns "US-ASCII" if not present.
+      encoding = Encoding.getByName(charset);
+      if (encoding == null) {
+        throw new UnsupportedError("Unknown charset: $charset");
+      }
+    }
+    String text = _text;
+    int start = _separatorIndices.last + 1;
+    if (isBase64) {
+      var converter = BASE64.decoder.fuse(encoding.decoder);
+      return converter.convert(text.substring(start));
+    }
+    return Uri._uriDecode(text, start, text.length, encoding, false);
+  }
+
+  /**
+   * A map representing the parameters of the media type.
+   *
+   * A data URI may contain parameters between the the MIME type and the
+   * data. This converts these parameters to a map from parameter name
+   * to parameter value.
+   * The map only contains parameters that actually occur in the URI.
+   * The `charset` parameter has a default value even if it doesn't occur
+   * in the URI, which is reflected by the [charset] getter. This means that
+   * [charset] may return a value even if `parameters["charset"]` is `null`.
+   *
+   * If the values contain non-ASCII values or percent escapes, they default
+   * to being decoded as UTF-8.
+   */
+  Map<String, String> get parameters {
+    var result = <String, String>{};
+    for (int i = 3; i < _separatorIndices.length; i += 2) {
+      var start = _separatorIndices[i - 2] + 1;
+      var equals = _separatorIndices[i - 1];
+      var end = _separatorIndices[i];
+      String key = Uri._uriDecode(_text, start, equals, UTF8, false);
+      String value = Uri._uriDecode(_text,equals + 1, end, UTF8, false);
+      result[key] = value;
+    }
+    return result;
+  }
+
+  static UriData _parse(String text, int start, Uri sourceUri) {
+    assert(start == 0 || start == 5);
+    assert((start == 5) == text.startsWith("data:"));
+
+    /// Character codes.
+    const int comma     = 0x2c;
+    const int slash     = 0x2f;
+    const int semicolon = 0x3b;
+    const int equals    = 0x3d;
+    List indices = [start - 1];
+    int slashIndex = -1;
+    var char;
+    int i = start;
+    for (; i < text.length; i++) {
+      char = text.codeUnitAt(i);
+      if (char == comma || char == semicolon) break;
+      if (char == slash) {
+        if (slashIndex < 0) {
+          slashIndex = i;
+          continue;
+        }
+        throw new FormatException("Invalid MIME type", text, i);
+      }
+    }
+    if (slashIndex < 0 && i > start) {
+      // An empty MIME type is allowed, but if non-empty it must contain
+      // exactly one slash.
+      throw new FormatException("Invalid MIME type", text, i);
+    }
+    while (char != comma) {
+      // Parse parameters and/or "base64".
+      indices.add(i);
+      i++;
+      int equalsIndex = -1;
+      for (; i < text.length; i++) {
+        char = text.codeUnitAt(i);
+        if (char == equals) {
+          if (equalsIndex < 0) equalsIndex = i;
+        } else if (char == semicolon || char == comma) {
+          break;
+        }
+      }
+      if (equalsIndex >= 0) {
+        indices.add(equalsIndex);
+      } else {
+        // Have to be final "base64".
+        var lastSeparator = indices.last;
+        if (char != comma ||
+            i != lastSeparator + 7 /* "base64,".length */ ||
+            !text.startsWith("base64", lastSeparator + 1)) {
+          throw new FormatException("Expecting '='", text, i);
+        }
+        break;
+      }
+    }
+    indices.add(i);
+    return new UriData._(text, indices, sourceUri);
+  }
+
+  /**
+   * Like [Uri._uriEncode] but takes the input as bytes, not a string.
+   *
+   * Encodes into [buffer] instead of creating its own buffer.
+   */
+  static void _uriEncodeBytes(List<int> canonicalTable,
+                              List<int> bytes,
+                              StringSink buffer) {
+    // Encode the string into bytes then generate an ASCII only string
+    // by percent encoding selected bytes.
+    int byteOr = 0;
+    for (int i = 0; i < bytes.length; i++) {
+      int byte = bytes[i];
+      byteOr |= byte;
+      if (byte < 128 &&
+          ((canonicalTable[byte >> 4] & (1 << (byte & 0x0f))) != 0)) {
+        buffer.writeCharCode(byte);
+      } else {
+        buffer.writeCharCode(Uri._PERCENT);
+        buffer.writeCharCode(Uri._hexDigits.codeUnitAt(byte >> 4));
+        buffer.writeCharCode(Uri._hexDigits.codeUnitAt(byte & 0x0f));
+      }
+    }
+    if ((byteOr & ~0xFF) != 0) {
+      for (int i = 0; i < bytes.length; i++) {
+        var byte = bytes[i];
+        if (byte < 0 || byte > 255) {
+          throw new ArgumentError.value(byte, "non-byte value");
+        }
+      }
+    }
+  }
+
+  String toString() =>
+      (_separatorIndices[0] == _noScheme) ? "data:$_text" : _text;
+
+  // Table of the `token` characters of RFC 2045 in a URI.
+  //
+  // A token is any US-ASCII character except SPACE, control characters and
+  // `tspecial` characters. The `tspecial` category is:
+  // '(', ')', '<', '>', '@', ',', ';', ':', '\', '"', '/', '[, ']', '?', '='.
+  //
+  // In a data URI, we also need to escape '%' and '#' characters.
+  static const _tokenCharTable = const [
+                //             LSB             MSB
+                //              |               |
+      0x0000,   // 0x00 - 0x0f  00000000 00000000
+      0x0000,   // 0x10 - 0x1f  00000000 00000000
+                //               !  $ &'   *+ -.
+      0x6cd2,   // 0x20 - 0x2f  01001011 00110110
+                //              01234567 89
+      0x03ff,   // 0x30 - 0x3f  11111111 11000000
+                //               ABCDEFG HIJKLMNO
+      0xfffe,   // 0x40 - 0x4f  01111111 11111111
+                //              PQRSTUVW XYZ   ^_
+      0xc7ff,   // 0x50 - 0x5f  11111111 11100011
+                //              `abcdefg hijklmno
+      0xffff,   // 0x60 - 0x6f  11111111 11111111
+                //              pqrstuvw xyz{|}~
+      0x7fff];  // 0x70 - 0x7f  11111111 11111110
+
+  // All non-escape RFC-2396 uric characters.
+  //
+  //  uric        =  reserved | unreserved | escaped
+  //  reserved    =  ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
+  //  unreserved  =  alphanum | mark
+  //  mark        =  "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
+  //
+  // This is the same characters as in a URI query (which is URI pchar plus '?')
+  static const _uricTable = Uri._queryCharTable;
 }
diff --git a/sdk/lib/dart2dart.platform b/sdk/lib/dart2dart.platform
new file mode 100644
index 0000000..fd9d8ed
--- /dev/null
+++ b/sdk/lib/dart2dart.platform
@@ -0,0 +1,48 @@
+# Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# The platform when compiling with dart2js for dart2dart.
+#
+# Includes the _mirror_helpers private libraries
+
+[dart-spec]
+spec:3rd edition.
+
+[features]
+# No extra features.
+
+[libraries]
+async: async/async.dart
+_chrome: _chrome/dart2js/chrome_dart2js.dart
+collection: collection/collection.dart
+convert: convert/convert.dart
+core: core/core.dart
+developer: developer/developer.dart
+html: html/dart2js/html_dart2js.dart
+html_common: html/html_common/html_common_dart2js.dart
+indexed_db: indexed_db/dart2js/indexed_db_dart2js.dart
+io: io/io.dart
+isolate: isolate/isolate.dart
+js: js/dart2js/js_dart2js.dart
+math: math/math.dart
+mirrors: mirrors/mirrors.dart
+nativewrappers: html/dart2js/nativewrappers.dart
+typed_data: typed_data/typed_data.dart
+_native_typed_data: _internal/js_runtime/lib/native_typed_data.dart
+svg: svg/dart2js/svg_dart2js.dart
+web_audio: web_audio/dart2js/web_audio_dart2js.dart
+web_gl: web_gl/dart2js/web_gl_dart2js.dart
+web_sql: web_sql/dart2js/web_sql_dart2js.dart
+_internal: internal/internal.dart
+_js_helper: _internal/js_runtime/lib/js_helper.dart
+_interceptors: _internal/js_runtime/lib/interceptors.dart
+_foreign_helper: _internal/js_runtime/lib/foreign_helper.dart
+_isolate_helper: _internal/js_runtime/lib/isolate_helper.dart
+_js_mirrors: _internal/js_runtime/lib/js_mirrors.dart
+_js_names: _internal/js_runtime/lib/js_names.dart
+_js_primitives: _internal/js_runtime/lib/js_primitives.dart
+_mirror_helper: _internal/js_runtime/lib/mirror_helper.dart
+_js_embedded_names: _internal/js_runtime/lib/shared/embedded_names.dart
+_async_await_error_codes: _internal/js_runtime/lib/shared/async_await_error_codes.dart
+_metadata: html/html_common/metadata.dart
diff --git a/sdk/lib/dart_client.platform b/sdk/lib/dart_client.platform
new file mode 100644
index 0000000..2e01cd9
--- /dev/null
+++ b/sdk/lib/dart_client.platform
@@ -0,0 +1,49 @@
+# Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# The platform for running dart on the web with dart2js.
+#
+# Includes dart:html and associated libraries.
+# Does not include dart:io.
+
+[dart-spec]
+spec: 3rd edition.
+
+[features]
+# No extra features.
+
+[libraries]
+async: async/async.dart
+_chrome: _chrome/dart2js/chrome_dart2js.dart
+collection: collection/collection.dart
+convert: convert/convert.dart
+core: core/core.dart
+developer: developer/developer.dart
+html: html/dart2js/html_dart2js.dart
+html_common: html/html_common/html_common_dart2js.dart
+indexed_db: indexed_db/dart2js/indexed_db_dart2js.dart
+io: unsupported:
+isolate: isolate/isolate.dart
+js: js/dart2js/js_dart2js.dart
+math: math/math.dart
+mirrors: mirrors/mirrors.dart
+nativewrappers: html/dart2js/nativewrappers.dart
+typed_data: typed_data/typed_data.dart
+_native_typed_data: _internal/js_runtime/lib/native_typed_data.dart
+svg: svg/dart2js/svg_dart2js.dart
+web_audio: web_audio/dart2js/web_audio_dart2js.dart
+web_gl: web_gl/dart2js/web_gl_dart2js.dart
+web_sql: web_sql/dart2js/web_sql_dart2js.dart
+_internal: internal/internal.dart
+_js_helper: _internal/js_runtime/lib/js_helper.dart
+_interceptors: _internal/js_runtime/lib/interceptors.dart
+_foreign_helper: _internal/js_runtime/lib/foreign_helper.dart
+_isolate_helper: _internal/js_runtime/lib/isolate_helper.dart
+_js_mirrors: _internal/js_runtime/lib/js_mirrors.dart
+_js_names: _internal/js_runtime/lib/js_names.dart
+_js_primitives: _internal/js_runtime/lib/js_primitives.dart
+_js_embedded_names: _internal/js_runtime/lib/shared/embedded_names.dart
+_async_await_error_codes: _internal/js_runtime/lib/shared/async_await_error_codes.dart
+_metadata: html/html_common/metadata.dart
+_mirror_helper: unsupported:
diff --git a/sdk/lib/dart_server.platform b/sdk/lib/dart_server.platform
new file mode 100644
index 0000000..821a175
--- /dev/null
+++ b/sdk/lib/dart_server.platform
@@ -0,0 +1,49 @@
+# Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# The platform for dart on the server with dart2js.
+#
+# Includes dart:io.
+# Does not include dart:html and associated libraries.
+
+[dart-spec]
+spec:3rd edition.
+
+[features]
+# No extra features.
+
+[libraries]
+async: async/async.dart
+collection: collection/collection.dart
+convert: convert/convert.dart
+core: core/core.dart
+developer: developer/developer.dart
+io: io/io.dart
+isolate: isolate/isolate.dart
+math: math/math.dart
+mirrors: mirrors/mirrors.dart
+nativewrappers: html/dart2js/nativewrappers.dart
+typed_data: typed_data/typed_data.dart
+_native_typed_data: _internal/js_runtime/lib/native_typed_data.dart
+html: unsupported:
+html_common: unsupported:
+indexed_db: unsupported:
+svg: unsupported:
+web_audio: unsupported:
+web_gl: unsupported:
+web_sql: unsupported:
+_chrome: unsupported:
+js: unsupported:
+_mirror_helper: unsupported:
+_internal: internal/internal.dart
+_js_helper: _internal/js_runtime/lib/js_helper.dart
+_interceptors: _internal/js_runtime/lib/interceptors.dart
+_foreign_helper: _internal/js_runtime/lib/foreign_helper.dart
+_isolate_helper: _internal/js_runtime/lib/isolate_helper.dart
+_js_mirrors: _internal/js_runtime/lib/js_mirrors.dart
+_js_names: _internal/js_runtime/lib/js_names.dart
+_js_primitives: _internal/js_runtime/lib/js_primitives.dart
+_js_embedded_names: _internal/js_runtime/lib/shared/embedded_names.dart
+_async_await_error_codes: _internal/js_runtime/lib/shared/async_await_error_codes.dart
+_metadata: html/html_common/metadata.dart
diff --git a/sdk/lib/dart_shared.platform b/sdk/lib/dart_shared.platform
new file mode 100644
index 0000000..539b868
--- /dev/null
+++ b/sdk/lib/dart_shared.platform
@@ -0,0 +1,47 @@
+# Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# A combination of the libraries for dart on the server and client.
+# For testing purposes only.
+
+[dart-spec]
+spec:3rd edition.
+
+[features]
+# No extra features.
+
+[libraries]
+async: async/async.dart
+_chrome: _chrome/dart2js/chrome_dart2js.dart
+collection: collection/collection.dart
+convert: convert/convert.dart
+core: core/core.dart
+developer: developer/developer.dart
+html: html/dart2js/html_dart2js.dart
+html_common: html/html_common/html_common_dart2js.dart
+indexed_db: indexed_db/dart2js/indexed_db_dart2js.dart
+io: io/io.dart
+isolate: isolate/isolate.dart
+js: js/dart2js/js_dart2js.dart
+math: math/math.dart
+mirrors: mirrors/mirrors.dart
+nativewrappers: html/dart2js/nativewrappers.dart
+typed_data: typed_data/typed_data.dart
+_native_typed_data: _internal/js_runtime/lib/native_typed_data.dart
+svg: svg/dart2js/svg_dart2js.dart
+web_audio: web_audio/dart2js/web_audio_dart2js.dart
+web_gl: web_gl/dart2js/web_gl_dart2js.dart
+web_sql: web_sql/dart2js/web_sql_dart2js.dart
+_internal: internal/internal.dart
+_js_helper: _internal/js_runtime/lib/js_helper.dart
+_interceptors: _internal/js_runtime/lib/interceptors.dart
+_foreign_helper: _internal/js_runtime/lib/foreign_helper.dart
+_isolate_helper: _internal/js_runtime/lib/isolate_helper.dart
+_js_mirrors: _internal/js_runtime/lib/js_mirrors.dart
+_js_names: _internal/js_runtime/lib/js_names.dart
+_js_primitives: _internal/js_runtime/lib/js_primitives.dart
+_js_embedded_names: _internal/js_runtime/lib/shared/embedded_names.dart
+_async_await_error_codes: _internal/js_runtime/lib/shared/async_await_error_codes.dart
+_metadata: html/html_common/metadata.dart
+_mirror_helper: unsupported:
diff --git a/sdk/lib/developer/timeline.dart b/sdk/lib/developer/timeline.dart
index 2753add..15ed062 100644
--- a/sdk/lib/developer/timeline.dart
+++ b/sdk/lib/developer/timeline.dart
@@ -5,6 +5,7 @@
 part of dart.developer;
 
 typedef dynamic TimelineSyncFunction();
+typedef Future TimelineAsyncFunction();
 
 /// Add to the timeline.
 class Timeline {
@@ -36,6 +37,24 @@
     block.finish();
   }
 
+  /// Emit an instant event.
+  static void instantSync(String name, {Map arguments}) {
+    if (name is! String) {
+      throw new ArgumentError.value(name,
+                                    'name',
+                                    'Must be a String');
+    }
+    Map instantArguments;
+    if (arguments is Map) {
+      instantArguments = new Map.from(arguments);
+    }
+    _reportInstantEvent(_getTraceClock(),
+                        'Dart',
+                        name,
+                        _argumentsAsJson(instantArguments));
+  }
+
+
   /// A utility method to time a synchronous [function]. Internally calls
   /// [function] bracketed by calls to [startSync] and [finishSync].
   static dynamic timeSync(String name,
@@ -50,76 +69,99 @@
   }
 
   static final List<_SyncBlock> _stack = new List<_SyncBlock>();
+  static final int _isolateId = _getIsolateNum();
+  static final String _isolateIdString = _isolateId.toString();
 }
 
-/// An asynchronous task on the timeline. Asynchronous tasks can live
-/// longer than the current event and can even be shared between isolates.
-/// An asynchronous task can have many (nested) blocks. To share a
-/// [_TimelineTask] across isolates, you must construct a [_TimelineTask] in
-/// both isolates using the same [taskId] and [category].
-class _TimelineTask {
+/// An asynchronous task on the timeline. An asynchronous task can have many
+/// (nested) synchronous operations. Synchronous operations can live longer than
+/// the current isolate event. To pass a [TimelineTask] to another isolate,
+/// you must first call [pass] to get the task id and then construct a new
+/// [TimelineTask] in the other isolate.
+class TimelineTask {
   /// Create a task. [taskId] will be set by the system.
-  /// Optionally you can specify a [category] name.
-  _TimelineTask({String category: 'Dart'})
-      : _taskId = _getNextAsyncId(),
-        category = category {
-    if (category is! String) {
-      throw new ArgumentError.value(category,
-                                    'category',
-                                    'Must be a String');
-    }
+  TimelineTask()
+      : _taskId = _getNextAsyncId() {
   }
 
   /// Create a task with an explicit [taskId]. This is useful if you are
-  /// passing a task between isolates. Optionally you can specify a [category]
-  /// name.
-  _TimelineTask.withTaskId(int taskId, {String category: 'Dart'})
-      : _taskId = taskId,
-        category = category {
+  /// passing a task from one isolate to another.
+  TimelineTask.withTaskId(int taskId)
+      : _taskId = taskId {
     if (taskId is! int) {
       throw new ArgumentError.value(taskId,
                                     'taskId',
                                     'Must be an int');
     }
-    if (category is! String) {
-      throw new ArgumentError.value(category,
-                                    'category',
-                                    'Must be a String');
-    }
   }
 
-  /// Start a block in this task named [name]. Optionally takes
-  /// a [Map] of [arguments].
-  /// Returns an [_AsyncBlock] which is used to finish this block.
-  _AsyncBlock start(String name, {Map arguments}) {
+  /// Start a synchronous operation within this task named [name].
+  /// Optionally takes a [Map] of [arguments].
+  void start(String name, {Map arguments}) {
     if (name is! String) {
       throw new ArgumentError.value(name,
                                     'name',
                                     'Must be a String');
     }
-    var block = new _AsyncBlock._(name, _taskId, category);
+    var block = new _AsyncBlock._(name, _taskId);
     if (arguments is Map) {
       block.arguments.addAll(arguments);
     }
-    /// Emit start event.
+    _stack.add(block);
     block._start();
-    return block;
   }
 
-  /// Retrieve the asynchronous task's id. Can be used to construct a
-  /// [_TimelineTask] in another isolate.
-  int get taskId => _taskId;
+  /// Emit an instant event for this task.
+  void instant(String name, {Map arguments}) {
+    if (name is! String) {
+      throw new ArgumentError.value(name,
+                                    'name',
+                                    'Must be a String');
+    }
+    Map instantArguments;
+    if (arguments is Map) {
+      instantArguments = new Map.from(arguments);
+    }
+    _reportTaskEvent(_getTraceClock(),
+                     _taskId,
+                     'n',
+                     'Dart',
+                     name,
+                     _argumentsAsJson(instantArguments));
+  }
+
+  /// Finish the last synchronous operation that was started.
+  void finish() {
+    if (_stack.length == 0) {
+      throw new StateError(
+          'Uneven calls to start and finish');
+    }
+    // Pop top item off of stack.
+    var block = _stack.removeLast();
+    block._finish();
+  }
+
+  /// Retrieve the [TimelineTask]'s task id. Will throw an exception if the
+  /// stack is not empty.
+  int pass() {
+    if (_stack.length > 0) {
+      throw new StateError(
+          'You cannot pass a TimelineTask without finishing all started '
+          'operations');
+    }
+    int r = _taskId;
+    return r;
+  }
+
   final int _taskId;
-  /// Retrieve the asynchronous task's category. Can be used to construct a
-  /// [_TimelineTask] in another isolate.
-  final String category;
+  final List<_AsyncBlock> _stack = [];
 }
 
 /// An asynchronous block of time on the timeline. This block can be kept
 /// open across isolate messages.
 class _AsyncBlock {
   /// The category this block belongs to.
-  final String category;
+  final String category = 'Dart';
   /// The name of this block.
   final String name;
   /// The asynchronous task id.
@@ -127,19 +169,17 @@
   /// An (optional) set of arguments which will be serialized to JSON and
   /// associated with this block.
   final Map arguments = {};
-  bool _finished = false;
 
-  _AsyncBlock._(this.name, this._taskId, this.category);
+  _AsyncBlock._(this.name, this._taskId);
 
   // Emit the start event.
   void _start() {
-    String argumentsAsJson = JSON.encode(arguments);
     _reportTaskEvent(_getTraceClock(),
                      _taskId,
                      'b',
                      category,
                      name,
-                     argumentsAsJson);
+                     _argumentsAsJson(arguments));
   }
 
   // Emit the finish event.
@@ -149,30 +189,7 @@
                      'e',
                      category,
                      name,
-                     JSON.encode({}));
-  }
-
-  /// Finish this block. Cannot be called twice.
-  void finish() {
-    if (_finished) {
-      throw new StateError(
-          'It is illegal to call finish twice on the same _AsyncBlock');
-    }
-    _finished = true;
-    _finish();
-  }
-
-  /// Finishes this block when [future] completes. Returns a [Future]
-  /// chained to [future].
-  Future finishWhenComplete(Future future) {
-    if (future is! Future) {
-      throw new ArgumentError.value(future,
-                                    'future',
-                                    'Must be a Future');
-    }
-    return future.whenComplete(() {
-      finish();
-    });
+                     _argumentsAsJson(null));
   }
 }
 
@@ -195,26 +212,38 @@
   /// Finish this block of time. At this point, this block can no longer be
   /// used.
   void finish() {
-    var end = _getTraceClock();
-
-    // Encode arguments map as JSON before reporting.
-    var argumentsAsJson = JSON.encode(arguments);
-
     // Report event to runtime.
     _reportCompleteEvent(_start,
-                         end,
+                         _getTraceClock(),
                          category,
                          name,
-                         argumentsAsJson);
+                         _argumentsAsJson(arguments));
   }
 }
 
+String _fastPathArguments;
+String _argumentsAsJson(Map arguments) {
+  if ((arguments == null) || (arguments.length == 0)) {
+    // Fast path no arguments. Avoid calling JSON.encode.
+    if (_fastPathArguments == null) {
+      _fastPathArguments = '{"isolateNumber":"${Timeline._isolateId}"}';
+    }
+    return _fastPathArguments;
+  }
+  // Add isolateNumber to arguments map.
+  arguments['isolateNumber'] = Timeline._isolateIdString;
+  return JSON.encode(arguments);
+}
+
 /// Returns the next async task id.
 external int _getNextAsyncId();
 
 /// Returns the current value from the trace clock.
 external int _getTraceClock();
 
+/// Returns the isolate's main port number.
+external int _getIsolateNum();
+
 /// Reports an event for a task.
 external void _reportTaskEvent(int start,
                                int taskId,
@@ -229,3 +258,9 @@
                                    String category,
                                    String name,
                                    String argumentsAsJson);
+
+/// Reports an instant event.
+external void _reportInstantEvent(int start,
+                                  String category,
+                                  String name,
+                                  String argumentsAsJson);
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 4983498..d3b2073 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -727,7 +727,7 @@
  *
  * See also:
  *
- * * [<area>](https://developer.mozilla.org/en-US/docs/HTML/Element/area)
+ * * [`<area>`](https://developer.mozilla.org/en-US/docs/HTML/Element/area)
  * on MDN.
  */
 @DomName('HTMLAreaElement')
@@ -1627,10 +1627,9 @@
    *
    * ## Other resources
    *
-   * * [WebGL fundamentals]
-   * (http://www.html5rocks.com/en/tutorials/webgl/webgl_fundamentals/) from
-   * HTML5Rocks.
-   * * [WebGL homepage] (http://get.webgl.org/).
+   * * [WebGL fundamentals](http://www.html5rocks.com/en/tutorials/webgl/webgl_fundamentals/)
+   *   from HTML5Rocks.
+   * * [WebGL homepage](http://get.webgl.org/).
    */
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.FIREFOX)
@@ -1729,7 +1728,8 @@
  * See also:
  *
  * * [CanvasGradient](https://developer.mozilla.org/en-US/docs/DOM/CanvasGradient) from MDN.
- * * [CanvasGradient](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvasgradient) from whatwg.
+ * * [CanvasGradient](https://html.spec.whatwg.org/multipage/scripting.html#canvasgradient)
+ *   from WHATWG.
  * * [CanvasGradient](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvasgradient) from W3C.
  */
 @DomName('CanvasGradient')
@@ -1781,7 +1781,8 @@
  *
  * See also:
  * * [CanvasPattern](https://developer.mozilla.org/en-US/docs/DOM/CanvasPattern) from MDN.
- * * [CanvasPattern](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvaspattern) from whatwg.
+ * * [CanvasPattern](https://html.spec.whatwg.org/multipage/scripting.html#canvaspattern)
+ *   from WHATWG.
  * * [CanvasPattern](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvaspattern) from W3C.
  */
 @DomName('CanvasPattern')
@@ -1849,9 +1850,9 @@
    *
    * ## Other resources
    *
-   * * [Image smoothing]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#image-smoothing)
-   * from WHATWG.
+   * * [Image
+   *   smoothing](https://html.spec.whatwg.org/multipage/scripting.html#image-smoothing)
+   *   from WHATWG.
    */
   @DomName('CanvasRenderingContext2D.imageSmoothingEnabled')
   @DocsEditable()
@@ -8971,7 +8972,7 @@
  *
  * See also:
  *
- * * [HTML <div> element](http://www.w3.org/TR/html-markup/div.html) from W3C.
+ * * [HTML `<div>` element](http://www.w3.org/TR/html-markup/div.html) from W3C.
  * * [Block-level element](http://www.w3.org/TR/CSS2/visuren.html#block-boxes) from W3C.
  * * [Inline-level element](http://www.w3.org/TR/CSS2/visuren.html#inline-boxes) from W3C.
  */
@@ -11318,13 +11319,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondrag')
   @DocsEditable()
@@ -11336,13 +11337,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragend')
   @DocsEditable()
@@ -11354,13 +11355,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragenter')
   @DocsEditable()
@@ -11372,13 +11373,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragleave')
   @DocsEditable()
@@ -11390,13 +11391,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragover')
   @DocsEditable()
@@ -11408,13 +11409,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragstart')
   @DocsEditable()
@@ -11426,13 +11427,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondrop')
   @DocsEditable()
@@ -11850,13 +11851,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondrag')
   @DocsEditable()
@@ -11868,13 +11869,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragend')
   @DocsEditable()
@@ -11886,13 +11887,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragenter')
   @DocsEditable()
@@ -11904,13 +11905,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragleave')
   @DocsEditable()
@@ -11922,13 +11923,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragover')
   @DocsEditable()
@@ -11940,13 +11941,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragstart')
   @DocsEditable()
@@ -11958,13 +11959,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondrop')
   @DocsEditable()
@@ -12583,7 +12584,8 @@
    *
    * See also:
    *
-   * * [Custom data attributes](http://www.w3.org/TR/html5/global-attributes.html#custom-data-attribute)
+   * * [Custom data
+   *   attributes](http://dev.w3.org/html5/spec-preview/global-attributes.html#custom-data-attribute)
    */
   Map<String, String> get dataset =>
     new _DataAttributeMap(attributes);
@@ -12796,8 +12798,8 @@
    *
    * ## Other resources
    *
-   * * [Node.namespaceURI]
-   * (http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-NodeNSname) from W3C.
+   * * [Node.namespaceURI](http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-NodeNSname)
+   *   from W3C.
    */
   @DomName('Element.namespaceUri')
   String get namespaceUri => _namespaceUri;
@@ -13014,11 +13016,9 @@
    *
    * ## Other resources
    *
-   * * [Shadow DOM 101]
-   * (http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
-   * from HTML5Rocks.
-   * * [Shadow DOM specification]
-   * (http://www.w3.org/TR/shadow-dom/) from W3C.
+   * * [Shadow DOM 101](http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
+   *   from HTML5Rocks.
+   * * [Shadow DOM specification](http://www.w3.org/TR/shadow-dom/) from W3C.
    */
   @DomName('Element.createShadowRoot')
   @SupportedBrowser(SupportedBrowser.CHROME, '25')
@@ -13034,11 +13034,10 @@
    *
    * ## Other resources
    *
-   * * [Shadow DOM 101]
-   * (http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
-   * from HTML5Rocks.
-   * * [Shadow DOM specification]
-   * (http://www.w3.org/TR/shadow-dom/) from W3C.
+   * * [Shadow DOM 101](http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
+   *   from HTML5Rocks.
+   * * [Shadow DOM specification](http://www.w3.org/TR/shadow-dom/)
+   *   from W3C.
    */
   @DomName('Element.shadowRoot')
   @SupportedBrowser(SupportedBrowser.CHROME, '25')
@@ -13569,13 +13568,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.dragEvent')
   @DocsEditable()
@@ -13587,13 +13586,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.dragendEvent')
   @DocsEditable()
@@ -13605,13 +13604,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.dragenterEvent')
   @DocsEditable()
@@ -13623,13 +13622,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.dragleaveEvent')
   @DocsEditable()
@@ -13641,13 +13640,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.dragoverEvent')
   @DocsEditable()
@@ -13658,13 +13657,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.dragstartEvent')
   @DocsEditable()
@@ -13676,13 +13675,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.dropEvent')
   @DocsEditable()
@@ -14116,13 +14115,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.draggable')
   @DocsEditable()
@@ -14133,9 +14132,9 @@
    *
    * ## Other resources
    *
-   * * [Hidden attribute specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/editing.html#the-hidden-attribute)
-   * from WHATWG.
+   * * [Hidden attribute
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#the-hidden-attribute)
+   *   from WHATWG.
    */
   @DomName('Element.hidden')
   @DocsEditable()
@@ -14169,9 +14168,9 @@
    *
    * ## Other resources
    *
-   * * [The translate attribute]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#the-translate-attribute)
-   * from WHATWG.
+   * * [The translate
+   *   attribute](https://html.spec.whatwg.org/multipage/dom.html#the-translate-attribute)
+   *   from WHATWG.
    */
   @DomName('Element.translate')
   @DocsEditable()
@@ -14186,13 +14185,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.webkitdropzone')
   @DocsEditable()
@@ -14336,12 +14335,11 @@
    *
    * ## Other resources
    *
-   * * [Element.getBoundingClientRect]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect)
-   * from MDN.
-   * * [The getBoundingClientRect() method]
-   * (http://www.w3.org/TR/cssom-view/#the-getclientrects-and-getboundingclientrect-methods)
-   * from W3C.
+   * * [Element.getBoundingClientRect](https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect)
+   *   from MDN.
+   * * [The getBoundingClientRect()
+   *   method](http://www.w3.org/TR/cssom-view/#the-getclientrects()-and-getboundingclientrect()-methods)
+   *   from W3C.
    */
   @DomName('Element.getBoundingClientRect')
   @DocsEditable()
@@ -14353,12 +14351,11 @@
    *
    * ## Other resources
    *
-   * * [Element.getClientRects]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Element.getClientRects)
-   * from MDN.
-   * * [The getClientRects() method]
-   * (http://www.w3.org/TR/cssom-view/#the-getclientrects-and-getboundingclientrect-methods)
-   * from W3C.
+   * * [Element.getClientRects](https://developer.mozilla.org/en-US/docs/Web/API/Element.getClientRects)
+   *   from MDN.
+   * * [The getClientRects()
+   *   method](http://www.w3.org/TR/cssom-view/#the-getclientrects()-and-getboundingclientrect()-methods)
+   *   from W3C.
    */
   @DomName('Element.getClientRects')
   @DocsEditable()
@@ -14372,9 +14369,9 @@
    *
    * ## Other resources
    *
-   * * [Shadow DOM specification]
-   * (https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html)
-   * from W3C.
+   * * [Shadow DOM
+   *   specification](https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html)
+   *   from W3C.
    */
   @DomName('Element.getDestinationInsertionPoints')
   @DocsEditable()
@@ -14388,11 +14385,9 @@
    *
    * ## Other resources
    *
-   * * [getElementsByClassName]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/document.getElementsByClassName)
-   * from MDN.
-   * * [DOM specification]
-   * (http://www.w3.org/TR/domcore/) from W3C.
+   * * [getElementsByClassName](https://developer.mozilla.org/en-US/docs/Web/API/document.getElementsByClassName)
+   *   from MDN.
+   * * [DOM specification](http://www.w3.org/TR/domcore/) from W3C.
    */
   @DomName('Element.getElementsByClassName')
   @DocsEditable()
@@ -14592,13 +14587,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondrag')
   @DocsEditable()
@@ -14610,13 +14605,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragend')
   @DocsEditable()
@@ -14628,13 +14623,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragenter')
   @DocsEditable()
@@ -14646,13 +14641,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragleave')
   @DocsEditable()
@@ -14664,13 +14659,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragover')
   @DocsEditable()
@@ -14682,13 +14677,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragstart')
   @DocsEditable()
@@ -14700,13 +14695,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondrop')
   @DocsEditable()
@@ -15340,8 +15335,8 @@
    *
    * ## Other resources
    *
-   * * [Target phase] (http://www.w3.org/TR/DOM-Level-3-Events/#target-phase)
-   * from W3C.
+   * * [Target phase](http://www.w3.org/TR/DOM-Level-3-Events/#target-phase)
+   *   from W3C.
    */
   @DomName('Event.AT_TARGET')
   @DocsEditable()
@@ -15352,8 +15347,8 @@
    *
    * ## Other resources
    *
-   * * [Bubble phase] (http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)
-   * from W3C.
+   * * [Bubble phase](http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)
+   *   from W3C.
    */
   @DomName('Event.BUBBLING_PHASE')
   @DocsEditable()
@@ -15365,8 +15360,8 @@
    *
    * ## Other resources
    *
-   * * [Bubble phase] (http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)
-   * from W3C.
+   * * [Bubble phase](http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)
+   *   from W3C.
    */
   @DomName('Event.CAPTURING_PHASE')
   @DocsEditable()
@@ -15385,8 +15380,8 @@
    *
    * ## Other resources
    *
-   * * [clipboardData specification]
-   * (http://www.w3.org/TR/clipboard-apis/#attributes) from W3C.
+   * * [clipboardData specification](http://www.w3.org/TR/clipboard-apis/#attributes)
+   *   from W3C.
    */
   @DomName('Event.clipboardData')
   @DocsEditable()
@@ -15421,9 +15416,9 @@
    *
    * ## Other resources
    *
-   * * [Shadow DOM extensions to Event]
-   * (http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event) from
-   * W3C.
+   * * [Shadow DOM extensions to
+   *   Event](http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event)
+   *   from W3C.
    */
   @DomName('Event.path')
   @DocsEditable()
@@ -17095,10 +17090,19 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
+// We implement EventTarget and have stubs for its methods because it's tricky to
+// convince the scripts to make our instance methods abstract, and the bodies that
+// get generated require `this` to be an EventTarget.
 @DocsEditable()
 @DomName('GlobalEventHandlers')
 @Experimental() // untriaged
-abstract class GlobalEventHandlers extends EventTarget {
+abstract class GlobalEventHandlers implements EventTarget {
+
+  void addEventListener(String type, dynamic listener(Event event), [bool useCapture]);
+  bool dispatchEvent(Event event);
+  void removeEventListener(String type, dynamic listener(Event event), [bool useCapture]);
+  Events get on;
+
   // To suppress missing implicit constructor warnings.
   factory GlobalEventHandlers._() { throw new UnsupportedError("Not supported"); }
 
@@ -17864,7 +17868,32 @@
   @SupportedBrowser(SupportedBrowser.FIREFOX)
   @SupportedBrowser(SupportedBrowser.IE, '10')
   @SupportedBrowser(SupportedBrowser.SAFARI)
-  void pushState(Object data, String title, [String url]) native;
+  void pushState(/*any*/ data, String title, [String url]) {
+    if (url != null) {
+      var data_1 = convertDartToNative_SerializedScriptValue(data);
+      _pushState_1(data_1, title, url);
+      return;
+    }
+    var data_1 = convertDartToNative_SerializedScriptValue(data);
+    _pushState_2(data_1, title);
+    return;
+  }
+  @JSName('pushState')
+  @DomName('History.pushState')
+  @DocsEditable()
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  void _pushState_1(data, title, url) native;
+  @JSName('pushState')
+  @DomName('History.pushState')
+  @DocsEditable()
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  void _pushState_2(data, title) native;
 
   @DomName('History.replaceState')
   @DocsEditable()
@@ -17872,7 +17901,32 @@
   @SupportedBrowser(SupportedBrowser.FIREFOX)
   @SupportedBrowser(SupportedBrowser.IE, '10')
   @SupportedBrowser(SupportedBrowser.SAFARI)
-  void replaceState(Object data, String title, [String url]) native;
+  void replaceState(/*any*/ data, String title, [String url]) {
+    if (url != null) {
+      var data_1 = convertDartToNative_SerializedScriptValue(data);
+      _replaceState_1(data_1, title, url);
+      return;
+    }
+    var data_1 = convertDartToNative_SerializedScriptValue(data);
+    _replaceState_2(data_1, title);
+    return;
+  }
+  @JSName('replaceState')
+  @DomName('History.replaceState')
+  @DocsEditable()
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  void _replaceState_1(data, title, url) native;
+  @JSName('replaceState')
+  @DomName('History.replaceState')
+  @DocsEditable()
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  void _replaceState_2(data, title) native;
 }
 // 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
@@ -18045,11 +18099,10 @@
    *
    * ## Other resources
    *
-   * * [Using the fullscreen API]
-   * (http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api) from
-   * WebPlatform.org.
-   * * [Fullscreen specification]
-   * (http://www.w3.org/TR/fullscreen/) from W3C.
+   * * [Using the fullscreen
+   *   API](http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api)
+   *   from WebPlatform.org.
+   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.
    */
   @DomName('Document.webkitExitFullscreen')
   @SupportedBrowser(SupportedBrowser.CHROME)
@@ -18073,11 +18126,10 @@
    *
    * ## Other resources
    *
-   * * [Using the fullscreen API]
-   * (http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api) from
-   * WebPlatform.org.
-   * * [Fullscreen specification]
-   * (http://www.w3.org/TR/fullscreen/) from W3C.
+   * * [Using the fullscreen
+   *   API](http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api)
+   *   from WebPlatform.org.
+   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.
    */
   @DomName('Document.webkitFullscreenElement')
   @SupportedBrowser(SupportedBrowser.CHROME)
@@ -18090,11 +18142,10 @@
    *
    * ## Other resources
    *
-   * * [Using the fullscreen API]
-   * (http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api) from
-   * WebPlatform.org.
-   * * [Fullscreen specification]
-   * (http://www.w3.org/TR/fullscreen/) from W3C.
+   * * [Using the fullscreen
+   *   API](http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api)
+   *   from WebPlatform.org.
+   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.
    */
   @DomName('Document.webkitFullscreenEnabled')
   @SupportedBrowser(SupportedBrowser.CHROME)
@@ -18797,7 +18848,8 @@
    * 'text'. Some newer browsers will throw NS_ERROR_DOM_INVALID_ACCESS_ERR if
    * `responseType` is set while performing a synchronous request.
    *
-   * See also: [MDN responseType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType)
+   * See also: [MDN
+   * responseType](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-responsetype)
    */
   @DomName('XMLHttpRequest.responseType')
   @DocsEditable()
@@ -18822,8 +18874,8 @@
   final Document responseXml;
 
   /**
-   * The http result code from the request (200, 404, etc).
-   * See also: [Http Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
+   * The HTTP result code from the request (200, 404, etc).
+   * See also: [HTTP Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
    */
   @DomName('XMLHttpRequest.status')
   @DocsEditable()
@@ -18831,7 +18883,7 @@
 
   /**
    * The request response string (such as \"200 OK\").
-   * See also: [Http Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
+   * See also: [HTTP Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
    */
   @DomName('XMLHttpRequest.statusText')
   @DocsEditable()
@@ -18846,12 +18898,10 @@
    *
    * ## Other resources
    *
-   * * [XMLHttpRequest.timeout]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#timeout)
-   * from MDN.
-   * * [The timeout attribute]
-   * (http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute)
-   * from W3C.
+   * * [XMLHttpRequest.timeout](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-timeout)
+   *   from MDN.
+   * * [The timeout attribute](http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute)
+   *   from W3C.
    */
   @DomName('XMLHttpRequest.timeout')
   @DocsEditable()
@@ -18895,7 +18945,8 @@
    * `getAllResponseHeaders` will return the response headers for the current
    * part of the request.
    *
-   * See also [HTTP response headers](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)
+   * See also [HTTP response
+   * headers](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Response_fields)
    * for a list of common response headers.
    */
   @DomName('XMLHttpRequest.getAllResponseHeaders')
@@ -18906,7 +18957,8 @@
   /**
    * Return the response header named `header`, or null if not found.
    *
-   * See also [HTTP response headers](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)
+   * See also [HTTP response
+   * headers](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Response_fields)
    * for a list of common response headers.
    */
   @DomName('XMLHttpRequest.getResponseHeader')
@@ -18919,7 +18971,7 @@
    * response.
    *
    * This value must be set before the request has been sent. See also the list
-   * of [common MIME types](http://en.wikipedia.org/wiki/Internet_media_type#List_of_common_media_types)
+   * of [IANA Official MIME types](https://www.iana.org/assignments/media-types/media-types.xhtml)
    */
   @DomName('XMLHttpRequest.overrideMimeType')
   @DocsEditable()
@@ -18938,9 +18990,8 @@
    *
    * ## Other resources
    *
-   * * [XMLHttpRequest.send]
-   * (https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)
-   * from MDN.
+   * * [XMLHttpRequest.send](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)
+   *   from MDN.
    */
   @DomName('XMLHttpRequest.send')
   @DocsEditable()
@@ -18957,12 +19008,11 @@
    *
    * ## Other resources
    *
-   * * [XMLHttpRequest.setRequestHeader]
-   * (https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)
-   * from MDN.
-   * * [The setRequestHeader() method]
-   * (http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader()-method) from
-   * W3C.
+   * * [XMLHttpRequest.setRequestHeader](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#setRequestHeader())
+   *   from MDN.
+   * * [The setRequestHeader()
+   *   method](http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader()-method)
+   *   from W3C.
    */
   @DomName('XMLHttpRequest.setRequestHeader')
   @DocsEditable()
@@ -23817,9 +23867,8 @@
    *
    * ## Other resources
    *
-   * * [Node.childNodes]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.childNodes)
-   * from MDN.
+   * * [Node.childNodes](https://developer.mozilla.org/en-US/docs/Web/API/Node.childNodes)
+   *   from MDN.
    */
   @DomName('Node.childNodes')
   @DocsEditable()
@@ -23888,9 +23937,8 @@
    *
    * ## Other resources
    *
-   * * [Node.firstChild]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.firstChild)
-   * from MDN.
+   * * [Node.firstChild](https://developer.mozilla.org/en-US/docs/Web/API/Node.firstChild)
+   *   from MDN.
    */
   @DomName('Node.firstChild')
   @DocsEditable()
@@ -23901,9 +23949,8 @@
    *
    * ## Other resources
    *
-   * * [Node.lastChild]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.lastChild)
-   * from MDN.
+   * * [Node.lastChild](https://developer.mozilla.org/en-US/docs/Web/API/Node.lastChild)
+   *   from MDN.
    */
   @DomName('Node.lastChild')
   @DocsEditable()
@@ -23925,9 +23972,8 @@
    *
    * ## Other resources
    *
-   * * [Node.nextSibling]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nextSibling)
-   * from MDN.
+   * * [Node.nextSibling](https://developer.mozilla.org/en-US/docs/Web/API/Node.nextSibling)
+   *   from MDN.
    */
   @DomName('Node.nextSibling')
   @DocsEditable()
@@ -23940,10 +23986,9 @@
    *
    * ## Other resources
    *
-   * * [Node.nodeName]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeName)
-   * from MDN. This page contains a table of [nodeName] values for each
-   * [nodeType].
+   * * [Node.nodeName](https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeName)
+   *   from MDN. This page contains a table of [nodeName] values for each
+   *   [nodeType].
    */
   @DomName('Node.nodeName')
   @DocsEditable()
@@ -23969,8 +24014,8 @@
    *
    * ## Other resources
    *
-   * * [Node.nodeType]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeType) from MDN.
+   * * [Node.nodeType](https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeType)
+   *   from MDN.
    */
   @DomName('Node.nodeType')
   @DocsEditable()
@@ -23983,10 +24028,9 @@
    *
    * ## Other resources
    *
-   * * [Node.nodeValue]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeValue)
-   * from MDN. This page contains a table of [nodeValue] values for each
-   * [nodeType].
+   * * [Node.nodeValue](https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeValue)
+   *   from MDN. This page contains a table of [nodeValue] values for each
+   *   [nodeType].
    */
   @DomName('Node.nodeValue')
   @DocsEditable()
@@ -23999,9 +24043,8 @@
    *
    * ## Other resources
    *
-   * * [Node.ownerDocument]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.ownerDocument) from
-   * MDN.
+   * * [Node.ownerDocument](https://developer.mozilla.org/en-US/docs/Web/API/Node.ownerDocument)
+   *   from MDN.
    */
   @DomName('Node.ownerDocument')
   @DocsEditable()
@@ -24016,9 +24059,8 @@
    *
    * ## Other resources
    *
-   * * [Node.parentElement]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.parentElement) from
-   * W3C.
+   * * [Node.parentElement](https://developer.mozilla.org/en-US/docs/Web/API/Node.parentElement)
+   *   from W3C.
    */
   @DomName('Node.parentElement')
   @DocsEditable()
@@ -24029,9 +24071,8 @@
    *
    * ## Other resources
    *
-   * * [Node.parentNode]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.parentNode) from
-   * MDN.
+   * * [Node.parentNode](https://developer.mozilla.org/en-US/docs/Web/API/Node.parentNode)
+   *   from MDN.
    */
   @DomName('Node.parentNode')
   @DocsEditable()
@@ -24043,9 +24084,8 @@
    *
    * ## Other resources
    *
-   * * [Node.previousSibling]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.previousSibling)
-   * from MDN.
+   * * [Node.previousSibling](https://developer.mozilla.org/en-US/docs/Web/API/Node.previousSibling)
+   *   from MDN.
    */
   @DomName('Node.previousSibling')
   @DocsEditable()
@@ -24057,9 +24097,8 @@
    *
    * ## Other resources
    *
-   * * [Node.textContent]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.textContent) from
-   * MDN.
+   * * [Node.textContent](https://developer.mozilla.org/en-US/docs/Web/API/Node.textContent)
+   *   from MDN.
    */
   @DomName('Node.textContent')
   @DocsEditable()
@@ -24088,9 +24127,8 @@
    *
    * ## Other resources
    *
-   * * [Node.cloneNode]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.cloneNode) from
-   * MDN.
+   * * [Node.cloneNode](https://developer.mozilla.org/en-US/docs/Web/API/Node.cloneNode)
+   *   from MDN.
    */
   @DomName('Node.cloneNode')
   @DocsEditable()
@@ -24101,8 +24139,8 @@
    *
    * ## Other resources
    *
-   * * [Node.contains]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.contains) from MDN.
+   * * [Node.contains](https://developer.mozilla.org/en-US/docs/Web/API/Node.contains)
+   *   from MDN.
    */
   @DomName('Node.contains')
   @DocsEditable()
@@ -24113,9 +24151,8 @@
    *
    * ## Other resources
    *
-   * * [Node.hasChildNodes]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.hasChildNodes) from
-   * MDN.
+   * * [Node.hasChildNodes](https://developer.mozilla.org/en-US/docs/Web/API/Node.hasChildNodes)
+   *   from MDN.
    */
   @DomName('Node.hasChildNodes')
   @DocsEditable()
@@ -24126,9 +24163,8 @@
    *
    * ## Other resources
    *
-   * * [Node.insertBefore]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.insertBefore) from
-   * MDN.
+   * * [Node.insertBefore](https://developer.mozilla.org/en-US/docs/Web/API/Node.insertBefore)
+   *   from MDN.
    */
   @DomName('Node.insertBefore')
   @DocsEditable()
@@ -32223,10 +32259,11 @@
    *
    * ## Other resources
    *
-   * * [Exploring the FileSystem APIs]
-   * (http://www.html5rocks.com/en/tutorials/file/filesystem/) from HTML5Rocks.
-   * * [File API]
-   * (http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem) from W3C.
+   * * [Exploring the FileSystem
+   *   APIs](http://www.html5rocks.com/en/tutorials/file/filesystem/)
+   *   from HTML5Rocks.
+   * * [File API](http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem)
+   *   from W3C.
    */
   @DomName('Window.PERSISTENT')
   @DocsEditable()
@@ -32239,10 +32276,10 @@
    *
    * ## Other resources
    *
-   * * [Exploring the FileSystem APIs]
-   * (http://www.html5rocks.com/en/tutorials/file/filesystem/) from HTML5Rocks.
-   * * [File API]
-   * (http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem) from W3C.
+   * * [Exploring the FileSystem
+   *   APIs](http://www.html5rocks.com/en/tutorials/file/filesystem/) from HTML5Rocks.
+   * * [File API](http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem)
+   *   from W3C.
    */
   @DomName('Window.TEMPORARY')
   @DocsEditable()
@@ -32267,11 +32304,12 @@
    *
    * ## Other resources
    *
-   * * [A beginner's guide to using the application cache]
-   * (http://www.html5rocks.com/en/tutorials/appcache/beginner) from HTML5Rocks.
-   * * [Application cache API]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/offline.html#application-cache-api)
-   * from WHATWG.
+   * * [A beginner's guide to using the application
+   *   cache](http://www.html5rocks.com/en/tutorials/appcache/beginner)
+   *   from HTML5Rocks.
+   * * [Application cache
+   *   API](https://html.spec.whatwg.org/multipage/browsers.html#application-cache-api)
+   *   from WHATWG.
    */
   @DomName('Window.applicationCache')
   @DocsEditable()
@@ -32311,12 +32349,10 @@
    *
    * ## Other resources
    *
-   * * [devicePixelRatio]
-   * (http://www.quirksmode.org/blog/archives/2012/06/devicepixelrati.html) from
-   * quirksmode.
-   * * [More about devicePixelRatio]
-   * (http://www.quirksmode.org/blog/archives/2012/07/more_about_devi.html) from
-   * quirksmode.
+   * * [devicePixelRatio](http://www.quirksmode.org/blog/archives/2012/06/devicepixelrati.html)
+   *   from quirksmode.
+   * * [More about devicePixelRatio](http://www.quirksmode.org/blog/archives/2012/07/more_about_devi.html)
+   *   from quirksmode.
    */
   @DomName('Window.devicePixelRatio')
   @DocsEditable()
@@ -32329,9 +32365,8 @@
    *
    * ## Other resources
    *
-   * * [Loading web pages]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html)
-   * from WHATWG.
+   * * [Loading web pages](https://html.spec.whatwg.org/multipage/browsers.html)
+   *   from WHATWG.
    */
   @DomName('Window.history')
   @DocsEditable()
@@ -32342,9 +32377,8 @@
    *
    * ## Other resources
    *
-   * * [innerHeight]
-   * (http://docs.webplatform.org/wiki/css/cssom/properties/innerHeight) from
-   * WebPlatform.org.
+   * * [innerHeight](http://docs.webplatform.org/wiki/css/cssom/properties/innerHeight)
+   *   from WebPlatform.org.
    */
   @DomName('Window.innerHeight')
   @DocsEditable()
@@ -32355,9 +32389,8 @@
    *
    * ## Other resources
    *
-   * * [innerWidth]
-   * (http://docs.webplatform.org/wiki/css/cssom/properties/innerWidth) from
-   * WebPlatform.org.
+   * * [innerWidth](http://docs.webplatform.org/wiki/css/cssom/properties/innerWidth)
+   *   from WebPlatform.org.
    */
   @DomName('Window.innerWidth')
   @DocsEditable()
@@ -32368,13 +32401,12 @@
    *
    * ## Other resources
    *
-   * * [DOM storage guide]
-   * (https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage) from
-   * MDN.
-   * * [The past, present & future of local storage for web applications]
-   * (http://diveintohtml5.info/storage.html) from Dive Into HTML5.
-   * * [Local storage specification]
-   * (http://www.w3.org/TR/webstorage/#the-localstorage-attribute) from W3C.
+   * * [DOM storage guide](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage)
+   *   from MDN.
+   * * [The past, present & future of local storage for web
+   *   applications](http://diveintohtml5.info/storage.html) from Dive Into HTML5.
+   * * [Local storage specification](http://www.w3.org/TR/webstorage/#the-localstorage-attribute)
+   *   from W3C.
    */
   @DomName('Window.localStorage')
   @DocsEditable()
@@ -32385,9 +32417,9 @@
    *
    * ## Other resources
    *
-   * * [Browser interface elements]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
-   * from WHATWG.
+   * * [Browser interface
+   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
+   *   from WHATWG.
    */
   @DomName('Window.locationbar')
   @DocsEditable()
@@ -32398,9 +32430,9 @@
    *
    * ## Other resources
    *
-   * * [Browser interface elements]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
-   * from WHATWG.
+   * * [Browser interface
+   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
+   *   from WHATWG.
    */
   @DomName('Window.menubar')
   @DocsEditable()
@@ -32411,9 +32443,8 @@
    *
    * ## Other resources
    *
-   * * [Window name]
-   * (http://docs.webplatform.org/wiki/html/attributes/name_(window)) from
-   * WebPlatform.org.
+   * * [Window name](http://docs.webplatform.org/wiki/html/attributes/name_(window))
+   *   from WebPlatform.org.
    */
   @DomName('Window.name')
   @DocsEditable()
@@ -32424,9 +32455,9 @@
    *
    * ## Other resources
    *
-   * * [The navigator object]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#the-navigator-object)
-   * from WHATWG.
+   * * [The navigator
+   *   object](https://html.spec.whatwg.org/multipage/webappapis.html#the-navigator-object)
+   *   from WHATWG.
    */
   @DomName('Window.navigator')
   @DocsEditable()
@@ -32437,9 +32468,8 @@
    *
    * ## Other resources
    *
-   * * [offscreenBuffering]
-   * (http://docs.webplatform.org/wiki/dom/properties/offscreenBuffering) from
-   * WebPlatform.org.
+   * * [offscreenBuffering](http://docs.webplatform.org/wiki/dom/properties/offscreenBuffering)
+   *   from WebPlatform.org.
    */
   @DomName('Window.offscreenBuffering')
   @DocsEditable()
@@ -32470,9 +32500,8 @@
    *
    * ## Other resources
    *
-   * * [outerHeight]
-   * (http://docs.webplatform.org/wiki/css/cssom/properties/outerHeight) from
-   * WebPlatform.org.
+   * * [outerHeight](http://docs.webplatform.org/wiki/css/cssom/properties/outerHeight)
+   *   from WebPlatform.org.
    */
   @DomName('Window.outerHeight')
   @DocsEditable()
@@ -32483,9 +32512,8 @@
    *
    * ## Other resources
    *
-   * * [outerWidth]
-   * (http://docs.webplatform.org/wiki/css/cssom/properties/outerWidth) from
-   * WebPlatform.org.
+   * * [outerWidth](http://docs.webplatform.org/wiki/css/cssom/properties/outerWidth)
+   *   from WebPlatform.org.
    */
   @DomName('Window.outerWidth')
   @DocsEditable()
@@ -32499,10 +32527,11 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
-   * * [scrollX and pageXOffset]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX) from MDN.
+   * * [The Screen interface
+   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [scrollX and
+   *   pageXOffset](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX)
+   *   from MDN.
    */
   @DomName('Window.pageXOffset')
   @DocsEditable()
@@ -32516,10 +32545,11 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
-   * * [scrollY and pageYOffset]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY) from MDN.
+   * * [The Screen interface
+   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [scrollY and
+   *   pageYOffset](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY)
+   *   from MDN.
    */
   @DomName('Window.pageYOffset')
   @DocsEditable()
@@ -32540,11 +32570,11 @@
    *
    * ## Other resources
    *
-   * * [Measuring page load speed with navigation timeing]
-   * (http://www.html5rocks.com/en/tutorials/webperformance/basics/) from
-   * HTML5Rocks.
-   * * [Navigation timing specification]
-   * (http://www.w3.org/TR/navigation-timing/) from W3C.
+   * * [Measuring page load speed with navigation
+   *   timeing](http://www.html5rocks.com/en/tutorials/webperformance/basics/)
+   *   from HTML5Rocks.
+   * * [Navigation timing
+   *   specification](http://www.w3.org/TR/navigation-timing/) from W3C.
    */
   @DomName('Window.performance')
   @DocsEditable()
@@ -32558,8 +32588,8 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
+   *   from W3C.
    */
   @DomName('Window.screen')
   @DocsEditable()
@@ -32571,8 +32601,8 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
+   *   from W3C.
    */
   @DomName('Window.screenLeft')
   @DocsEditable()
@@ -32583,8 +32613,8 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
+   *   from W3C.
    */
   @DomName('Window.screenTop')
   @DocsEditable()
@@ -32595,8 +32625,8 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
+   *   from W3C.
    */
   @DomName('Window.screenX')
   @DocsEditable()
@@ -32607,8 +32637,8 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
+   *   from W3C.
    */
   @DomName('Window.screenY')
   @DocsEditable()
@@ -32619,9 +32649,9 @@
    *
    * ## Other resources
    *
-   * * [Browser interface elements]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
-   * from WHATWG.
+   * * [Browser interface
+   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
+   *   from WHATWG.
    */
   @DomName('Window.scrollbars')
   @DocsEditable()
@@ -32632,8 +32662,8 @@
    *
    * ## Other resources
    *
-   * * [Window.self]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.self) from MDN.
+   * * [Window.self](https://developer.mozilla.org/en-US/docs/Web/API/Window.self)
+   *   from MDN.
    */
   @DomName('Window.self')
   @DocsEditable()
@@ -32644,8 +32674,8 @@
    *
    * ## Other resources
    *
-   * * [Window.self]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.self) from MDN.
+   * * [Window.self](https://developer.mozilla.org/en-US/docs/Web/API/Window.self)
+   *   from MDN.
    */
   @DomName('Window.self')
   @DocsEditable()
@@ -32658,13 +32688,13 @@
    *
    * ## Other resources
    *
-   * * [DOM storage guide]
-   * (https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage) from
-   * MDN.
-   * * [The past, present & future of local storage for web applications]
-   * (http://diveintohtml5.info/storage.html) from Dive Into HTML5.
-   * * [Local storage specification]
-   * (http://www.w3.org/TR/webstorage/#dom-sessionstorage) from W3C.
+   * * [DOM storage
+   *   guide](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage)
+   *   from MDN.
+   * * [The past, present & future of local storage for web
+   *   applications](http://diveintohtml5.info/storage.html) from Dive Into HTML5.
+   * * [Local storage
+   *   specification](http://www.w3.org/TR/webstorage/#dom-sessionstorage) from W3C.
    */
   @DomName('Window.sessionStorage')
   @DocsEditable()
@@ -32675,9 +32705,9 @@
    *
    * ## Other resources
    *
-   * * [Web speech specification]
-   * (https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section)
-   * from W3C.
+   * * [Web speech
+   *   specification](https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section)
+   *   from W3C.
    */
   @DomName('Window.speechSynthesis')
   @DocsEditable()
@@ -32695,9 +32725,9 @@
    *
    * ## Other resources
    *
-   * * [Browser interface elements]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
-   * from WHATWG.
+   * * [Browser interface
+   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
+   *   from WHATWG.
    */
   @DomName('Window.statusbar')
   @DocsEditable()
@@ -32708,9 +32738,9 @@
    *
    * ## Other resources
    *
-   * * [StyleMedia class reference]
-   * (https://developer.apple.com/library/safari/documentation/SafariDOMAdditions/Reference/StyleMedia/StyleMedia/StyleMedia.html)
-   * from Safari Developer Library.
+   * * [StyleMedia class
+   *   reference](https://developer.apple.com/library/safari/documentation/SafariDOMAdditions/Reference/StyleMedia/)
+   *   from Safari Developer Library.
    */
   @DomName('Window.styleMedia')
   @DocsEditable()
@@ -32723,9 +32753,9 @@
    *
    * ## Other resources
    *
-   * * [Browser interface elements]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
-   * from WHATWG.
+   * * [Browser interface
+   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
+   *   from WHATWG.
    */
   @DomName('Window.toolbar')
   @DocsEditable()
@@ -32746,8 +32776,8 @@
    *
    * ## Other resources
    *
-   * * [Window.window]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.window) from MDN.
+   * * [Window.window](https://developer.mozilla.org/en-US/docs/Web/API/Window.window)
+   *   from MDN.
    */
   @DomName('Window.window')
   @DocsEditable()
@@ -32758,8 +32788,8 @@
    *
    * ## Other resources
    *
-   * * [Window.window]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.window) from MDN.
+   * * [Window.window](https://developer.mozilla.org/en-US/docs/Web/API/Window.window)
+   *   from MDN.
    */
   @DomName('Window.window')
   @DocsEditable()
@@ -32798,9 +32828,8 @@
    *
    * ## Other resources
    *
-   * * [User prompts]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#user-prompts)
-   * from WHATWG.
+   * * [User prompts](https://html.spec.whatwg.org/multipage/webappapis.html#user-prompts)
+   *   from WHATWG.
    */
   @DomName('Window.alert')
   @DocsEditable()
@@ -32815,9 +32844,8 @@
    *
    * ## Other resources
    *
-   * * [User prompts]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#user-prompts)
-   * from WHATWG.
+   * * [User prompts](https://html.spec.whatwg.org/multipage/webappapis.html#user-prompts)
+   *   from WHATWG.
    */
   @DomName('Window.confirm')
   @DocsEditable()
@@ -32828,8 +32856,8 @@
    *
    * ## Other resources
    *
-   * * [Window.find]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.find) from MDN.
+   * * [Window.find](https://developer.mozilla.org/en-US/docs/Web/API/Window.find)
+   *   from MDN.
    */
   @DomName('Window.find')
   @DocsEditable()
@@ -32857,9 +32885,8 @@
    *
    * ## Other resources
    *
-   * * [Window.getSelection]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.getSelection)
-   * from MDN.
+   * * [Window.getSelection](https://developer.mozilla.org/en-US/docs/Web/API/Window.getSelection)
+   *   from MDN.
    */
   @DomName('Window.getSelection')
   @DocsEditable()
@@ -32870,11 +32897,11 @@
    *
    * ## Other resources
    *
-   * * [Testing media queries]
-   * (https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Testing_media_queries)
-   * from MDN.
-   * * [The MediaQueryList specification]
-   * (http://www.w3.org/TR/cssom-view/#the-mediaquerylist-interface) from W3C.
+   * * [Testing media
+   *   queries](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Testing_media_queries)
+   *   from MDN.
+   * * [The MediaQueryList
+   *   specification](http://www.w3.org/TR/cssom-view/#the-mediaquerylist-interface) from W3C.
    */
   @DomName('Window.matchMedia')
   @DocsEditable()
@@ -32887,10 +32914,9 @@
    *
    * ## Other resources
    *
-   * * [Window.moveBy]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.moveBy) from MDN.
-   * * [Window.moveBy]
-   * (http://dev.w3.org/csswg/cssom-view/#dom-window-moveby) from W3C.
+   * * [Window.moveBy](https://developer.mozilla.org/en-US/docs/Web/API/Window.moveBy)
+   *   from MDN.
+   * * [Window.moveBy](http://dev.w3.org/csswg/cssom-view/#dom-window-moveby) from W3C.
    */
   @DomName('Window.moveBy')
   @DocsEditable()
@@ -32938,8 +32964,8 @@
    *
    * ## Other resources
    *
-   * * [Window.print]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.print) from MDN.
+   * * [Window.print](https://developer.mozilla.org/en-US/docs/Web/API/Window.print)
+   *   from MDN.
    */
   @DomName('Window.print')
   @DocsEditable()
@@ -32950,8 +32976,8 @@
    *
    * ## Other resources
    *
-   * * [Window resizeBy] (http://docs.webplatform.org/wiki/dom/methods/resizeBy)
-   * from WebPlatform.org.
+   * * [Window resizeBy](http://docs.webplatform.org/wiki/dom/methods/resizeBy)
+   *   from WebPlatform.org.
    */
   @DomName('Window.resizeBy')
   @DocsEditable()
@@ -32962,8 +32988,8 @@
    *
    * ## Other resources
    *
-   * * [Window resizeTo] (http://docs.webplatform.org/wiki/dom/methods/resizeTo)
-   * from WebPlatform.org.
+   * * [Window resizeTo](http://docs.webplatform.org/wiki/dom/methods/resizeTo)
+   *   from WebPlatform.org.
    */
   @DomName('Window.resizeTo')
   @DocsEditable()
@@ -32976,8 +33002,8 @@
    *
    * ## Other resources
    *
-   * * [Window scroll] (http://docs.webplatform.org/wiki/dom/methods/scroll)
-   * from WebPlatform.org.
+   * * [Window scroll](http://docs.webplatform.org/wiki/dom/methods/scroll)
+   *   from WebPlatform.org.
    */
   @DomName('Window.scroll')
   @DocsEditable()
@@ -33010,8 +33036,8 @@
    *
    * ## Other resources
    *
-   * * [Window scroll] (http://docs.webplatform.org/wiki/dom/methods/scroll)
-   * from WebPlatform.org.
+   * * [Window scroll](http://docs.webplatform.org/wiki/dom/methods/scroll)
+   *   from WebPlatform.org.
    */
   @DomName('Window.scroll')
   @DocsEditable()
@@ -33024,8 +33050,8 @@
    *
    * ## Other resources
    *
-   * * [Window scroll] (http://docs.webplatform.org/wiki/dom/methods/scroll)
-   * from WebPlatform.org.
+   * * [Window scroll](http://docs.webplatform.org/wiki/dom/methods/scroll)
+   *   from WebPlatform.org.
    */
   @DomName('Window.scroll')
   @DocsEditable()
@@ -33038,8 +33064,8 @@
    *
    * ## Other resources
    *
-   * * [Window scroll] (http://docs.webplatform.org/wiki/dom/methods/scroll)
-   * from WebPlatform.org.
+   * * [Window scroll](http://docs.webplatform.org/wiki/dom/methods/scroll)
+   *   from WebPlatform.org.
    */
   @DomName('Window.scroll')
   @DocsEditable()
@@ -33052,8 +33078,8 @@
    *
    * ## Other resources
    *
-   * * [Window scroll] (http://docs.webplatform.org/wiki/dom/methods/scroll)
-   * from WebPlatform.org.
+   * * [Window scroll](http://docs.webplatform.org/wiki/dom/methods/scroll)
+   *   from WebPlatform.org.
    */
   @DomName('Window.scroll')
   @DocsEditable()
@@ -33064,8 +33090,8 @@
    *
    * ## Other resources
    *
-   * * [Window scrollBy] (http://docs.webplatform.org/wiki/dom/methods/scrollBy)
-   * from WebPlatform.org.
+   * * [Window scrollBy](http://docs.webplatform.org/wiki/dom/methods/scrollBy)
+   *   from WebPlatform.org.
    */
   @DomName('Window.scrollBy')
   @DocsEditable()
@@ -33096,8 +33122,8 @@
    *
    * ## Other resources
    *
-   * * [Window scrollBy] (http://docs.webplatform.org/wiki/dom/methods/scrollBy)
-   * from WebPlatform.org.
+   * * [Window scrollBy](http://docs.webplatform.org/wiki/dom/methods/scrollBy)
+   *   from WebPlatform.org.
    */
   @DomName('Window.scrollBy')
   @DocsEditable()
@@ -33108,8 +33134,8 @@
    *
    * ## Other resources
    *
-   * * [Window scrollBy] (http://docs.webplatform.org/wiki/dom/methods/scrollBy)
-   * from WebPlatform.org.
+   * * [Window scrollBy](http://docs.webplatform.org/wiki/dom/methods/scrollBy)
+   *   from WebPlatform.org.
    */
   @DomName('Window.scrollBy')
   @DocsEditable()
@@ -33120,8 +33146,8 @@
    *
    * ## Other resources
    *
-   * * [Window scrollBy] (http://docs.webplatform.org/wiki/dom/methods/scrollBy)
-   * from WebPlatform.org.
+   * * [Window scrollBy](http://docs.webplatform.org/wiki/dom/methods/scrollBy)
+   *   from WebPlatform.org.
    */
   @DomName('Window.scrollBy')
   @DocsEditable()
@@ -33132,8 +33158,8 @@
    *
    * ## Other resources
    *
-   * * [Window scrollBy] (http://docs.webplatform.org/wiki/dom/methods/scrollBy)
-   * from WebPlatform.org.
+   * * [Window scrollBy](http://docs.webplatform.org/wiki/dom/methods/scrollBy)
+   *   from WebPlatform.org.
    */
   @DomName('Window.scrollBy')
   @DocsEditable()
@@ -33146,8 +33172,8 @@
    *
    * ## Other resources
    *
-   * * [Window scrollTo] (http://docs.webplatform.org/wiki/dom/methods/scrollTo)
-   * from WebPlatform.org.
+   * * [Window scrollTo](http://docs.webplatform.org/wiki/dom/methods/scrollTo)
+   *   from WebPlatform.org.
    */
   @DomName('Window.scrollTo')
   @DocsEditable()
@@ -33180,8 +33206,8 @@
    *
    * ## Other resources
    *
-   * * [Window scrollTo] (http://docs.webplatform.org/wiki/dom/methods/scrollTo)
-   * from WebPlatform.org.
+   * * [Window scrollTo](http://docs.webplatform.org/wiki/dom/methods/scrollTo)
+   *   from WebPlatform.org.
    */
   @DomName('Window.scrollTo')
   @DocsEditable()
@@ -33194,8 +33220,8 @@
    *
    * ## Other resources
    *
-   * * [Window scrollTo] (http://docs.webplatform.org/wiki/dom/methods/scrollTo)
-   * from WebPlatform.org.
+   * * [Window scrollTo](http://docs.webplatform.org/wiki/dom/methods/scrollTo)
+   *   from WebPlatform.org.
    */
   @DomName('Window.scrollTo')
   @DocsEditable()
@@ -33208,8 +33234,8 @@
    *
    * ## Other resources
    *
-   * * [Window scrollTo] (http://docs.webplatform.org/wiki/dom/methods/scrollTo)
-   * from WebPlatform.org.
+   * * [Window scrollTo](http://docs.webplatform.org/wiki/dom/methods/scrollTo)
+   *   from WebPlatform.org.
    */
   @DomName('Window.scrollTo')
   @DocsEditable()
@@ -33222,8 +33248,8 @@
    *
    * ## Other resources
    *
-   * * [Window scrollTo] (http://docs.webplatform.org/wiki/dom/methods/scrollTo)
-   * from WebPlatform.org.
+   * * [Window scrollTo](http://docs.webplatform.org/wiki/dom/methods/scrollTo)
+   *   from WebPlatform.org.
    */
   @DomName('Window.scrollTo')
   @DocsEditable()
@@ -33234,9 +33260,9 @@
    *
    * ## Other resources
    *
-   * * [Dialogs implemented using separate documents]
-   * (http://www.w3.org/html/wg/drafts/html/master/webappapis.html#dialogs-implemented-using-separate-documents)
-   * from W3C.
+   * * [Dialogs implemented using separate
+   *   documents](http://www.w3.org/html/wg/drafts/html/master/webappapis.html#dialogs-implemented-using-separate-documents)
+   *   from W3C.
    */
   @DomName('Window.showModalDialog')
   @DocsEditable()
@@ -33248,9 +33274,9 @@
    *
    * ## Other resources
    *
-   * * [The Window object]
-   * (http://www.w3.org/html/wg/drafts/html/master/browsers.html#the-window-object)
-   * from W3C.
+   * * [The Window
+   *   object](http://www.w3.org/html/wg/drafts/html/master/browsers.html#the-window-object)
+   *   from W3C.
    */
   @DomName('Window.stop')
   @DocsEditable()
@@ -33284,8 +33310,8 @@
    *
    * ## Other resources
    *
-   * * [Obtaining access to file system entry points]
-   * (http://www.w3.org/TR/file-system-api/#obtaining-access-to-file-system-entry-points)
+   * * [Obtaining access to file system entry
+   *   points](http://www.w3.org/TR/file-system-api/#obtaining-access-to-file-system-entry-points)
    * from W3C.
    */
   @DomName('Window.webkitResolveLocalFileSystemURL')
@@ -33301,8 +33327,8 @@
    *
    * ## Other resources
    *
-   * * [Obtaining access to file system entry points]
-   * (http://www.w3.org/TR/file-system-api/#obtaining-access-to-file-system-entry-points)
+   * * [Obtaining access to file system entry
+   *   points](http://www.w3.org/TR/file-system-api/#obtaining-access-to-file-system-entry-points)
    * from W3C.
    */
   @DomName('Window.webkitResolveLocalFileSystemURL')
@@ -36229,12 +36255,11 @@
  *
  * ## Other resources
  *
- * * [Image sources for 2D rendering contexts]
- * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#image-sources-for-2d-rendering-contexts)
- * from WHATWG.
- * * [Drawing images]
- * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
- * from WHATWG.
+ * * [Image sources for 2D rendering
+ *   contexts](https://html.spec.whatwg.org/multipage/scripting.html#image-sources-for-2d-rendering-contexts)
+ *   from WHATWG.
+ * * [Drawing images](https://html.spec.whatwg.org/multipage/scripting.html#dom-context-2d-drawimage)
+ *   from WHATWG.
  */
 abstract class CanvasImageSource {}
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -36277,9 +36302,9 @@
    *
    * ## Other resources
    *
-   * * [Session history and navigation specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html)
-   * from WHATWG.
+   * * [Session history and navigation
+   *   specification](https://html.spec.whatwg.org/multipage/browsers.html#history)
+   *   from WHATWG.
    */
   HistoryBase get history;
 
@@ -36372,12 +36397,10 @@
    *
    * ## Other resources
    *
-   * * [window.postMessage]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage) from
-   * MDN.
-   * * [Cross-document messaging]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/web-messaging.html)
-   * from WHATWG.
+   * * [window.postMessage](https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage)
+   *   from MDN.
+   * * [Cross-document messaging](https://html.spec.whatwg.org/multipage/comms.html#web-messaging)
+   *   from WHATWG.
    */
   void postMessage(var message, String targetOrigin, [List messagePorts]);
 }
@@ -37221,9 +37244,8 @@
    *
    * ## Other resources
    *
-   * * [Event Capture]
-   * (http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture)
-   * from the W3C DOM Events specification.
+   * * [Event Capture](http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture)
+   *   from the W3C DOM Events specification.
    */
   StreamSubscription<T> capture(void onData(T event));
 }
@@ -40630,9 +40652,9 @@
    *
    * ## Other resources
    *
-   * * [Shadow DOM extensions to Event]
-   * (http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event) from
-   * W3C.
+   * * [Shadow DOM extensions to
+   *   Event](http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event)
+   *   from W3C.
    */
   // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#extensions-to-event
   @Experimental()
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 109eca3..cc87949 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -1160,32 +1160,6 @@
 
 }
 
-/// Upgrade a Dart HtmlElement to the user's Dart custom element class.
-_upgradeHtmlElement(dartInstance) {
-  // Only try upgrading HtmlElement (Dart class) if there is a failure then
-  // don't try it again - one failure is enough.
-  if (dartInstance.runtimeType == HtmlElement && !dartInstance.isBadUpgrade) {
-    // Must be exactly HtmlElement not something derived from it.
-
-    var customElementClass = getCustomElementType(dartInstance);
-
-    // Custom Element to upgrade.
-    if (customElementClass != null) {
-      var jsObject = dartInstance.blink_jsObject;
-      try {
-        dartInstance = _blink.Blink_Utils.constructElement(customElementClass, jsObject);
-      } catch (e) {
-        dartInstance._badUpgrade();
-      } finally {
-        dartInstance.blink_jsObject = jsObject;
-        js.setDartHtmlWrapperFor(jsObject, dartInstance);
-     }
-   }
-  }
-
-  return dartInstance;
-}
-
 @Deprecated("Internal Use Only")
 class DebugAssertException implements Exception {
   String message;
@@ -1235,7 +1209,12 @@
   try {
     dartClass = _blink.Blink_Utils.constructElement(customElementClass, $this);
   } catch (e) {
-    dartClass._badUpgrade();
+    // Did the dartClass get allocated but the created failed?  Otherwise, other
+    // components inside of this failed somewhere (could be JS custom element).
+    if (dartClass != null) {
+      // Yes, mark as didn't upgrade.
+      dartClass._badUpgrade();
+    }
     throw e;
   } finally {
     // Need to remember the Dart class that was created for this custom so
@@ -2093,7 +2072,7 @@
  *
  * See also:
  *
- * * [<area>](https://developer.mozilla.org/en-US/docs/HTML/Element/area)
+ * * [`<area>`](https://developer.mozilla.org/en-US/docs/HTML/Element/area)
  * on MDN.
  */
 @DomName('HTMLAreaElement')
@@ -3386,10 +3365,9 @@
    *
    * ## Other resources
    *
-   * * [WebGL fundamentals]
-   * (http://www.html5rocks.com/en/tutorials/webgl/webgl_fundamentals/) from
-   * HTML5Rocks.
-   * * [WebGL homepage] (http://get.webgl.org/).
+   * * [WebGL fundamentals](http://www.html5rocks.com/en/tutorials/webgl/webgl_fundamentals/)
+   *   from HTML5Rocks.
+   * * [WebGL homepage](http://get.webgl.org/).
    */
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.FIREFOX)
@@ -3490,7 +3468,8 @@
  * See also:
  *
  * * [CanvasGradient](https://developer.mozilla.org/en-US/docs/DOM/CanvasGradient) from MDN.
- * * [CanvasGradient](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvasgradient) from whatwg.
+ * * [CanvasGradient](https://html.spec.whatwg.org/multipage/scripting.html#canvasgradient)
+ *   from WHATWG.
  * * [CanvasGradient](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvasgradient) from W3C.
  */
 @DomName('CanvasGradient')
@@ -3559,7 +3538,8 @@
  *
  * See also:
  * * [CanvasPattern](https://developer.mozilla.org/en-US/docs/DOM/CanvasPattern) from MDN.
- * * [CanvasPattern](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvaspattern) from whatwg.
+ * * [CanvasPattern](https://html.spec.whatwg.org/multipage/scripting.html#canvaspattern)
+ *   from WHATWG.
  * * [CanvasPattern](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvaspattern) from W3C.
  */
 @DomName('CanvasPattern')
@@ -3680,9 +3660,9 @@
    *
    * ## Other resources
    *
-   * * [Image smoothing]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#image-smoothing)
-   * from WHATWG.
+   * * [Image
+   *   smoothing](https://html.spec.whatwg.org/multipage/scripting.html#image-smoothing)
+   *   from WHATWG.
    */
   @DomName('CanvasRenderingContext2D.imageSmoothingEnabled')
   @DocsEditable()
@@ -3695,9 +3675,9 @@
    *
    * ## Other resources
    *
-   * * [Image smoothing]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#image-smoothing)
-   * from WHATWG.
+   * * [Image
+   *   smoothing](https://html.spec.whatwg.org/multipage/scripting.html#image-smoothing)
+   *   from WHATWG.
    */
   @DomName('CanvasRenderingContext2D.imageSmoothingEnabled')
   @DocsEditable()
@@ -10235,7 +10215,7 @@
  *
  * See also:
  *
- * * [HTML <div> element](http://www.w3.org/TR/html-markup/div.html) from W3C.
+ * * [HTML `<div>` element](http://www.w3.org/TR/html-markup/div.html) from W3C.
  * * [Block-level element](http://www.w3.org/TR/CSS2/visuren.html#block-boxes) from W3C.
  * * [Inline-level element](http://www.w3.org/TR/CSS2/visuren.html#inline-boxes) from W3C.
  */
@@ -12970,13 +12950,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondrag')
   @DocsEditable()
@@ -12988,13 +12968,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragend')
   @DocsEditable()
@@ -13006,13 +12986,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragenter')
   @DocsEditable()
@@ -13024,13 +13004,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragleave')
   @DocsEditable()
@@ -13042,13 +13022,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragover')
   @DocsEditable()
@@ -13060,13 +13040,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragstart')
   @DocsEditable()
@@ -13078,13 +13058,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondrop')
   @DocsEditable()
@@ -13506,13 +13486,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondrag')
   @DocsEditable()
@@ -13524,13 +13504,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragend')
   @DocsEditable()
@@ -13542,13 +13522,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragenter')
   @DocsEditable()
@@ -13560,13 +13540,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragleave')
   @DocsEditable()
@@ -13578,13 +13558,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragover')
   @DocsEditable()
@@ -13596,13 +13576,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragstart')
   @DocsEditable()
@@ -13614,13 +13594,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondrop')
   @DocsEditable()
@@ -14238,7 +14218,8 @@
    *
    * See also:
    *
-   * * [Custom data attributes](http://www.w3.org/TR/html5/global-attributes.html#custom-data-attribute)
+   * * [Custom data
+   *   attributes](http://dev.w3.org/html5/spec-preview/global-attributes.html#custom-data-attribute)
    */
   Map<String, String> get dataset =>
     new _DataAttributeMap(attributes);
@@ -14445,8 +14426,8 @@
    *
    * ## Other resources
    *
-   * * [Node.namespaceURI]
-   * (http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-NodeNSname) from W3C.
+   * * [Node.namespaceURI](http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-NodeNSname)
+   *   from W3C.
    */
   @DomName('Element.namespaceUri')
   String get namespaceUri => _namespaceUri;
@@ -15067,13 +15048,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.dragEvent')
   @DocsEditable()
@@ -15085,13 +15066,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.dragendEvent')
   @DocsEditable()
@@ -15103,13 +15084,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.dragenterEvent')
   @DocsEditable()
@@ -15121,13 +15102,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.dragleaveEvent')
   @DocsEditable()
@@ -15139,13 +15120,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.dragoverEvent')
   @DocsEditable()
@@ -15156,13 +15137,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.dragstartEvent')
   @DocsEditable()
@@ -15174,13 +15155,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.dropEvent')
   @DocsEditable()
@@ -15799,12 +15780,11 @@
    *
    * ## Other resources
    *
-   * * [Element.getBoundingClientRect]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect)
-   * from MDN.
-   * * [The getBoundingClientRect() method]
-   * (http://www.w3.org/TR/cssom-view/#the-getclientrects-and-getboundingclientrect-methods)
-   * from W3C.
+   * * [Element.getBoundingClientRect](https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect)
+   *   from MDN.
+   * * [The getBoundingClientRect()
+   *   method](http://www.w3.org/TR/cssom-view/#the-getclientrects()-and-getboundingclientrect()-methods)
+   *   from W3C.
    */
   @DomName('Element.getBoundingClientRect')
   @DocsEditable()
@@ -15816,12 +15796,11 @@
    *
    * ## Other resources
    *
-   * * [Element.getClientRects]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Element.getClientRects)
-   * from MDN.
-   * * [The getClientRects() method]
-   * (http://www.w3.org/TR/cssom-view/#the-getclientrects-and-getboundingclientrect-methods)
-   * from W3C.
+   * * [Element.getClientRects](https://developer.mozilla.org/en-US/docs/Web/API/Element.getClientRects)
+   *   from MDN.
+   * * [The getClientRects()
+   *   method](http://www.w3.org/TR/cssom-view/#the-getclientrects()-and-getboundingclientrect()-methods)
+   *   from W3C.
    */
   @DomName('Element.getClientRects')
   @DocsEditable()
@@ -15833,9 +15812,9 @@
    *
    * ## Other resources
    *
-   * * [Shadow DOM specification]
-   * (https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html)
-   * from W3C.
+   * * [Shadow DOM
+   *   specification](https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html)
+   *   from W3C.
    */
   @DomName('Element.getDestinationInsertionPoints')
   @DocsEditable()
@@ -15847,11 +15826,9 @@
    *
    * ## Other resources
    *
-   * * [getElementsByClassName]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/document.getElementsByClassName)
-   * from MDN.
-   * * [DOM specification]
-   * (http://www.w3.org/TR/domcore/) from W3C.
+   * * [getElementsByClassName](https://developer.mozilla.org/en-US/docs/Web/API/document.getElementsByClassName)
+   *   from MDN.
+   * * [DOM specification](http://www.w3.org/TR/domcore/) from W3C.
    */
   @DomName('Element.getElementsByClassName')
   @DocsEditable()
@@ -16059,13 +16036,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondrag')
   @DocsEditable()
@@ -16077,13 +16054,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragend')
   @DocsEditable()
@@ -16095,13 +16072,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragenter')
   @DocsEditable()
@@ -16113,13 +16090,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragleave')
   @DocsEditable()
@@ -16131,13 +16108,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragover')
   @DocsEditable()
@@ -16149,13 +16126,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragstart')
   @DocsEditable()
@@ -16167,13 +16144,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondrop')
   @DocsEditable()
@@ -16905,8 +16882,8 @@
    *
    * ## Other resources
    *
-   * * [Target phase] (http://www.w3.org/TR/DOM-Level-3-Events/#target-phase)
-   * from W3C.
+   * * [Target phase](http://www.w3.org/TR/DOM-Level-3-Events/#target-phase)
+   *   from W3C.
    */
   @DomName('Event.AT_TARGET')
   @DocsEditable()
@@ -16917,8 +16894,8 @@
    *
    * ## Other resources
    *
-   * * [Bubble phase] (http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)
-   * from W3C.
+   * * [Bubble phase](http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)
+   *   from W3C.
    */
   @DomName('Event.BUBBLING_PHASE')
   @DocsEditable()
@@ -16930,8 +16907,8 @@
    *
    * ## Other resources
    *
-   * * [Bubble phase] (http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)
-   * from W3C.
+   * * [Bubble phase](http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)
+   *   from W3C.
    */
   @DomName('Event.CAPTURING_PHASE')
   @DocsEditable()
@@ -16950,8 +16927,8 @@
    *
    * ## Other resources
    *
-   * * [clipboardData specification]
-   * (http://www.w3.org/TR/clipboard-apis/#attributes) from W3C.
+   * * [clipboardData specification](http://www.w3.org/TR/clipboard-apis/#attributes)
+   *   from W3C.
    */
   @DomName('Event.clipboardData')
   @DocsEditable()
@@ -16980,9 +16957,9 @@
    *
    * ## Other resources
    *
-   * * [Shadow DOM extensions to Event]
-   * (http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event) from
-   * W3C.
+   * * [Shadow DOM extensions to
+   *   Event](http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event)
+   *   from W3C.
    */
   @DomName('Event.path')
   @DocsEditable()
@@ -19123,10 +19100,19 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
+// We implement EventTarget and have stubs for its methods because it's tricky to
+// convince the scripts to make our instance methods abstract, and the bodies that
+// get generated require `this` to be an EventTarget.
 @DocsEditable()
 @DomName('GlobalEventHandlers')
 @Experimental() // untriaged
-abstract class GlobalEventHandlers extends EventTarget {
+abstract class GlobalEventHandlers implements EventTarget {
+
+  void addEventListener(String type, dynamic listener(Event event), [bool useCapture]);
+  bool dispatchEvent(Event event);
+  void removeEventListener(String type, dynamic listener(Event event), [bool useCapture]);
+  Events get on;
+
   // To suppress missing implicit constructor warnings.
   factory GlobalEventHandlers._() { throw new UnsupportedError("Not supported"); }
 
@@ -19961,7 +19947,7 @@
   
   @DomName('History.state')
   @DocsEditable()
-  dynamic get state => _blink.BlinkHistory.instance.state_Getter_(unwrap_jso(this));
+  dynamic get state => wrap_jso(_blink.BlinkHistory.instance.state_Getter_(unwrap_jso(this)));
   
   @DomName('History.back')
   @DocsEditable()
@@ -19981,7 +19967,7 @@
   @SupportedBrowser(SupportedBrowser.FIREFOX)
   @SupportedBrowser(SupportedBrowser.IE, '10')
   @SupportedBrowser(SupportedBrowser.SAFARI)
-  void pushState(Object data, String title, [String url]) => _blink.BlinkHistory.instance.pushState_Callback_3_(unwrap_jso(this), data, title, url);
+  void pushState(Object data, String title, [String url]) => _blink.BlinkHistory.instance.pushState_Callback_3_(unwrap_jso(this), convertDartToNative_SerializedScriptValue(data), title, url);
   
   @DomName('History.replaceState')
   @DocsEditable()
@@ -19989,7 +19975,7 @@
   @SupportedBrowser(SupportedBrowser.FIREFOX)
   @SupportedBrowser(SupportedBrowser.IE, '10')
   @SupportedBrowser(SupportedBrowser.SAFARI)
-  void replaceState(Object data, String title, [String url]) => _blink.BlinkHistory.instance.replaceState_Callback_3_(unwrap_jso(this), data, title, url);
+  void replaceState(Object data, String title, [String url]) => _blink.BlinkHistory.instance.replaceState_Callback_3_(unwrap_jso(this), convertDartToNative_SerializedScriptValue(data), title, url);
   }
 // 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
@@ -20198,11 +20184,10 @@
    *
    * ## Other resources
    *
-   * * [Using the fullscreen API]
-   * (http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api) from
-   * WebPlatform.org.
-   * * [Fullscreen specification]
-   * (http://www.w3.org/TR/fullscreen/) from W3C.
+   * * [Using the fullscreen
+   *   API](http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api)
+   *   from WebPlatform.org.
+   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.
    */
   @DomName('Document.webkitExitFullscreen')
   @SupportedBrowser(SupportedBrowser.CHROME)
@@ -20226,11 +20211,10 @@
    *
    * ## Other resources
    *
-   * * [Using the fullscreen API]
-   * (http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api) from
-   * WebPlatform.org.
-   * * [Fullscreen specification]
-   * (http://www.w3.org/TR/fullscreen/) from W3C.
+   * * [Using the fullscreen
+   *   API](http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api)
+   *   from WebPlatform.org.
+   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.
    */
   @DomName('Document.webkitFullscreenElement')
   @SupportedBrowser(SupportedBrowser.CHROME)
@@ -20243,11 +20227,10 @@
    *
    * ## Other resources
    *
-   * * [Using the fullscreen API]
-   * (http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api) from
-   * WebPlatform.org.
-   * * [Fullscreen specification]
-   * (http://www.w3.org/TR/fullscreen/) from W3C.
+   * * [Using the fullscreen
+   *   API](http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api)
+   *   from WebPlatform.org.
+   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.
    */
   @DomName('Document.webkitFullscreenEnabled')
   @SupportedBrowser(SupportedBrowser.CHROME)
@@ -21903,7 +21886,8 @@
    * 'text'. Some newer browsers will throw NS_ERROR_DOM_INVALID_ACCESS_ERR if
    * `responseType` is set while performing a synchronous request.
    *
-   * See also: [MDN responseType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType)
+   * See also: [MDN
+   * responseType](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-responsetype)
    */
   @DomName('XMLHttpRequest.responseType')
   @DocsEditable()
@@ -21917,7 +21901,8 @@
    * 'text'. Some newer browsers will throw NS_ERROR_DOM_INVALID_ACCESS_ERR if
    * `responseType` is set while performing a synchronous request.
    *
-   * See also: [MDN responseType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType)
+   * See also: [MDN
+   * responseType](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-responsetype)
    */
   @DomName('XMLHttpRequest.responseType')
   @DocsEditable()
@@ -21940,8 +21925,8 @@
   Document get responseXml => wrap_jso(_blink.BlinkXMLHttpRequest.instance.responseXML_Getter_(unwrap_jso(this)));
   
   /**
-   * The http result code from the request (200, 404, etc).
-   * See also: [Http Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
+   * The HTTP result code from the request (200, 404, etc).
+   * See also: [HTTP Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
    */
   @DomName('XMLHttpRequest.status')
   @DocsEditable()
@@ -21949,7 +21934,7 @@
   
   /**
    * The request response string (such as \"200 OK\").
-   * See also: [Http Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
+   * See also: [HTTP Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
    */
   @DomName('XMLHttpRequest.statusText')
   @DocsEditable()
@@ -21964,12 +21949,10 @@
    *
    * ## Other resources
    *
-   * * [XMLHttpRequest.timeout]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#timeout)
-   * from MDN.
-   * * [The timeout attribute]
-   * (http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute)
-   * from W3C.
+   * * [XMLHttpRequest.timeout](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-timeout)
+   *   from MDN.
+   * * [The timeout attribute](http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute)
+   *   from W3C.
    */
   @DomName('XMLHttpRequest.timeout')
   @DocsEditable()
@@ -21985,12 +21968,10 @@
    *
    * ## Other resources
    *
-   * * [XMLHttpRequest.timeout]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#timeout)
-   * from MDN.
-   * * [The timeout attribute]
-   * (http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute)
-   * from W3C.
+   * * [XMLHttpRequest.timeout](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-timeout)
+   *   from MDN.
+   * * [The timeout attribute](http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute)
+   *   from W3C.
    */
   @DomName('XMLHttpRequest.timeout')
   @DocsEditable()
@@ -22044,7 +22025,8 @@
    * `getAllResponseHeaders` will return the response headers for the current
    * part of the request.
    *
-   * See also [HTTP response headers](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)
+   * See also [HTTP response
+   * headers](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Response_fields)
    * for a list of common response headers.
    */
   @DomName('XMLHttpRequest.getAllResponseHeaders')
@@ -22055,7 +22037,8 @@
   /**
    * Return the response header named `header`, or null if not found.
    *
-   * See also [HTTP response headers](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)
+   * See also [HTTP response
+   * headers](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Response_fields)
    * for a list of common response headers.
    */
   @DomName('XMLHttpRequest.getResponseHeader')
@@ -22068,7 +22051,7 @@
    * response.
    *
    * This value must be set before the request has been sent. See also the list
-   * of [common MIME types](http://en.wikipedia.org/wiki/Internet_media_type#List_of_common_media_types)
+   * of [IANA Official MIME types](https://www.iana.org/assignments/media-types/media-types.xhtml)
    */
   @DomName('XMLHttpRequest.overrideMimeType')
   @DocsEditable()
@@ -22087,9 +22070,8 @@
    *
    * ## Other resources
    *
-   * * [XMLHttpRequest.send]
-   * (https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)
-   * from MDN.
+   * * [XMLHttpRequest.send](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)
+   *   from MDN.
    */
   @DomName('XMLHttpRequest.send')
   @DocsEditable()
@@ -22106,12 +22088,11 @@
    *
    * ## Other resources
    *
-   * * [XMLHttpRequest.setRequestHeader]
-   * (https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)
-   * from MDN.
-   * * [The setRequestHeader() method]
-   * (http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader()-method) from
-   * W3C.
+   * * [XMLHttpRequest.setRequestHeader](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#setRequestHeader())
+   *   from MDN.
+   * * [The setRequestHeader()
+   *   method](http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader()-method)
+   *   from W3C.
    */
   @DomName('XMLHttpRequest.setRequestHeader')
   @DocsEditable()
@@ -28425,9 +28406,8 @@
    *
    * ## Other resources
    *
-   * * [Node.childNodes]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.childNodes)
-   * from MDN.
+   * * [Node.childNodes](https://developer.mozilla.org/en-US/docs/Web/API/Node.childNodes)
+   *   from MDN.
    */
   @DomName('Node.childNodes')
   @DocsEditable()
@@ -28506,9 +28486,8 @@
    *
    * ## Other resources
    *
-   * * [Node.firstChild]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.firstChild)
-   * from MDN.
+   * * [Node.firstChild](https://developer.mozilla.org/en-US/docs/Web/API/Node.firstChild)
+   *   from MDN.
    */
   @DomName('Node.firstChild')
   @DocsEditable()
@@ -28519,9 +28498,8 @@
    *
    * ## Other resources
    *
-   * * [Node.lastChild]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.lastChild)
-   * from MDN.
+   * * [Node.lastChild](https://developer.mozilla.org/en-US/docs/Web/API/Node.lastChild)
+   *   from MDN.
    */
   @DomName('Node.lastChild')
   @DocsEditable()
@@ -28540,9 +28518,8 @@
    *
    * ## Other resources
    *
-   * * [Node.nextSibling]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nextSibling)
-   * from MDN.
+   * * [Node.nextSibling](https://developer.mozilla.org/en-US/docs/Web/API/Node.nextSibling)
+   *   from MDN.
    */
   @DomName('Node.nextSibling')
   @DocsEditable()
@@ -28555,10 +28532,9 @@
    *
    * ## Other resources
    *
-   * * [Node.nodeName]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeName)
-   * from MDN. This page contains a table of [nodeName] values for each
-   * [nodeType].
+   * * [Node.nodeName](https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeName)
+   *   from MDN. This page contains a table of [nodeName] values for each
+   *   [nodeType].
    */
   @DomName('Node.nodeName')
   @DocsEditable()
@@ -28584,8 +28560,8 @@
    *
    * ## Other resources
    *
-   * * [Node.nodeType]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeType) from MDN.
+   * * [Node.nodeType](https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeType)
+   *   from MDN.
    */
   @DomName('Node.nodeType')
   @DocsEditable()
@@ -28598,10 +28574,9 @@
    *
    * ## Other resources
    *
-   * * [Node.nodeValue]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeValue)
-   * from MDN. This page contains a table of [nodeValue] values for each
-   * [nodeType].
+   * * [Node.nodeValue](https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeValue)
+   *   from MDN. This page contains a table of [nodeValue] values for each
+   *   [nodeType].
    */
   @DomName('Node.nodeValue')
   @DocsEditable()
@@ -28614,9 +28589,8 @@
    *
    * ## Other resources
    *
-   * * [Node.ownerDocument]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.ownerDocument) from
-   * MDN.
+   * * [Node.ownerDocument](https://developer.mozilla.org/en-US/docs/Web/API/Node.ownerDocument)
+   *   from MDN.
    */
   @DomName('Node.ownerDocument')
   @DocsEditable()
@@ -28630,9 +28604,8 @@
    *
    * ## Other resources
    *
-   * * [Node.parentElement]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.parentElement) from
-   * W3C.
+   * * [Node.parentElement](https://developer.mozilla.org/en-US/docs/Web/API/Node.parentElement)
+   *   from W3C.
    */
   @DomName('Node.parentElement')
   @DocsEditable()
@@ -28643,9 +28616,8 @@
    *
    * ## Other resources
    *
-   * * [Node.parentNode]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.parentNode) from
-   * MDN.
+   * * [Node.parentNode](https://developer.mozilla.org/en-US/docs/Web/API/Node.parentNode)
+   *   from MDN.
    */
   @DomName('Node.parentNode')
   @DocsEditable()
@@ -28656,9 +28628,8 @@
    *
    * ## Other resources
    *
-   * * [Node.previousSibling]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.previousSibling)
-   * from MDN.
+   * * [Node.previousSibling](https://developer.mozilla.org/en-US/docs/Web/API/Node.previousSibling)
+   *   from MDN.
    */
   @DomName('Node.previousSibling')
   @DocsEditable()
@@ -28669,9 +28640,8 @@
    *
    * ## Other resources
    *
-   * * [Node.textContent]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.textContent) from
-   * MDN.
+   * * [Node.textContent](https://developer.mozilla.org/en-US/docs/Web/API/Node.textContent)
+   *   from MDN.
    */
   @DomName('Node.textContent')
   @DocsEditable()
@@ -28682,9 +28652,8 @@
    *
    * ## Other resources
    *
-   * * [Node.textContent]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.textContent) from
-   * MDN.
+   * * [Node.textContent](https://developer.mozilla.org/en-US/docs/Web/API/Node.textContent)
+   *   from MDN.
    */
   @DomName('Node.textContent')
   @DocsEditable()
@@ -28711,9 +28680,8 @@
    *
    * ## Other resources
    *
-   * * [Node.cloneNode]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.cloneNode) from
-   * MDN.
+   * * [Node.cloneNode](https://developer.mozilla.org/en-US/docs/Web/API/Node.cloneNode)
+   *   from MDN.
    */
   @DomName('Node.cloneNode')
   @DocsEditable()
@@ -28724,8 +28692,8 @@
    *
    * ## Other resources
    *
-   * * [Node.contains]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.contains) from MDN.
+   * * [Node.contains](https://developer.mozilla.org/en-US/docs/Web/API/Node.contains)
+   *   from MDN.
    */
   @DomName('Node.contains')
   @DocsEditable()
@@ -28736,9 +28704,8 @@
    *
    * ## Other resources
    *
-   * * [Node.hasChildNodes]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.hasChildNodes) from
-   * MDN.
+   * * [Node.hasChildNodes](https://developer.mozilla.org/en-US/docs/Web/API/Node.hasChildNodes)
+   *   from MDN.
    */
   @DomName('Node.hasChildNodes')
   @DocsEditable()
@@ -28749,9 +28716,8 @@
    *
    * ## Other resources
    *
-   * * [Node.insertBefore]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.insertBefore) from
-   * MDN.
+   * * [Node.insertBefore](https://developer.mozilla.org/en-US/docs/Web/API/Node.insertBefore)
+   *   from MDN.
    */
   @DomName('Node.insertBefore')
   @DocsEditable()
@@ -39242,10 +39208,11 @@
    *
    * ## Other resources
    *
-   * * [Exploring the FileSystem APIs]
-   * (http://www.html5rocks.com/en/tutorials/file/filesystem/) from HTML5Rocks.
-   * * [File API]
-   * (http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem) from W3C.
+   * * [Exploring the FileSystem
+   *   APIs](http://www.html5rocks.com/en/tutorials/file/filesystem/)
+   *   from HTML5Rocks.
+   * * [File API](http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem)
+   *   from W3C.
    */
   @DomName('Window.PERSISTENT')
   @DocsEditable()
@@ -39258,10 +39225,10 @@
    *
    * ## Other resources
    *
-   * * [Exploring the FileSystem APIs]
-   * (http://www.html5rocks.com/en/tutorials/file/filesystem/) from HTML5Rocks.
-   * * [File API]
-   * (http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem) from W3C.
+   * * [Exploring the FileSystem
+   *   APIs](http://www.html5rocks.com/en/tutorials/file/filesystem/) from HTML5Rocks.
+   * * [File API](http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem)
+   *   from W3C.
    */
   @DomName('Window.TEMPORARY')
   @DocsEditable()
@@ -39285,11 +39252,12 @@
    *
    * ## Other resources
    *
-   * * [A beginner's guide to using the application cache]
-   * (http://www.html5rocks.com/en/tutorials/appcache/beginner) from HTML5Rocks.
-   * * [Application cache API]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/offline.html#application-cache-api)
-   * from WHATWG.
+   * * [A beginner's guide to using the application
+   *   cache](http://www.html5rocks.com/en/tutorials/appcache/beginner)
+   *   from HTML5Rocks.
+   * * [Application cache
+   *   API](https://html.spec.whatwg.org/multipage/browsers.html#application-cache-api)
+   *   from WHATWG.
    */
   @DomName('Window.applicationCache')
   @DocsEditable()
@@ -39345,12 +39313,10 @@
    *
    * ## Other resources
    *
-   * * [devicePixelRatio]
-   * (http://www.quirksmode.org/blog/archives/2012/06/devicepixelrati.html) from
-   * quirksmode.
-   * * [More about devicePixelRatio]
-   * (http://www.quirksmode.org/blog/archives/2012/07/more_about_devi.html) from
-   * quirksmode.
+   * * [devicePixelRatio](http://www.quirksmode.org/blog/archives/2012/06/devicepixelrati.html)
+   *   from quirksmode.
+   * * [More about devicePixelRatio](http://www.quirksmode.org/blog/archives/2012/07/more_about_devi.html)
+   *   from quirksmode.
    */
   @DomName('Window.devicePixelRatio')
   @DocsEditable()
@@ -39367,9 +39333,8 @@
    *
    * ## Other resources
    *
-   * * [Loading web pages]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html)
-   * from WHATWG.
+   * * [Loading web pages](https://html.spec.whatwg.org/multipage/browsers.html)
+   *   from WHATWG.
    */
   @DomName('Window.history')
   @DocsEditable()
@@ -39388,9 +39353,8 @@
    *
    * ## Other resources
    *
-   * * [innerHeight]
-   * (http://docs.webplatform.org/wiki/css/cssom/properties/innerHeight) from
-   * WebPlatform.org.
+   * * [innerHeight](http://docs.webplatform.org/wiki/css/cssom/properties/innerHeight)
+   *   from WebPlatform.org.
    */
   @DomName('Window.innerHeight')
   @DocsEditable()
@@ -39401,9 +39365,8 @@
    *
    * ## Other resources
    *
-   * * [innerWidth]
-   * (http://docs.webplatform.org/wiki/css/cssom/properties/innerWidth) from
-   * WebPlatform.org.
+   * * [innerWidth](http://docs.webplatform.org/wiki/css/cssom/properties/innerWidth)
+   *   from WebPlatform.org.
    */
   @DomName('Window.innerWidth')
   @DocsEditable()
@@ -39414,13 +39377,12 @@
    *
    * ## Other resources
    *
-   * * [DOM storage guide]
-   * (https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage) from
-   * MDN.
-   * * [The past, present & future of local storage for web applications]
-   * (http://diveintohtml5.info/storage.html) from Dive Into HTML5.
-   * * [Local storage specification]
-   * (http://www.w3.org/TR/webstorage/#the-localstorage-attribute) from W3C.
+   * * [DOM storage guide](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage)
+   *   from MDN.
+   * * [The past, present & future of local storage for web
+   *   applications](http://diveintohtml5.info/storage.html) from Dive Into HTML5.
+   * * [Local storage specification](http://www.w3.org/TR/webstorage/#the-localstorage-attribute)
+   *   from W3C.
    */
   @DomName('Window.localStorage')
   @DocsEditable()
@@ -39435,9 +39397,9 @@
    *
    * ## Other resources
    *
-   * * [Browser interface elements]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
-   * from WHATWG.
+   * * [Browser interface
+   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
+   *   from WHATWG.
    */
   @DomName('Window.locationbar')
   @DocsEditable()
@@ -39448,9 +39410,9 @@
    *
    * ## Other resources
    *
-   * * [Browser interface elements]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
-   * from WHATWG.
+   * * [Browser interface
+   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
+   *   from WHATWG.
    */
   @DomName('Window.menubar')
   @DocsEditable()
@@ -39461,9 +39423,8 @@
    *
    * ## Other resources
    *
-   * * [Window name]
-   * (http://docs.webplatform.org/wiki/html/attributes/name_(window)) from
-   * WebPlatform.org.
+   * * [Window name](http://docs.webplatform.org/wiki/html/attributes/name_(window))
+   *   from WebPlatform.org.
    */
   @DomName('Window.name')
   @DocsEditable()
@@ -39474,9 +39435,8 @@
    *
    * ## Other resources
    *
-   * * [Window name]
-   * (http://docs.webplatform.org/wiki/html/attributes/name_(window)) from
-   * WebPlatform.org.
+   * * [Window name](http://docs.webplatform.org/wiki/html/attributes/name_(window))
+   *   from WebPlatform.org.
    */
   @DomName('Window.name')
   @DocsEditable()
@@ -39487,9 +39447,9 @@
    *
    * ## Other resources
    *
-   * * [The navigator object]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#the-navigator-object)
-   * from WHATWG.
+   * * [The navigator
+   *   object](https://html.spec.whatwg.org/multipage/webappapis.html#the-navigator-object)
+   *   from WHATWG.
    */
   @DomName('Window.navigator')
   @DocsEditable()
@@ -39500,9 +39460,8 @@
    *
    * ## Other resources
    *
-   * * [offscreenBuffering]
-   * (http://docs.webplatform.org/wiki/dom/properties/offscreenBuffering) from
-   * WebPlatform.org.
+   * * [offscreenBuffering](http://docs.webplatform.org/wiki/dom/properties/offscreenBuffering)
+   *   from WebPlatform.org.
    */
   @DomName('Window.offscreenBuffering')
   @DocsEditable()
@@ -39527,9 +39486,8 @@
    *
    * ## Other resources
    *
-   * * [outerHeight]
-   * (http://docs.webplatform.org/wiki/css/cssom/properties/outerHeight) from
-   * WebPlatform.org.
+   * * [outerHeight](http://docs.webplatform.org/wiki/css/cssom/properties/outerHeight)
+   *   from WebPlatform.org.
    */
   @DomName('Window.outerHeight')
   @DocsEditable()
@@ -39540,9 +39498,8 @@
    *
    * ## Other resources
    *
-   * * [outerWidth]
-   * (http://docs.webplatform.org/wiki/css/cssom/properties/outerWidth) from
-   * WebPlatform.org.
+   * * [outerWidth](http://docs.webplatform.org/wiki/css/cssom/properties/outerWidth)
+   *   from WebPlatform.org.
    */
   @DomName('Window.outerWidth')
   @DocsEditable()
@@ -39555,10 +39512,11 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
-   * * [scrollX and pageXOffset]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX) from MDN.
+   * * [The Screen interface
+   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [scrollX and
+   *   pageXOffset](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX)
+   *   from MDN.
    */
   @DomName('Window.pageXOffset')
   @DocsEditable()
@@ -39571,10 +39529,11 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
-   * * [scrollY and pageYOffset]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY) from MDN.
+   * * [The Screen interface
+   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [scrollY and
+   *   pageYOffset](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY)
+   *   from MDN.
    */
   @DomName('Window.pageYOffset')
   @DocsEditable()
@@ -39589,11 +39548,11 @@
    *
    * ## Other resources
    *
-   * * [Measuring page load speed with navigation timeing]
-   * (http://www.html5rocks.com/en/tutorials/webperformance/basics/) from
-   * HTML5Rocks.
-   * * [Navigation timing specification]
-   * (http://www.w3.org/TR/navigation-timing/) from W3C.
+   * * [Measuring page load speed with navigation
+   *   timeing](http://www.html5rocks.com/en/tutorials/webperformance/basics/)
+   *   from HTML5Rocks.
+   * * [Navigation timing
+   *   specification](http://www.w3.org/TR/navigation-timing/) from W3C.
    */
   @DomName('Window.performance')
   @DocsEditable()
@@ -39607,8 +39566,8 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
+   *   from W3C.
    */
   @DomName('Window.screen')
   @DocsEditable()
@@ -39620,8 +39579,8 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
+   *   from W3C.
    */
   @DomName('Window.screenLeft')
   @DocsEditable()
@@ -39632,8 +39591,8 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
+   *   from W3C.
    */
   @DomName('Window.screenTop')
   @DocsEditable()
@@ -39644,8 +39603,8 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
+   *   from W3C.
    */
   @DomName('Window.screenX')
   @DocsEditable()
@@ -39656,8 +39615,8 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
+   *   from W3C.
    */
   @DomName('Window.screenY')
   @DocsEditable()
@@ -39676,9 +39635,9 @@
    *
    * ## Other resources
    *
-   * * [Browser interface elements]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
-   * from WHATWG.
+   * * [Browser interface
+   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
+   *   from WHATWG.
    */
   @DomName('Window.scrollbars')
   @DocsEditable()
@@ -39689,8 +39648,8 @@
    *
    * ## Other resources
    *
-   * * [Window.self]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.self) from MDN.
+   * * [Window.self](https://developer.mozilla.org/en-US/docs/Web/API/Window.self)
+   *   from MDN.
    */
   @DomName('Window.self')
   @DocsEditable()
@@ -39701,13 +39660,13 @@
    *
    * ## Other resources
    *
-   * * [DOM storage guide]
-   * (https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage) from
-   * MDN.
-   * * [The past, present & future of local storage for web applications]
-   * (http://diveintohtml5.info/storage.html) from Dive Into HTML5.
-   * * [Local storage specification]
-   * (http://www.w3.org/TR/webstorage/#dom-sessionstorage) from W3C.
+   * * [DOM storage
+   *   guide](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage)
+   *   from MDN.
+   * * [The past, present & future of local storage for web
+   *   applications](http://diveintohtml5.info/storage.html) from Dive Into HTML5.
+   * * [Local storage
+   *   specification](http://www.w3.org/TR/webstorage/#dom-sessionstorage) from W3C.
    */
   @DomName('Window.sessionStorage')
   @DocsEditable()
@@ -39718,9 +39677,9 @@
    *
    * ## Other resources
    *
-   * * [Web speech specification]
-   * (https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section)
-   * from W3C.
+   * * [Web speech
+   *   specification](https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section)
+   *   from W3C.
    */
   @DomName('Window.speechSynthesis')
   @DocsEditable()
@@ -39743,9 +39702,9 @@
    *
    * ## Other resources
    *
-   * * [Browser interface elements]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
-   * from WHATWG.
+   * * [Browser interface
+   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
+   *   from WHATWG.
    */
   @DomName('Window.statusbar')
   @DocsEditable()
@@ -39756,9 +39715,9 @@
    *
    * ## Other resources
    *
-   * * [StyleMedia class reference]
-   * (https://developer.apple.com/library/safari/documentation/SafariDOMAdditions/Reference/StyleMedia/StyleMedia/StyleMedia.html)
-   * from Safari Developer Library.
+   * * [StyleMedia class
+   *   reference](https://developer.apple.com/library/safari/documentation/SafariDOMAdditions/Reference/StyleMedia/)
+   *   from Safari Developer Library.
    */
   @DomName('Window.styleMedia')
   @DocsEditable()
@@ -39771,9 +39730,9 @@
    *
    * ## Other resources
    *
-   * * [Browser interface elements]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
-   * from WHATWG.
+   * * [Browser interface
+   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
+   *   from WHATWG.
    */
   @DomName('Window.toolbar')
   @DocsEditable()
@@ -39788,8 +39747,8 @@
    *
    * ## Other resources
    *
-   * * [Window.window]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.window) from MDN.
+   * * [Window.window](https://developer.mozilla.org/en-US/docs/Web/API/Window.window)
+   *   from MDN.
    */
   @DomName('Window.window')
   @DocsEditable()
@@ -39834,8 +39793,8 @@
    *
    * ## Other resources
    *
-   * * [Window.find]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.find) from MDN.
+   * * [Window.find](https://developer.mozilla.org/en-US/docs/Web/API/Window.find)
+   *   from MDN.
    */
   @DomName('Window.find')
   @DocsEditable()
@@ -39859,9 +39818,8 @@
    *
    * ## Other resources
    *
-   * * [Window.getSelection]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.getSelection)
-   * from MDN.
+   * * [Window.getSelection](https://developer.mozilla.org/en-US/docs/Web/API/Window.getSelection)
+   *   from MDN.
    */
   @DomName('Window.getSelection')
   @DocsEditable()
@@ -39872,11 +39830,11 @@
    *
    * ## Other resources
    *
-   * * [Testing media queries]
-   * (https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Testing_media_queries)
-   * from MDN.
-   * * [The MediaQueryList specification]
-   * (http://www.w3.org/TR/cssom-view/#the-mediaquerylist-interface) from W3C.
+   * * [Testing media
+   *   queries](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Testing_media_queries)
+   *   from MDN.
+   * * [The MediaQueryList
+   *   specification](http://www.w3.org/TR/cssom-view/#the-mediaquerylist-interface) from W3C.
    */
   @DomName('Window.matchMedia')
   @DocsEditable()
@@ -39889,10 +39847,9 @@
    *
    * ## Other resources
    *
-   * * [Window.moveBy]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.moveBy) from MDN.
-   * * [Window.moveBy]
-   * (http://dev.w3.org/csswg/cssom-view/#dom-window-moveby) from W3C.
+   * * [Window.moveBy](https://developer.mozilla.org/en-US/docs/Web/API/Window.moveBy)
+   *   from MDN.
+   * * [Window.moveBy](http://dev.w3.org/csswg/cssom-view/#dom-window-moveby) from W3C.
    */
   @DomName('Window.moveBy')
   @DocsEditable()
@@ -39922,8 +39879,8 @@
    *
    * ## Other resources
    *
-   * * [Window.print]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.print) from MDN.
+   * * [Window.print](https://developer.mozilla.org/en-US/docs/Web/API/Window.print)
+   *   from MDN.
    */
   @DomName('Window.print')
   @DocsEditable()
@@ -39938,8 +39895,8 @@
    *
    * ## Other resources
    *
-   * * [Window resizeBy] (http://docs.webplatform.org/wiki/dom/methods/resizeBy)
-   * from WebPlatform.org.
+   * * [Window resizeBy](http://docs.webplatform.org/wiki/dom/methods/resizeBy)
+   *   from WebPlatform.org.
    */
   @DomName('Window.resizeBy')
   @DocsEditable()
@@ -39950,8 +39907,8 @@
    *
    * ## Other resources
    *
-   * * [Window resizeTo] (http://docs.webplatform.org/wiki/dom/methods/resizeTo)
-   * from WebPlatform.org.
+   * * [Window resizeTo](http://docs.webplatform.org/wiki/dom/methods/resizeTo)
+   *   from WebPlatform.org.
    */
   @DomName('Window.resizeTo')
   @DocsEditable()
@@ -40022,9 +39979,9 @@
    *
    * ## Other resources
    *
-   * * [Dialogs implemented using separate documents]
-   * (http://www.w3.org/html/wg/drafts/html/master/webappapis.html#dialogs-implemented-using-separate-documents)
-   * from W3C.
+   * * [Dialogs implemented using separate
+   *   documents](http://www.w3.org/html/wg/drafts/html/master/webappapis.html#dialogs-implemented-using-separate-documents)
+   *   from W3C.
    */
   @DomName('Window.showModalDialog')
   @DocsEditable()
@@ -40035,9 +39992,9 @@
    *
    * ## Other resources
    *
-   * * [The Window object]
-   * (http://www.w3.org/html/wg/drafts/html/master/browsers.html#the-window-object)
-   * from W3C.
+   * * [The Window
+   *   object](http://www.w3.org/html/wg/drafts/html/master/browsers.html#the-window-object)
+   *   from W3C.
    */
   @DomName('Window.stop')
   @DocsEditable()
@@ -43887,12 +43844,11 @@
  *
  * ## Other resources
  *
- * * [Image sources for 2D rendering contexts]
- * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#image-sources-for-2d-rendering-contexts)
- * from WHATWG.
- * * [Drawing images]
- * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
- * from WHATWG.
+ * * [Image sources for 2D rendering
+ *   contexts](https://html.spec.whatwg.org/multipage/scripting.html#image-sources-for-2d-rendering-contexts)
+ *   from WHATWG.
+ * * [Drawing images](https://html.spec.whatwg.org/multipage/scripting.html#dom-context-2d-drawimage)
+ *   from WHATWG.
  */
 abstract class CanvasImageSource {}
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -43935,9 +43891,9 @@
    *
    * ## Other resources
    *
-   * * [Session history and navigation specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html)
-   * from WHATWG.
+   * * [Session history and navigation
+   *   specification](https://html.spec.whatwg.org/multipage/browsers.html#history)
+   *   from WHATWG.
    */
   HistoryBase get history;
 
@@ -44030,12 +43986,10 @@
    *
    * ## Other resources
    *
-   * * [window.postMessage]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage) from
-   * MDN.
-   * * [Cross-document messaging]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/web-messaging.html)
-   * from WHATWG.
+   * * [window.postMessage](https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage)
+   *   from MDN.
+   * * [Cross-document messaging](https://html.spec.whatwg.org/multipage/comms.html#web-messaging)
+   *   from WHATWG.
    */
   void postMessage(var message, String targetOrigin, [List messagePorts]);
 }
@@ -44710,9 +44664,8 @@
    *
    * ## Other resources
    *
-   * * [Event Capture]
-   * (http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture)
-   * from the W3C DOM Events specification.
+   * * [Event Capture](http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture)
+   *   from the W3C DOM Events specification.
    */
   StreamSubscription<T> capture(void onData(T event));
 }
@@ -48110,9 +48063,9 @@
    *
    * ## Other resources
    *
-   * * [Shadow DOM extensions to Event]
-   * (http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event) from
-   * W3C.
+   * * [Shadow DOM extensions to
+   *   Event](http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event)
+   *   from W3C.
    */
   // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#extensions-to-event
   @Experimental()
@@ -48463,6 +48416,9 @@
       // 'this' needs to be handled by calling Dart_EvaluateExpr with
       // 'this' as the target rather than by passing it as an argument.
       if (arg == 'this') return;
+      // Avoid being broken by bogus ':async_op' local passed in when within
+      // an async method.
+      if (arg.startsWith(':')) return;
       if (args.isNotEmpty) {
         sb.write(", ");
       }
diff --git a/sdk/lib/html/html_common/conversions_dartium.dart b/sdk/lib/html/html_common/conversions_dartium.dart
index 56ed9d5..2403387 100644
--- a/sdk/lib/html/html_common/conversions_dartium.dart
+++ b/sdk/lib/html/html_common/conversions_dartium.dart
@@ -121,7 +121,7 @@
 
     var wrapper = js.getDartHtmlWrapperFor(jsObject);
     // if we have a wrapper return the Dart instance.
-    if (wrapper != null && wrapper is! js.JsObject) {
+    if (wrapper != null) {
       return wrapper;
     }
 
@@ -236,6 +236,13 @@
       return wrapper;
     }
 
+    // TODO(jacobr): auomatically wrapping JsArray here is fundamentally broken
+    // as it hijacks adding custom methods on JS Array classes as part of the
+    // new typed DartJsInterop.
+    // To make this work we really need to make DartHtmlWrappingList extend
+    // JsArrayImpl. Fixing this issue needs to be part of a broader refactor
+    // that allows calling custom typed JS interop methods on all dart:html
+    // classes.
     if (jsObject is js.JsArray) {
       var wrappingList = new DartHtmlWrappingList(jsObject);
       js.setDartHtmlWrapperFor(jsObject, wrappingList);
@@ -380,7 +387,7 @@
 
   final js.JsArray blink_jsObject;
 
-  operator [](int index) => wrap_jso(js.JsNative.getArrayIndex(blink_jsObject, index));
+  operator [](int index) => wrap_jso_no_SerializedScriptvalue(js.JsNative.getArrayIndex(blink_jsObject, index));
 
   operator []=(int index, value) => blink_jsObject[index] = value;
 
diff --git a/sdk/lib/internal/iterable.dart b/sdk/lib/internal/iterable.dart
index 47c94f8..9a5f29f 100644
--- a/sdk/lib/internal/iterable.dart
+++ b/sdk/lib/internal/iterable.dart
@@ -465,9 +465,6 @@
 
   ExpandIterator(this._iterator, Iterable<T> this._f(S element));
 
-  void _nextExpansion() {
-  }
-
   T get current => _current;
 
   bool moveNext() {
diff --git a/sdk/lib/io/directory.dart b/sdk/lib/io/directory.dart
index 8005726..2ff3928 100644
--- a/sdk/lib/io/directory.dart
+++ b/sdk/lib/io/directory.dart
@@ -100,16 +100,16 @@
  * ## Other resources
  *
  * * [Dart by Example](https://www.dartlang.org/dart-by-example/#files-directories-and-symlinks)
- * provides additional task-oriented code samples that show how to use
- * various API from the Directory class and the related [File] class.
+ *   provides additional task-oriented code samples that show how to use
+ *   various API from the Directory class and the related [File] class.
  *
- * * [I/O for Command-Line Apps](https://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-dartio---file-and-socket-io-for-command-line-apps)
- * a section from _A Tour of the Dart Libraries_
- * covers files and directories.
+ * * [I/O for Command-Line
+ *   Apps](https://www.dartlang.org/docs/dart-up-and-running/ch03.html#dartio---io-for-command-line-apps)
+ *   a section from _A Tour of the Dart Libraries_ covers files and directories.
  *
  * * [Write Command-Line Apps](https://www.dartlang.org/docs/tutorials/cmdline/),
- * a tutorial about writing command-line apps, includes information
- * about files and directories.
+ *   a tutorial about writing command-line apps, includes information about
+ *   files and directories.
  */
 abstract class Directory implements FileSystemEntity {
   /**
diff --git a/sdk/lib/io/file.dart b/sdk/lib/io/file.dart
index 691d783..d9b2cb4 100644
--- a/sdk/lib/io/file.dart
+++ b/sdk/lib/io/file.dart
@@ -184,17 +184,16 @@
  * ## Other resources
  *
  * * [Dart by Example](https://www.dartlang.org/dart-by-example/#files-directories-and-symlinks)
- * provides additional task-oriented code samples that show how to use
- * various API from the Directory class and the related [File] class.
+ *   provides additional task-oriented code samples that show how to use
+ *   various API from the Directory class and the related [File] class.
  *
- * * [I/O for Command-Line Apps](https://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-dartio---file-and-socket-io-for-command-line-apps)
- * a section from _A Tour of the Dart Libraries_
- * covers files and directories.
+ * * [I/O for Command-Line
+ *   Apps](https://www.dartlang.org/docs/dart-up-and-running/ch03.html#dartio---io-for-command-line-apps)
+ *   a section from _A Tour of the Dart Libraries_ covers files and directories.
  *
  * * [Write Command-Line Apps](https://www.dartlang.org/docs/tutorials/cmdline/),
- * a tutorial about writing command-line apps, includes information
- * about files and directories.
-
+ *   a tutorial about writing command-line apps, includes information about
+ *   files and directories.
  */
 abstract class File implements FileSystemEntity {
   /**
diff --git a/sdk/lib/io/file_system_entity.dart b/sdk/lib/io/file_system_entity.dart
index 7e8b0dd..f39eafd 100644
--- a/sdk/lib/io/file_system_entity.dart
+++ b/sdk/lib/io/file_system_entity.dart
@@ -197,19 +197,19 @@
  *
  * ## Other resources
  *
- * [Dart by Example](https://www.dartlang.org/dart-by-example/#files-directories-and-symlinks)
- * provides additional task-oriented code samples that show how to use
- * various API from the [Directory] class and the [File] class,
- * both subclasses of FileSystemEntity.
+ * * [Dart by
+ *   Example](https://www.dartlang.org/dart-by-example/#files-directories-and-symlinks)
+ *   provides additional task-oriented code samples that show how to use various
+ *   API from the [Directory] class and the [File] class, both subclasses of
+ *   FileSystemEntity.
  *
- * * [I/O for Command-Line Apps](https://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-dartio---file-and-socket-io-for-command-line-apps)
- * a section from _A Tour of the Dart Libraries_
- * covers files and directories.
+ * * [I/O for Command-Line
+ *   Apps](https://www.dartlang.org/docs/dart-up-and-running/ch03.html#dartio---io-for-command-line-apps),
+ *   a section from _A Tour of the Dart Libraries_ covers files and directories.
  *
  * * [Write Command-Line Apps](https://www.dartlang.org/docs/tutorials/cmdline/),
- * a tutorial about writing command-line apps, includes information
- * about files and directories.
-
+ *   a tutorial about writing command-line apps, includes information about
+ *   files and directories.
  */
 abstract class FileSystemEntity {
   String get path;
diff --git a/sdk/lib/io/http.dart b/sdk/lib/io/http.dart
index deae6dc..c63d28b 100644
--- a/sdk/lib/io/http.dart
+++ b/sdk/lib/io/http.dart
@@ -683,9 +683,11 @@
    */
   static HeaderValue parse(String value,
                            {String parameterSeparator: ";",
+                            String valueSeparator: null,
                             bool preserveBackslash: false}) {
     return _HeaderValue.parse(value,
                               parameterSeparator: parameterSeparator,
+                              valueSeparator: valueSeparator,
                               preserveBackslash: preserveBackslash);
   }
 
diff --git a/sdk/lib/io/http_date.dart b/sdk/lib/io/http_date.dart
index 9bf8197..7f69613 100644
--- a/sdk/lib/io/http_date.dart
+++ b/sdk/lib/io/http_date.dart
@@ -72,8 +72,8 @@
    *     Thursday, 1-Jan-1970 00:00:00 GMT
    *     Thu Jan  1 00:00:00 1970
    *
-   * For more information see [RFC-2616 section 3.1.1]
-   * (http://tools.ietf.org/html/rfc2616#section-3.3.1
+   * For more information see [RFC-2616 section
+   * 3.1.1](http://tools.ietf.org/html/rfc2616#section-3.3.1
    * "RFC-2616 section 3.1.1").
    */
   static DateTime parse(String date) {
diff --git a/sdk/lib/io/http_headers.dart b/sdk/lib/io/http_headers.dart
index 4700128..676e4a8 100644
--- a/sdk/lib/io/http_headers.dart
+++ b/sdk/lib/io/http_headers.dart
@@ -630,10 +630,11 @@
 
   static _HeaderValue parse(String value,
                             {parameterSeparator: ";",
+                             valueSeparator: null,
                              preserveBackslash: false}) {
     // Parse the string.
     var result = new _HeaderValue();
-    result._parse(value, parameterSeparator, preserveBackslash);
+    result._parse(value, parameterSeparator, valueSeparator, preserveBackslash);
     return result;
   }
 
@@ -664,7 +665,10 @@
     return sb.toString();
   }
 
-  void _parse(String s, String parameterSeparator, bool preserveBackslash) {
+  void _parse(String s,
+        String parameterSeparator,
+        String valueSeparator,
+        bool preserveBackslash) {
     int index = 0;
 
     bool done() => index == s.length;
@@ -681,6 +685,7 @@
       while (!done()) {
         if (s[index] == " " ||
             s[index] == "\t" ||
+            s[index] == valueSeparator ||
             s[index] == parameterSeparator) break;
         index++;
       }
@@ -705,14 +710,17 @@
       String parseParameterName() {
         int start = index;
         while (!done()) {
-          if (s[index] == " " || s[index] == "\t" || s[index] == "=") break;
+          if (s[index] == " " ||
+              s[index] == "\t" ||
+              s[index] == "=" ||
+              s[index] == valueSeparator) break;
           index++;
         }
         return s.substring(start, index).toLowerCase();
       }
 
       String parseParameterValue() {
-        if (s[index] == "\"") {
+        if (!done() && s[index] == "\"") {
           // Parse quoted value.
           StringBuffer sb = new StringBuffer();
           index++;
@@ -735,7 +743,8 @@
           return sb.toString();
         } else {
           // Parse non-quoted value.
-          return parseValue();
+          var val = parseValue();
+          return val == "" ? null : val;
         }
       }
 
@@ -744,8 +753,16 @@
         if (done()) return;
         String name = parseParameterName();
         skipWS();
-        expect("=");
+        if (done()) {
+          parameters[name] = null;
+          return;
+        }
+        maybeExpect("=");
         skipWS();
+        if(done()) {
+          parameters[name] = null;
+          return;
+        }
         String value = parseParameterValue();
         if (name == 'charset' && this is _ContentType) {
           // Charset parameter of ContentTypes are always lower-case.
@@ -754,6 +771,8 @@
         parameters[name] = value;
         skipWS();
         if (done()) return;
+        // TODO: Implement support for multi-valued parameters.
+        if(s[index] == valueSeparator) return;
         expect(parameterSeparator);
       }
     }
@@ -800,7 +819,7 @@
 
   static _ContentType parse(String value) {
     var result = new _ContentType._();
-    result._parse(value, ";", false);
+    result._parse(value, ";", null, false);
     int index = result._value.indexOf("/");
     if (index == -1 || index == (result._value.length - 1)) {
       result._primaryType = result._value.trim().toLowerCase();
diff --git a/sdk/lib/io/io.dart b/sdk/lib/io/io.dart
index aea1b5b..04cc6f2 100644
--- a/sdk/lib/io/io.dart
+++ b/sdk/lib/io/io.dart
@@ -186,13 +186,11 @@
  *
  * ## Other resources
  *
- * For an introduction to I/O in Dart, see the
- * [dart:io section of the library tour]
- * (https://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-dartio---file-and-socket-io-for-command-line-apps).
+ * For an introduction to I/O in Dart, see the [dart:io section of the library
+ * tour](https://www.dartlang.org/docs/dart-up-and-running/ch03.html#dartio---io-for-command-line-apps).
  *
- * To learn more about I/O in Dart, refer to the
- * [tutorial about writing command-line apps]
- * (https://www.dartlang.org/docs/tutorials/io/).
+ * To learn more about I/O in Dart, refer to the [tutorial about writing
+ * command-line apps](https://www.dartlang.org/docs/tutorials/io/).
  */
 library dart.io;
 
diff --git a/sdk/lib/io/platform.dart b/sdk/lib/io/platform.dart
index 56ddea0..c9e1cc6 100644
--- a/sdk/lib/io/platform.dart
+++ b/sdk/lib/io/platform.dart
@@ -84,7 +84,7 @@
   static String get pathSeparator => _pathSeparator;
 
   /**
-   * Get a string (`linux`, `macos`, `windows` or `android`)
+   * Get a string (`linux`, `macos`, `windows`, `android`, or `ios`)
    * representing the operating system.
    */
   static String get operatingSystem => _operatingSystem;
@@ -115,6 +115,11 @@
   static final bool isAndroid = (_operatingSystem == "android");
 
   /**
+   * Returns true if the operating system is iOS.
+   */
+  static final bool isiOS = (_operatingSystem == "ios");
+
+  /**
    * Get the environment for this process.
    *
    * The returned environment is an unmodifiable map which content is
diff --git a/sdk/lib/io/websocket.dart b/sdk/lib/io/websocket.dart
index 599e295..edb5b6d 100644
--- a/sdk/lib/io/websocket.dart
+++ b/sdk/lib/io/websocket.dart
@@ -12,7 +12,7 @@
   static const int GOING_AWAY = 1001;
   static const int PROTOCOL_ERROR = 1002;
   static const int UNSUPPORTED_DATA = 1003;
-  static const int RESERVED_1004  = 1004;
+  static const int RESERVED_1004 = 1004;
   static const int NO_STATUS_RECEIVED = 1005;
   static const int ABNORMAL_CLOSURE = 1006;
   static const int INVALID_FRAME_PAYLOAD_DATA = 1007;
@@ -24,6 +24,144 @@
 }
 
 /**
+ * The [CompressionOptions] class allows you to control
+ * the options of WebSocket compression.
+ */
+class CompressionOptions {
+  /**
+   * Default WebSocket Compression options.
+   * Compression will be enabled with the following options:
+   * clientNoContextTakeover: false
+   * serverNoContextTakeover: false
+   * clientMaxWindowBits: 15
+   * serverMaxWindowBits: 15
+   */
+  static const CompressionOptions DEFAULT = const CompressionOptions();
+
+  /**
+   * Disables WebSocket Compression.
+   */
+  static const CompressionOptions OFF =
+      const CompressionOptions(enabled: false);
+
+  /**
+   * Control whether the client will reuse it's compression instances.
+   */
+  final bool clientNoContextTakeover;
+
+  /**
+   * Control whether the server will reuse it's compression instances.
+   */
+  final bool serverNoContextTakeover;
+
+  /**
+   * Sets the Max Window Bits for the Client.
+   */
+  final int clientMaxWindowBits;
+
+  /**
+   * Sets the Max Window Bits for the Server.
+   */
+  final int serverMaxWindowBits;
+
+  /**
+   * Enables or disables WebSocket compression.
+   */
+  final bool enabled;
+
+  const CompressionOptions(
+      {this.clientNoContextTakeover: false,
+      this.serverNoContextTakeover: false,
+      this.clientMaxWindowBits,
+      this.serverMaxWindowBits,
+      this.enabled: true});
+
+  /// Parses list of requested server headers to return server compression
+  /// response headers. Uses [serverMaxWindowBits] value if set, otherwise will
+  /// attempt to use value from headers. Defaults to
+  /// [WebSocket.DEFAULT_WINDOW_BITS]. Returns a [_CompressionMaxWindowBits]
+  /// object which contains the response headers and negotiated max window bits.
+  _CompressionMaxWindowBits _createServerResponseHeader(HeaderValue requested) {
+    var info = new _CompressionMaxWindowBits();
+
+    int mwb;
+    String part;
+    if (requested?.parameters != null) {
+      part = requested.parameters[_serverMaxWindowBits];
+    }
+    if (part != null) {
+      if (part.length >= 2 && part.startsWith('0')) {
+        throw new ArgumentError("Illegal 0 padding on value.");
+      } else {
+        mwb = serverMaxWindowBits == null
+            ? int.parse(part,
+                        onError: (source) => _WebSocketImpl.DEFAULT_WINDOW_BITS)
+            : serverMaxWindowBits;
+        info.headerValue = "; server_max_window_bits=${mwb}";
+        info.maxWindowBits = mwb;
+      }
+    } else {
+      info.headerValue = "";
+      info.maxWindowBits = _WebSocketImpl.DEFAULT_WINDOW_BITS;
+    }
+    return info;
+  }
+
+  /// Returns default values for client compression request headers.
+  String _createClientRequestHeader(HeaderValue requested, int size) {
+    var info = "";
+
+    // If responding to a valid request, specify size
+    if (requested != null) {
+      info = "; client_max_window_bits=$size";
+    } else {
+      // Client request. Specify default
+      info = "; client_max_window_bits";
+    }
+
+    return info;
+  }
+
+  /// Create a Compression Header. If [requested] is null or contains
+  /// client request headers, returns Client compression request headers with
+  /// default settings for `client_max_window_bits` header value.
+  /// If [requested] contains server response headers this method returns
+  /// a Server compression response header negotiating the max window bits
+  /// for both client and server as requested server_max_window_bits value.
+  /// This method returns a [_CompressionMaxWindowBits] object with the
+  /// response headers and negotiated maxWindowBits value.
+  _CompressionMaxWindowBits _createHeader([HeaderValue requested]) {
+    var info = new _CompressionMaxWindowBits("", 0);
+    if (!enabled) {
+      return info;
+    }
+
+    info.headerValue = _WebSocketImpl.PER_MESSAGE_DEFLATE;
+
+    if (clientNoContextTakeover &&
+        (requested != null &&
+            requested.parameters.containsKey(_clientNoContextTakeover))) {
+      info.headerValue += "; client_no_context_takeover";
+    }
+
+    if (serverNoContextTakeover &&
+        (requested != null &&
+            requested.parameters.containsKey(_serverNoContextTakeover))) {
+      info.headerValue += "; server_no_context_takeover";
+    }
+
+    var headerList = _createServerResponseHeader(requested);
+    info.headerValue += headerList.headerValue;
+    info.maxWindowBits = headerList.maxWindowBits;
+
+    info.headerValue +=
+        _createClientRequestHeader(requested, info.maxWindowBits);
+
+    return info;
+  }
+}
+
+/**
  * The [WebSocketTransformer] provides the ability to upgrade a
  * [HttpRequest] to a [WebSocket] connection. It supports both
  * upgrading a single [HttpRequest] and upgrading a stream of
@@ -53,7 +191,6 @@
  */
 abstract class WebSocketTransformer
     implements StreamTransformer<HttpRequest, WebSocket> {
-
   /**
    * Create a new [WebSocketTransformer].
    *
@@ -62,9 +199,15 @@
    * [protocolSelector] is should return either a [String] or a [Future]
    * completing with a [String]. The [String] must exist in the list of
    * protocols.
+   *
+   * If [compression] is provided, the [WebSocket] created will be configured
+   * to negotiate with the specified [CompressionOptions]. If none is specified
+   * then the [WebSocket] will be created with the default [CompressionOptions].
    */
-  factory WebSocketTransformer({protocolSelector(List<String> protocols)})
-      => new _WebSocketTransformerImpl(protocolSelector);
+  factory WebSocketTransformer(
+          {protocolSelector(List<String> protocols),
+          CompressionOptions compression: CompressionOptions.DEFAULT}) =>
+      new _WebSocketTransformerImpl(protocolSelector, compression);
 
   /**
    * Upgrades a [HttpRequest] to a [WebSocket] connection. If the
@@ -78,10 +221,16 @@
    * [protocolSelector] is should return either a [String] or a [Future]
    * completing with a [String]. The [String] must exist in the list of
    * protocols.
+   *
+   * If [compression] is provided, the [WebSocket] created will be configured
+   * to negotiate with the specified [CompressionOptions]. If none is specified
+   * then the [WebSocket] will be created with the default [CompressionOptions].
    */
   static Future<WebSocket> upgrade(HttpRequest request,
-                                   {protocolSelector(List<String> protocols)}) {
-    return _WebSocketTransformerImpl._upgrade(request, protocolSelector);
+      {protocolSelector(List<String> protocols),
+      CompressionOptions compression: CompressionOptions.DEFAULT}) {
+    return _WebSocketTransformerImpl._upgrade(
+        request, protocolSelector, compression);
   }
 
   /**
@@ -92,7 +241,6 @@
   }
 }
 
-
 /**
  * A two-way HTTP communication object for client or server applications.
  *
@@ -152,9 +300,10 @@
    * authentication when setting up the connection.
    */
   static Future<WebSocket> connect(String url,
-                                   {Iterable<String> protocols,
-                                    Map<String, dynamic> headers}) =>
-      _WebSocketImpl.connect(url, protocols, headers);
+          {Iterable<String> protocols,
+          Map<String, dynamic> headers,
+          CompressionOptions compression: CompressionOptions.DEFAULT}) =>
+      _WebSocketImpl.connect(url, protocols, headers, compression: compression);
 
   @Deprecated('This constructor will be removed in Dart 2.0. Use `implements`'
       ' instead of `extends` if implementing this abstract class.')
@@ -174,14 +323,21 @@
    * [serverSide] must be passed explicitly. If it's `false`, the WebSocket will
    * act as the client and mask the messages it sends. If it's `true`, it will
    * act as the server and will not mask its messages.
+   *
+   * If [compression] is provided, the [WebSocket] created will be configured
+   * to negotiate with the specified [CompressionOptions]. If none is specified
+   * then the [WebSocket] will be created with the default [CompressionOptions].
    */
-  factory WebSocket.fromUpgradedSocket(Socket socket, {String protocol,
-        bool serverSide}) {
+  factory WebSocket.fromUpgradedSocket(Socket socket,
+      {String protocol,
+      bool serverSide,
+      CompressionOptions compression: CompressionOptions.DEFAULT}) {
     if (serverSide == null) {
       throw new ArgumentError("The serverSide argument must be passed "
           "explicitly to WebSocket.fromUpgradedSocket.");
     }
-    return new _WebSocketImpl._fromSocket(socket, protocol, serverSide);
+    return new _WebSocketImpl._fromSocket(
+        socket, protocol, compression, serverSide);
   }
 
   /**
@@ -238,9 +394,10 @@
   Future addStream(Stream stream);
 }
 
-
 class WebSocketException implements IOException {
   final String message;
+
   const WebSocketException([this.message = ""]);
+
   String toString() => "WebSocketException: $message";
 }
diff --git a/sdk/lib/io/websocket_impl.dart b/sdk/lib/io/websocket_impl.dart
index cc68544..879d05e 100644
--- a/sdk/lib/io/websocket_impl.dart
+++ b/sdk/lib/io/websocket_impl.dart
@@ -5,6 +5,10 @@
 part of dart.io;
 
 const String _webSocketGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
+const String _clientNoContextTakeover = "client_no_context_takeover";
+const String _serverNoContextTakeover = "server_no_context_takeover";
+const String _clientMaxWindowBits = "client_max_window_bits";
+const String _serverMaxWindowBits = "server_max_window_bits";
 
 // Matches _WebSocketOpcode.
 class _WebSocketMessageType {
@@ -13,7 +17,6 @@
   static const int BINARY = 2;
 }
 
-
 class _WebSocketOpcode {
   static const int CONTINUATION = 0;
   static const int TEXT = 1;
@@ -34,12 +37,24 @@
 }
 
 /**
+ *  Stores the header and integer value derived from negotiation of
+ *  client_max_window_bits and server_max_window_bits. headerValue will be
+ *  set in the Websocket response headers.
+ */
+class _CompressionMaxWindowBits {
+  String headerValue;
+  int maxWindowBits;
+  _CompressionMaxWindowBits([this.headerValue, this.maxWindowBits]);
+  String toString() => headerValue;
+}
+
+/**
  * The web socket protocol transformer handles the protocol byte stream
  * which is supplied through the [:handleData:]. As the protocol is processed,
  * it'll output frame data as either a List<int> or String.
  *
- * Important infomation about usage: Be sure you use cancelOnError, so the
- * socket will be closed when the processer encounter an error. Not using it
+ * Important information about usage: Be sure you use cancelOnError, so the
+ * socket will be closed when the processor encounter an error. Not using it
  * will lead to undefined behaviour.
  */
 // TODO(ajohnsen): make this transformer reusable?
@@ -51,9 +66,15 @@
   static const int PAYLOAD = 4;
   static const int CLOSED = 5;
   static const int FAILURE = 6;
+  static const int FIN = 0x80;
+  static const int RSV1 = 0x40;
+  static const int RSV2 = 0x20;
+  static const int RSV3 = 0x10;
+  static const int OPCODE = 0xF;
 
   int _state = START;
   bool _fin = false;
+  bool _compressed = false;
   int _opcode = -1;
   int _len = -1;
   bool _masked = false;
@@ -71,18 +92,17 @@
   final List _maskingBytes = new List(4);
   final BytesBuilder _payload = new BytesBuilder(copy: false);
 
-  _WebSocketProtocolTransformer([this._serverSide = false]);
+  _WebSocketPerMessageDeflate _deflate;
+  _WebSocketProtocolTransformer([this._serverSide = false, this._deflate]);
 
   Stream bind(Stream stream) {
-    return new Stream.eventTransformed(
-        stream,
-        (EventSink eventSink) {
-          if (_eventSink != null) {
-            throw new StateError("WebSocket transformer already used.");
-          }
-          _eventSink = eventSink;
-          return this;
-        });
+    return new Stream.eventTransformed(stream, (EventSink eventSink) {
+      if (_eventSink != null) {
+        throw new StateError("WebSocket transformer already used.");
+      }
+      _eventSink = eventSink;
+      return this;
+    });
   }
 
   void addError(Object error, [StackTrace stackTrace]) =>
@@ -94,9 +114,8 @@
    * Process data received from the underlying communication channel.
    */
   void add(Uint8List buffer) {
-    int count = buffer.length;
     int index = 0;
-    int lastIndex = count;
+    int lastIndex = buffer.length;
     if (_state == CLOSED) {
       throw new WebSocketException("Data on closed connection");
     }
@@ -107,12 +126,20 @@
       int byte = buffer[index];
       if (_state <= LEN_REST) {
         if (_state == START) {
-          _fin = (byte & 0x80) != 0;
-          if ((byte & 0x70) != 0) {
-            // The RSV1, RSV2 bits RSV3 must be all zero.
+          _fin = (byte & FIN) != 0;
+
+          if((byte & (RSV2 | RSV3)) != 0) {
+            // The RSV2, RSV3 bits must both be zero.
             throw new WebSocketException("Protocol error");
           }
-          _opcode = (byte & 0xF);
+
+          if ((byte & RSV1) != 0) {
+            _compressed = true;
+          } else {
+            _compressed = false;
+          }
+          _opcode = (byte & OPCODE);
+
           if (_opcode <= _WebSocketOpcode.BINARY) {
             if (_opcode == _WebSocketOpcode.CONTINUATION) {
               if (_currentMessageType == _WebSocketMessageType.NONE) {
@@ -120,14 +147,14 @@
               }
             } else {
               assert(_opcode == _WebSocketOpcode.TEXT ||
-                     _opcode == _WebSocketOpcode.BINARY);
+                  _opcode == _WebSocketOpcode.BINARY);
               if (_currentMessageType != _WebSocketMessageType.NONE) {
                 throw new WebSocketException("Protocol error");
               }
               _currentMessageType = _opcode;
             }
           } else if (_opcode >= _WebSocketOpcode.CLOSE &&
-                     _opcode <= _WebSocketOpcode.PONG) {
+              _opcode <= _WebSocketOpcode.PONG) {
             // Control frames cannot be fragmented.
             if (!_fin) throw new WebSocketException("Protocol error");
           } else {
@@ -176,15 +203,14 @@
             _unmask(index, payloadLength, buffer);
           }
           // Control frame and data frame share _payloads.
-          _payload.add(
-              new Uint8List.view(buffer.buffer, index, payloadLength));
+          _payload.add(new Uint8List.view(buffer.buffer, index, payloadLength));
           index += payloadLength;
           if (_isControlFrame()) {
             if (_remainingPayloadBytes == 0) _controlFrameEnd();
           } else {
             if (_currentMessageType != _WebSocketMessageType.TEXT &&
                 _currentMessageType != _WebSocketMessageType.BINARY) {
-                throw new WebSocketException("Protocol error");
+              throw new WebSocketException("Protocol error");
             }
             if (_remainingPayloadBytes == 0) _messageFrameEnd();
           }
@@ -219,8 +245,8 @@
           mask = (mask << 8) | _maskingBytes[(_unmaskingIndex + i) & 3];
         }
         Int32x4 blockMask = new Int32x4(mask, mask, mask, mask);
-        Int32x4List blockBuffer = new Int32x4List.view(
-            buffer.buffer, index, blockCount);
+        Int32x4List blockBuffer =
+            new Int32x4List.view(buffer.buffer, index, blockCount);
         for (int i = 0; i < blockBuffer.length; i++) {
           blockBuffer[i] ^= blockMask;
         }
@@ -284,12 +310,17 @@
 
   void _messageFrameEnd() {
     if (_fin) {
+      var bytes = _payload.takeBytes();
+      if (_deflate != null && _compressed) {
+        bytes = _deflate.processIncomingMessage(bytes);
+      }
+
       switch (_currentMessageType) {
         case _WebSocketMessageType.TEXT:
-          _eventSink.add(UTF8.decode(_payload.takeBytes()));
+          _eventSink.add(UTF8.decode(bytes));
           break;
         case _WebSocketMessageType.BINARY:
-          _eventSink.add(_payload.takeBytes());
+          _eventSink.add(bytes);
           break;
       }
       _currentMessageType = _WebSocketMessageType.NONE;
@@ -331,8 +362,8 @@
 
   bool _isControlFrame() {
     return _opcode == _WebSocketOpcode.CLOSE ||
-           _opcode == _WebSocketOpcode.PING ||
-           _opcode == _WebSocketOpcode.PONG;
+        _opcode == _WebSocketOpcode.PING ||
+        _opcode == _WebSocketOpcode.PONG;
   }
 
   void _prepareForNextFrame() {
@@ -347,31 +378,29 @@
   }
 }
 
-
 class _WebSocketPing {
   final List<int> payload;
   _WebSocketPing([this.payload = null]);
 }
 
-
 class _WebSocketPong {
   final List<int> payload;
   _WebSocketPong([this.payload = null]);
 }
 
-
 class _WebSocketTransformerImpl implements WebSocketTransformer {
   final StreamController<WebSocket> _controller =
       new StreamController<WebSocket>(sync: true);
   final Function _protocolSelector;
+  final CompressionOptions _compression;
 
-  _WebSocketTransformerImpl(this._protocolSelector);
+  _WebSocketTransformerImpl(this._protocolSelector, this._compression);
 
   Stream<WebSocket> bind(Stream<HttpRequest> stream) {
     stream.listen((request) {
-        _upgrade(request, _protocolSelector)
-            .then((WebSocket webSocket) => _controller.add(webSocket))
-            .catchError(_controller.addError);
+      _upgrade(request, _protocolSelector, _compression)
+          .then((WebSocket webSocket) => _controller.add(webSocket))
+          .catchError(_controller.addError);
     }, onDone: () {
       _controller.close();
     });
@@ -379,13 +408,14 @@
     return _controller.stream;
   }
 
-  static Future<WebSocket> _upgrade(HttpRequest request, _protocolSelector) {
+  static Future<WebSocket> _upgrade(
+      HttpRequest request, _protocolSelector, CompressionOptions compression) {
     var response = request.response;
     if (!_isUpgradeRequest(request)) {
       // Send error response.
       response
-          ..statusCode = HttpStatus.BAD_REQUEST
-          ..close();
+        ..statusCode = HttpStatus.BAD_REQUEST
+        ..close();
       return new Future.error(
           new WebSocketException("Invalid WebSocket upgrade request"));
     }
@@ -393,9 +423,9 @@
     Future upgrade(String protocol) {
       // Send the upgrade response.
       response
-          ..statusCode = HttpStatus.SWITCHING_PROTOCOLS
-          ..headers.add(HttpHeaders.CONNECTION, "Upgrade")
-          ..headers.add(HttpHeaders.UPGRADE, "websocket");
+        ..statusCode = HttpStatus.SWITCHING_PROTOCOLS
+        ..headers.add(HttpHeaders.CONNECTION, "Upgrade")
+        ..headers.add(HttpHeaders.UPGRADE, "websocket");
       String key = request.headers.value("Sec-WebSocket-Key");
       _SHA1 sha1 = new _SHA1();
       sha1.add("$key$_webSocketGUID".codeUnits);
@@ -404,10 +434,13 @@
       if (protocol != null) {
         response.headers.add("Sec-WebSocket-Protocol", protocol);
       }
+
+      var deflate = _negotiateCompression(request, response, compression);
+
       response.headers.contentLength = 0;
-      return response.detachSocket()
-          .then((socket) => new _WebSocketImpl._fromSocket(
-                socket, protocol, true));
+      return response.detachSocket().then((socket) =>
+          new _WebSocketImpl._fromSocket(
+              socket, protocol, compression, true, deflate));
     }
 
     var protocols = request.headers['Sec-WebSocket-Protocol'];
@@ -416,26 +449,51 @@
       // consisting of multiple protocols. To unify all of them, first join
       // the lists with ', ' and then tokenize.
       protocols = _HttpParser._tokenizeFieldValue(protocols.join(', '));
-      return new Future(() => _protocolSelector(protocols))
-        .then((protocol) {
-          if (protocols.indexOf(protocol) < 0) {
-            throw new WebSocketException(
-                "Selected protocol is not in the list of available protocols");
-          }
-          return protocol;
-        })
-        .catchError((error) {
-          response
-              ..statusCode = HttpStatus.INTERNAL_SERVER_ERROR
-              ..close();
-          throw error;
-        })
-        .then(upgrade);
+      return new Future(() => _protocolSelector(protocols)).then((protocol) {
+        if (protocols.indexOf(protocol) < 0) {
+          throw new WebSocketException(
+              "Selected protocol is not in the list of available protocols");
+        }
+        return protocol;
+      }).catchError((error) {
+        response
+          ..statusCode = HttpStatus.INTERNAL_SERVER_ERROR
+          ..close();
+        throw error;
+      }).then(upgrade);
     } else {
       return upgrade(null);
     }
   }
 
+  static _WebSocketPerMessageDeflate _negotiateCompression(HttpRequest request,
+      HttpResponse response, CompressionOptions compression) {
+    var extensionHeader = request.headers.value("Sec-WebSocket-Extensions");
+
+    extensionHeader ??= "";
+
+    var hv = HeaderValue.parse(extensionHeader, valueSeparator: ',');
+    if (compression.enabled && hv.value == _WebSocketImpl.PER_MESSAGE_DEFLATE) {
+      var info = compression._createHeader(hv);
+
+      response.headers.add("Sec-WebSocket-Extensions", info.headerValue);
+      var serverNoContextTakeover =
+          hv.parameters.containsKey(_serverNoContextTakeover);
+      var clientNoContextTakeover =
+          hv.parameters.containsKey(_clientNoContextTakeover);
+      var deflate = new _WebSocketPerMessageDeflate(
+          serverNoContextTakeover: serverNoContextTakeover,
+          clientNoContextTakeover: clientNoContextTakeover,
+          serverMaxWindowBits: info.maxWindowBits,
+          clientMaxWindowBits: info.maxWindowBits,
+          serverSide: true);
+
+      return deflate;
+    }
+
+    return null;
+  }
+
   static bool _isUpgradeRequest(HttpRequest request) {
     if (request.method != "GET") {
       return false;
@@ -464,24 +522,127 @@
   }
 }
 
+class _WebSocketPerMessageDeflate {
+  bool serverNoContextTakeover;
+  bool clientNoContextTakeover;
+  int clientMaxWindowBits;
+  int serverMaxWindowBits;
+  bool serverSide;
+
+  _Filter decoder;
+  _Filter encoder;
+
+  _WebSocketPerMessageDeflate(
+      {this.clientMaxWindowBits: _WebSocketImpl.DEFAULT_WINDOW_BITS,
+       this.serverMaxWindowBits: _WebSocketImpl.DEFAULT_WINDOW_BITS,
+       this.serverNoContextTakeover: false,
+       this.clientNoContextTakeover: false,
+       this.serverSide: false});
+
+  void _ensureDecoder() {
+    if (decoder == null) {
+      decoder = _Filter._newZLibInflateFilter(
+          serverSide ? clientMaxWindowBits : serverMaxWindowBits, null, true);
+    }
+  }
+
+  void _ensureEncoder() {
+    if (encoder == null) {
+      encoder = _Filter._newZLibDeflateFilter(
+          false,
+          ZLibOption.DEFAULT_LEVEL,
+          serverSide ? serverMaxWindowBits : clientMaxWindowBits,
+          ZLibOption.DEFAULT_MEM_LEVEL,
+          ZLibOption.STRATEGY_DEFAULT,
+          null,
+          true);
+    }
+  }
+
+  Uint8List processIncomingMessage(List<int> msg) {
+    _ensureDecoder();
+
+    var data = [];
+    data.addAll(msg);
+    data.addAll(const [0x00, 0x00, 0xff, 0xff]);
+
+    decoder.process(data, 0, data.length);
+    var reuse =
+        !(serverSide ? clientNoContextTakeover : serverNoContextTakeover);
+    var result = [];
+    var out;
+
+    while ((out = decoder.processed(flush: reuse)) != null) {
+      result.addAll(out);
+    }
+
+    decoder.processed(flush: reuse);
+
+    if (!reuse) {
+      decoder.end();
+      decoder = null;
+    }
+    return new Uint8List.fromList(result);
+  }
+
+  List<int> processOutgoingMessage(List<int> msg) {
+    _ensureEncoder();
+    var reuse =
+        !(serverSide ? serverNoContextTakeover : clientNoContextTakeover);
+    var result = [];
+    Uint8List buffer;
+    var out;
+
+    if (msg is! Uint8List) {
+      for (var i = 0; i < msg.length; i++) {
+        if (msg[i] < 0 || 255 < msg[i]) {
+          throw new ArgumentError("List element is not a byte value "
+              "(value ${msg[i]} at index $i)");
+        }
+      }
+      buffer = new Uint8List.fromList(msg);
+    } else {
+      buffer = msg;
+    }
+
+    encoder.process(buffer, 0, buffer.length);
+
+    while ((out = encoder.processed(flush: reuse)) != null) {
+      result.addAll(out);
+    }
+
+    if (serverSide ? serverNoContextTakeover : clientNoContextTakeover) {
+      encoder.end();
+      encoder = null;
+    }
+
+    if (result.length > 4) {
+      result = result.sublist(0, result.length - 4);
+    }
+
+    return result;
+  }
+}
 
 // TODO(ajohnsen): Make this transformer reusable.
 class _WebSocketOutgoingTransformer implements StreamTransformer, EventSink {
   final _WebSocketImpl webSocket;
   EventSink _eventSink;
 
-  _WebSocketOutgoingTransformer(this.webSocket);
+  _WebSocketPerMessageDeflate _deflateHelper;
+
+  _WebSocketOutgoingTransformer(this.webSocket) {
+    _deflateHelper = webSocket._deflate;
+  }
 
   Stream bind(Stream stream) {
-    return new Stream.eventTransformed(
-        stream,
-        (EventSink eventSink) {
-          if (_eventSink != null) {
-            throw new StateError("WebSocket transformer already used");
-          }
-          _eventSink = eventSink;
-          return this;
-        });
+    return new Stream.eventTransformed(stream, (EventSink eventSink) {
+      if (_eventSink != null) {
+        throw new StateError("WebSocket transformer already used");
+      }
+      _eventSink = eventSink;
+      return this;
+    });
   }
 
   void add(message) {
@@ -500,12 +661,16 @@
         opcode = _WebSocketOpcode.TEXT;
         data = UTF8.encode(message);
       } else {
-        if (message is !List<int>) {
+        if (message is! List<int>) {
           throw new ArgumentError(message);
         }
         opcode = _WebSocketOpcode.BINARY;
         data = message;
       }
+
+      if (_deflateHelper != null) {
+        data = _deflateHelper.processOutgoingMessage(data);
+      }
     } else {
       opcode = _WebSocketOpcode.TEXT;
     }
@@ -531,11 +696,19 @@
     _eventSink.close();
   }
 
-  void addFrame(int opcode, List<int> data) =>
-      createFrame(opcode, data, webSocket._serverSide).forEach(_eventSink.add);
+  void addFrame(int opcode, List<int> data) => createFrame(
+          opcode,
+          data,
+          webSocket._serverSide,
+          _deflateHelper != null &&
+              (opcode == _WebSocketOpcode.TEXT ||
+                  opcode == _WebSocketOpcode.BINARY)).forEach((e) {
+        _eventSink.add(e);
+      });
 
-  static Iterable createFrame(int opcode, List<int> data, bool serverSide) {
-    bool mask = !serverSide;  // Masking not implemented for server.
+  static Iterable createFrame(
+      int opcode, List<int> data, bool serverSide, bool compressed) {
+    bool mask = !serverSide; // Masking not implemented for server.
     int dataLength = data == null ? 0 : data.length;
     // Determine the header size.
     int headerSize = (mask) ? 6 : 2;
@@ -546,11 +719,15 @@
     }
     Uint8List header = new Uint8List(headerSize);
     int index = 0;
+
     // Set FIN and opcode.
-    header[index++] = 0x80 | opcode;
+    var hoc = _WebSocketProtocolTransformer.FIN
+              | (compressed ? _WebSocketProtocolTransformer.RSV1 : 0)
+              | (opcode & _WebSocketProtocolTransformer.OPCODE);
+
+    header[index++] = hoc;
     // Determine size and position of length field.
     int lengthBytes = 1;
-    int firstLengthByte = 1;
     if (dataLength > 65535) {
       header[index++] = 127;
       lengthBytes = 8;
@@ -580,8 +757,7 @@
             list = new Uint8List(data.length);
             for (int i = 0; i < data.length; i++) {
               if (data[i] < 0 || 255 < data[i]) {
-                throw new ArgumentError(
-                    "List element is not a byte value "
+                throw new ArgumentError("List element is not a byte value "
                     "(value ${data[i]} at index $i)");
               }
               list[i] = data[i];
@@ -597,8 +773,8 @@
             mask = (mask << 8) | maskBytes[i];
           }
           Int32x4 blockMask = new Int32x4(mask, mask, mask, mask);
-          Int32x4List blockBuffer = new Int32x4List.view(
-              list.buffer, 0, blockCount);
+          Int32x4List blockBuffer =
+              new Int32x4List.view(list.buffer, 0, blockCount);
           for (int i = 0; i < blockBuffer.length; i++) {
             blockBuffer[i] ^= blockMask;
           }
@@ -619,7 +795,6 @@
   }
 }
 
-
 class _WebSocketConsumer implements StreamConsumer {
   final _WebSocketImpl webSocket;
   final Socket socket;
@@ -664,28 +839,28 @@
 
   _ensureController() {
     if (_controller != null) return;
-    _controller = new StreamController(sync: true,
-                                       onPause: _onPause,
-                                       onResume: _onResume,
-                                       onCancel: _onListen);
-    var stream = _controller.stream.transform(
-        new _WebSocketOutgoingTransformer(webSocket));
-    socket.addStream(stream)
-        .then((_) {
-          _done();
-          _closeCompleter.complete(webSocket);
-        }, onError: (error, StackTrace stackTrace) {
-          _closed = true;
-          _cancel();
-          if (error is ArgumentError) {
-            if (!_done(error, stackTrace)) {
-              _closeCompleter.completeError(error, stackTrace);
-            }
-          } else {
-            _done();
-            _closeCompleter.complete(webSocket);
-          }
-        });
+    _controller = new StreamController(
+        sync: true,
+        onPause: _onPause,
+        onResume: _onResume,
+        onCancel: _onListen);
+    var stream = _controller.stream
+        .transform(new _WebSocketOutgoingTransformer(webSocket));
+    socket.addStream(stream).then((_) {
+      _done();
+      _closeCompleter.complete(webSocket);
+    }, onError: (error, StackTrace stackTrace) {
+      _closed = true;
+      _cancel();
+      if (error is ArgumentError) {
+        if (!_done(error, stackTrace)) {
+          _closeCompleter.completeError(error, stackTrace);
+        }
+      } else {
+        _done();
+        _closeCompleter.complete(webSocket);
+      }
+    });
   }
 
   bool _done([error, StackTrace stackTrace]) {
@@ -706,13 +881,9 @@
     }
     _ensureController();
     _completer = new Completer();
-    _subscription = stream.listen(
-        (data) {
-          _controller.add(data);
-        },
-        onDone: _done,
-        onError: _done,
-        cancelOnError: true);
+    _subscription = stream.listen((data) {
+      _controller.add(data);
+    }, onDone: _done, onError: _done, cancelOnError: true);
     if (_issuedPause) {
       _subscription.pause();
       _issuedPause = false;
@@ -742,10 +913,11 @@
   }
 }
 
-
 class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket {
   // Use default Map so we keep order.
   static Map<int, _WebSocketImpl> _webSockets = new Map<int, _WebSocketImpl>();
+  static const int DEFAULT_WINDOW_BITS = 15;
+  static const String PER_MESSAGE_DEFLATE = "permessage-deflate";
 
   final String protocol;
 
@@ -766,11 +938,13 @@
   int _outCloseCode;
   String _outCloseReason;
   Timer _closeTimer;
+  _WebSocketPerMessageDeflate _deflate;
 
   static final HttpClient _httpClient = new HttpClient();
 
   static Future<WebSocket> connect(
-      String url, Iterable<String> protocols, Map<String, dynamic> headers) {
+      String url, Iterable<String> protocols, Map<String, dynamic> headers,
+      {CompressionOptions compression: CompressionOptions.DEFAULT}) {
     Uri uri = Uri.parse(url);
     if (uri.scheme != "ws" && uri.scheme != "wss") {
       throw new WebSocketException("Unsupported URL scheme '${uri.scheme}'");
@@ -784,144 +958,182 @@
     }
     String nonce = _CryptoUtils.bytesToBase64(nonceData);
 
-    uri = new Uri(scheme: uri.scheme == "wss" ? "https" : "http",
-                  userInfo: uri.userInfo,
-                  host: uri.host,
-                  port: uri.port,
-                  path: uri.path,
-                  query: uri.query,
-                  fragment: uri.fragment);
-    return _httpClient.openUrl("GET", uri)
-      .then((request) {
-        if (uri.userInfo != null && !uri.userInfo.isEmpty) {
-          // If the URL contains user information use that for basic
-          // authorization.
-          String auth =
-          _CryptoUtils.bytesToBase64(UTF8.encode(uri.userInfo));
-          request.headers.set(HttpHeaders.AUTHORIZATION, "Basic $auth");
-        }
-        if (headers != null) {
-          headers.forEach((field, value) => request.headers.add(field, value));
-        }
-        // Setup the initial handshake.
+    uri = new Uri(
+        scheme: uri.scheme == "wss" ? "https" : "http",
+        userInfo: uri.userInfo,
+        host: uri.host,
+        port: uri.port,
+        path: uri.path,
+        query: uri.query,
+        fragment: uri.fragment);
+    return _httpClient.openUrl("GET", uri).then((request) {
+      if (uri.userInfo != null && !uri.userInfo.isEmpty) {
+        // If the URL contains user information use that for basic
+        // authorization.
+        String auth = _CryptoUtils.bytesToBase64(UTF8.encode(uri.userInfo));
+        request.headers.set(HttpHeaders.AUTHORIZATION, "Basic $auth");
+      }
+      if (headers != null) {
+        headers.forEach((field, value) => request.headers.add(field, value));
+      }
+      // Setup the initial handshake.
+      request.headers
+        ..set(HttpHeaders.CONNECTION, "Upgrade")
+        ..set(HttpHeaders.UPGRADE, "websocket")
+        ..set("Sec-WebSocket-Key", nonce)
+        ..set("Cache-Control", "no-cache")
+        ..set("Sec-WebSocket-Version", "13");
+      if (protocols != null) {
+        request.headers.add("Sec-WebSocket-Protocol", protocols.toList());
+      }
+
+      if (compression.enabled) {
         request.headers
-            ..set(HttpHeaders.CONNECTION, "Upgrade")
-            ..set(HttpHeaders.UPGRADE, "websocket")
-            ..set("Sec-WebSocket-Key", nonce)
-            ..set("Cache-Control", "no-cache")
-            ..set("Sec-WebSocket-Version", "13");
-        if (protocols != null) {
-          request.headers.add("Sec-WebSocket-Protocol", protocols.toList());
+            .add("Sec-WebSocket-Extensions", compression._createHeader());
+      }
+
+      return request.close();
+    }).then((response) {
+      void error(String message) {
+        // Flush data.
+        response.detachSocket().then((socket) {
+          socket.destroy();
+        });
+        throw new WebSocketException(message);
+      }
+      if (response.statusCode != HttpStatus.SWITCHING_PROTOCOLS ||
+          response.headers[HttpHeaders.CONNECTION] == null ||
+          !response.headers[HttpHeaders.CONNECTION]
+              .any((value) => value.toLowerCase() == "upgrade") ||
+          response.headers.value(HttpHeaders.UPGRADE).toLowerCase() !=
+              "websocket") {
+        error("Connection to '$uri' was not upgraded to websocket");
+      }
+      String accept = response.headers.value("Sec-WebSocket-Accept");
+      if (accept == null) {
+        error("Response did not contain a 'Sec-WebSocket-Accept' header");
+      }
+      _SHA1 sha1 = new _SHA1();
+      sha1.add("$nonce$_webSocketGUID".codeUnits);
+      List<int> expectedAccept = sha1.close();
+      List<int> receivedAccept = _CryptoUtils.base64StringToBytes(accept);
+      if (expectedAccept.length != receivedAccept.length) {
+        error("Reasponse header 'Sec-WebSocket-Accept' is the wrong length");
+      }
+      for (int i = 0; i < expectedAccept.length; i++) {
+        if (expectedAccept[i] != receivedAccept[i]) {
+          error("Bad response 'Sec-WebSocket-Accept' header");
         }
-        return request.close();
-      })
-      .then((response) {
-        void error(String message) {
-          // Flush data.
-          response.detachSocket().then((socket) {
-            socket.destroy();
-          });
-          throw new WebSocketException(message);
-        }
-        if (response.statusCode != HttpStatus.SWITCHING_PROTOCOLS ||
-            response.headers[HttpHeaders.CONNECTION] == null ||
-            !response.headers[HttpHeaders.CONNECTION].any(
-                (value) => value.toLowerCase() == "upgrade") ||
-            response.headers.value(HttpHeaders.UPGRADE).toLowerCase() !=
-                "websocket") {
-          error("Connection to '$uri' was not upgraded to websocket");
-        }
-        String accept = response.headers.value("Sec-WebSocket-Accept");
-        if (accept == null) {
-          error("Response did not contain a 'Sec-WebSocket-Accept' header");
-        }
-        _SHA1 sha1 = new _SHA1();
-        sha1.add("$nonce$_webSocketGUID".codeUnits);
-        List<int> expectedAccept = sha1.close();
-        List<int> receivedAccept = _CryptoUtils.base64StringToBytes(accept);
-        if (expectedAccept.length != receivedAccept.length) {
-          error("Reasponse header 'Sec-WebSocket-Accept' is the wrong length");
-        }
-        for (int i = 0; i < expectedAccept.length; i++) {
-          if (expectedAccept[i] != receivedAccept[i]) {
-            error("Bad response 'Sec-WebSocket-Accept' header");
-          }
-        }
-        var protocol = response.headers.value('Sec-WebSocket-Protocol');
-        return response.detachSocket()
-            .then((socket) => new _WebSocketImpl._fromSocket(socket, protocol));
-      });
+      }
+      var protocol = response.headers.value('Sec-WebSocket-Protocol');
+
+      _WebSocketPerMessageDeflate deflate =
+          negotiateClientCompression(response, compression);
+
+      return response.detachSocket().then((socket) =>
+          new _WebSocketImpl._fromSocket(
+              socket, protocol, compression, false, deflate));
+    });
   }
 
-  _WebSocketImpl._fromSocket(this._socket, this.protocol,
-                             [this._serverSide = false]) {
+  static _WebSocketPerMessageDeflate negotiateClientCompression(
+      HttpClientResponse response, CompressionOptions compression) {
+    String extensionHeader = response.headers.value('Sec-WebSocket-Extensions');
+
+    if (extensionHeader == null) {
+      extensionHeader = "";
+    }
+
+    var hv = HeaderValue.parse(extensionHeader, valueSeparator: ',');
+
+    if (compression.enabled && hv.value == PER_MESSAGE_DEFLATE) {
+      var serverNoContextTakeover =
+          hv.parameters.containsKey(_serverNoContextTakeover);
+      var clientNoContextTakeover =
+          hv.parameters.containsKey(_clientNoContextTakeover);
+
+      int getWindowBits(String type) {
+        var o = hv.parameters[type];
+        if (o == null) {
+          return DEFAULT_WINDOW_BITS;
+        }
+
+        o = int.parse(o, onError: (s) => DEFAULT_WINDOW_BITS);
+        return o;
+      }
+
+      return new _WebSocketPerMessageDeflate(
+          clientMaxWindowBits: getWindowBits(_clientMaxWindowBits),
+          serverMaxWindowBits: getWindowBits(_serverMaxWindowBits),
+          clientNoContextTakeover: clientNoContextTakeover,
+          serverNoContextTakeover: serverNoContextTakeover);
+    }
+
+    return null;
+  }
+
+  _WebSocketImpl._fromSocket(
+      this._socket, this.protocol, CompressionOptions compression,
+      [this._serverSide = false, _WebSocketPerMessageDeflate deflate]) {
     _consumer = new _WebSocketConsumer(this, _socket);
     _sink = new _StreamSinkImpl(_consumer);
     _readyState = WebSocket.OPEN;
+    _deflate = deflate;
 
-    var transformer = new _WebSocketProtocolTransformer(_serverSide);
-    _subscription = _socket.transform(transformer).listen(
-        (data) {
-          if (data is _WebSocketPing) {
-            if (!_writeClosed) _consumer.add(new _WebSocketPong(data.payload));
-          } else if (data is _WebSocketPong) {
-            // Simply set pingInterval, as it'll cancel any timers.
-            pingInterval = _pingInterval;
-          } else {
-            _controller.add(data);
-          }
-        },
-        onError: (error) {
-          if (_closeTimer != null) _closeTimer.cancel();
-          if (error is FormatException) {
-            _close(WebSocketStatus.INVALID_FRAME_PAYLOAD_DATA);
-          } else {
-            _close(WebSocketStatus.PROTOCOL_ERROR);
-          }
-          // An error happened, set the close code set above.
-          _closeCode = _outCloseCode;
-          _closeReason = _outCloseReason;
-          _controller.close();
-        },
-        onDone: () {
-          if (_closeTimer != null) _closeTimer.cancel();
-          if (_readyState == WebSocket.OPEN) {
-            _readyState = WebSocket.CLOSING;
-            if (!_isReservedStatusCode(transformer.closeCode)) {
-              _close(transformer.closeCode, transformer.closeReason);
-            } else {
-              _close();
-            }
-            _readyState = WebSocket.CLOSED;
-          }
-          // Protocol close, use close code from transformer.
-          _closeCode = transformer.closeCode;
-          _closeReason = transformer.closeReason;
-          _controller.close();
-        },
-        cancelOnError: true);
+    var transformer = new _WebSocketProtocolTransformer(_serverSide, _deflate);
+    _subscription = _socket.transform(transformer).listen((data) {
+      if (data is _WebSocketPing) {
+        if (!_writeClosed) _consumer.add(new _WebSocketPong(data.payload));
+      } else if (data is _WebSocketPong) {
+        // Simply set pingInterval, as it'll cancel any timers.
+        pingInterval = _pingInterval;
+      } else {
+        _controller.add(data);
+      }
+    }, onError: (error, stackTrace) {
+      if (_closeTimer != null) _closeTimer.cancel();
+      if (error is FormatException) {
+        _close(WebSocketStatus.INVALID_FRAME_PAYLOAD_DATA);
+      } else {
+        _close(WebSocketStatus.PROTOCOL_ERROR);
+      }
+      // An error happened, set the close code set above.
+      _closeCode = _outCloseCode;
+      _closeReason = _outCloseReason;
+      _controller.close();
+    }, onDone: () {
+      if (_closeTimer != null) _closeTimer.cancel();
+      if (_readyState == WebSocket.OPEN) {
+        _readyState = WebSocket.CLOSING;
+        if (!_isReservedStatusCode(transformer.closeCode)) {
+          _close(transformer.closeCode, transformer.closeReason);
+        } else {
+          _close();
+        }
+        _readyState = WebSocket.CLOSED;
+      }
+      // Protocol close, use close code from transformer.
+      _closeCode = transformer.closeCode;
+      _closeReason = transformer.closeReason;
+      _controller.close();
+    }, cancelOnError: true);
     _subscription.pause();
-    _controller = new StreamController(sync: true,
-                                       onListen: _subscription.resume,
-                                       onCancel: () {
-                                         _subscription.cancel();
-                                         _subscription = null;
-                                       },
-                                       onPause: _subscription.pause,
-                                       onResume: _subscription.resume);
+    _controller = new StreamController(
+        sync: true, onListen: _subscription.resume, onCancel: () {
+      _subscription.cancel();
+      _subscription = null;
+    }, onPause: _subscription.pause, onResume: _subscription.resume);
 
     _webSockets[_serviceId] = this;
-    try { _socket._owner = this; } catch (_) {}
+    try {
+      _socket._owner = this;
+    } catch (_) {}
   }
 
   StreamSubscription listen(void onData(message),
-                            {Function onError,
-                             void onDone(),
-                             bool cancelOnError}) {
+      {Function onError, void onDone(), bool cancelOnError}) {
     return _controller.stream.listen(onData,
-                                     onError: onError,
-                                     onDone: onDone,
-                                     cancelOnError: cancelOnError);
+        onError: onError, onDone: onDone, cancelOnError: cancelOnError);
   }
 
   Duration get pingInterval => _pingInterval;
@@ -1027,13 +1239,12 @@
 
   static bool _isReservedStatusCode(int code) {
     return code != null &&
-           (code < WebSocketStatus.NORMAL_CLOSURE ||
+        (code < WebSocketStatus.NORMAL_CLOSURE ||
             code == WebSocketStatus.RESERVED_1004 ||
             code == WebSocketStatus.NO_STATUS_RECEIVED ||
             code == WebSocketStatus.ABNORMAL_CLOSURE ||
             (code > WebSocketStatus.INTERNAL_SERVER_ERROR &&
-             code < WebSocketStatus.RESERVED_1015) ||
-            (code >= WebSocketStatus.RESERVED_1015 &&
-             code < 3000));
+                code < WebSocketStatus.RESERVED_1015) ||
+            (code >= WebSocketStatus.RESERVED_1015 && code < 3000));
   }
 }
diff --git a/sdk/lib/js/dartium/js_dartium.dart b/sdk/lib/js/dartium/js_dartium.dart
index b01dce0..ce2c5a2 100644
--- a/sdk/lib/js/dartium/js_dartium.dart
+++ b/sdk/lib/js/dartium/js_dartium.dart
@@ -310,8 +310,24 @@
 final _JS_LIBRARY_PREFIX = "js_library";
 final _UNDEFINED_VAR = "_UNDEFINED_JS_CONST";
 
-String _accessJsPath(String path) =>
-    "${_JS_LIBRARY_PREFIX}.context${path.split(".").map((p) => "['$p']").join('')}";
+String _accessJsPath(String path) => _accessJsPathHelper(path.split("."));
+
+String _accessJsPathHelper(Iterable<String> parts) {
+  var sb = new StringBuffer();
+  sb
+    ..write('${_JS_LIBRARY_PREFIX}.JsNative.getProperty(' * parts.length)
+    ..write("${_JS_LIBRARY_PREFIX}.context");
+  for (var p in parts) {
+    sb.write(", '$p')");
+  }
+  return sb.toString();
+}
+
+String _accessJsPathSetter(String path) {
+  var parts = path.split(".");
+  return "${_JS_LIBRARY_PREFIX}.JsNative.setProperty(${_accessJsPathHelper(parts.getRange(0, parts.length - 1))
+      }, '${parts.last}', v)";
+}
 
 @Deprecated("Internal Use Only")
 void addMemberHelper(
@@ -331,9 +347,9 @@
   }
   sb.write(" ");
   if (declaration.isGetter) {
-    sb.write("get $name => ${_accessJsPath(path)};");
+    sb.write("get $name => ${_JS_LIBRARY_PREFIX}.maybeWrapTypedInterop(${_accessJsPath(path)});");
   } else if (declaration.isSetter) {
-    sb.write("set $name(v) => ${_accessJsPath(path)} = v;");
+    sb.write("set $name(v) => ${_JS_LIBRARY_PREFIX}.maybeWrapTypedInterop(${_accessJsPathSetter(path)});");
   } else {
     sb.write("$name(");
     bool hasOptional = false;
@@ -362,6 +378,7 @@
     }
     // TODO(jacobr):
     sb.write(") => ");
+    sb.write('${_JS_LIBRARY_PREFIX}.maybeWrapTypedInterop(');
     if (declaration.isConstructor) {
       sb.write("new ${_JS_LIBRARY_PREFIX}.JsObject(");
     }
@@ -373,18 +390,17 @@
     if (hasOptional) {
       sb.write(".takeWhile((i) => i != ${_UNDEFINED_VAR}).toList()");
     }
-    sb.write(");");
+    sb.write("));");
   }
   sb.write("\n");
 }
 
-// TODO(jacobr): make this check more robust.
-bool _isExternal(mirrors.Mirror mirror) {
-  /*
-  var source = mirror.source;
-  return source != null && source.startsWith("external ");
-  */
-  return mirror.isExternal;
+bool _isExternal(mirrors.MethodMirror mirror) {
+  // This try-catch block is a workaround for BUG:24834.
+  try {
+    return mirror.isExternal;
+  } catch (e) { }
+  return false;
 }
 
 List<String> _generateExternalMethods() {
@@ -853,6 +869,10 @@
   return _cachedContext;
 }
 
+@Deprecated("Internal Use Only")
+maybeWrapTypedInterop(o) =>
+    html_common.wrap_jso_no_SerializedScriptvalue(o);
+
 _maybeWrap(o) {
   var wrapped = html_common.wrap_jso_no_SerializedScriptvalue(o);
   if (identical(wrapped, o)) return o;
@@ -1102,7 +1122,7 @@
         throwError();
       } else {
         // TODO(jacobr): should we throw if the JavaScript object doesn't have the property?
-        return this[name];
+        return maybeWrapTypedInterop(this._operator_getter(name));
       }
     } else if (invocation.isSetter) {
       if (CHECK_JS_INVOCATIONS) {
@@ -1112,7 +1132,8 @@
       }
       assert(name.endsWith("="));
       name = name.substring(0, name.length - 1);
-      return this[name] = invocation.positionalArguments.first;
+      return maybeWrapTypedInterop(_operator_setter(
+          name, invocation.positionalArguments.first));
     } else {
       // TODO(jacobr): also allow calling getters that look like functions.
       var matches;
@@ -1121,7 +1142,7 @@
         if (matches == null ||
             !matches.checkInvocation(invocation)) throwError();
       }
-      var ret = this.callMethod(name, _buildArgs(invocation));
+      var ret = maybeWrapTypedInterop(this._callMethod(name, _buildArgs(invocation)));
       if (CHECK_JS_INVOCATIONS) {
         if (!matches._checkReturnType(ret)) throwError();
       }
@@ -1136,12 +1157,17 @@
 // Warning: this API is not exposed to dart:js.
 @Deprecated("Internal Use Only")
 class JsNative {
-  static getProperty(JsObject o, name) {
-    return o._operator_getter(name);
+  static getProperty(o, name) {
+    o = unwrap_jso(o);
+    return o != null ? o._operator_getter(name) : null;
   }
 
-  static callMethod(JsObject o, String method, List args) {
-    return o._callMethod(method, args);
+  static setProperty(o, name, value) {
+    return unwrap_jso(o)._operator_setter(name, value);
+  }
+
+  static callMethod(o, String method, List args) {
+    return unwrap_jso(o)._callMethod(method, args);
   }
 
   static getArrayIndex(JsArray array, int index) {
diff --git a/sdk/lib/math/random.dart b/sdk/lib/math/random.dart
index 0c1c76c..47c5582 100644
--- a/sdk/lib/math/random.dart
+++ b/sdk/lib/math/random.dart
@@ -9,23 +9,34 @@
  *
  * The default implementation supplies a stream of
  * pseudo-random bits that are not suitable for cryptographic purposes.
+ *
+ * Use the Random.secure() constructor for cryptographic
+ * purposes.
  */
 abstract class Random {
   /**
    * Creates a random number generator.
    *
-   * The optional parameter [seed] is used
-   * to initialize the internal state of the generator. The implementation of
-   * the random stream can change between releases of the library.
+   * The optional parameter [seed] is used to initialize the
+   * internal state of the generator. The implementation of the
+   * random stream can change between releases of the library.
    */
   external factory Random([int seed]);
 
   /**
+   * Creates a cryptographically secure random number generator.
+   *
+   * If the program cannot provide a cryptographically secure
+   * source of random numbers, it throws an [UnsupportedError].
+   */
+  external factory Random.secure();
+
+  /**
    * Generates a non-negative random integer uniformly distributed in the range
    * from 0, inclusive, to [max], exclusive.
    *
    * Implementation note: The default implementation supports [max] values
-   * between 1 and ((1<<32) - 1) inclusive.
+   * between 1 and (1<<32) inclusive.
    */
   int nextInt(int max);
 
diff --git a/sdk/lib/typed_data/typed_data.dart b/sdk/lib/typed_data/typed_data.dart
index b04675c..d972b62 100644
--- a/sdk/lib/typed_data/typed_data.dart
+++ b/sdk/lib/typed_data/typed_data.dart
@@ -10,7 +10,7 @@
 
 /**
  * A sequence of bytes underlying a typed data object.
- * 
+ *
  * Used to process large quantities of binary or numerical data
  * more efficiently using a typed view.
  */
@@ -404,7 +404,7 @@
  * A fixed-length, random-access sequence of bytes that also provides random
  * and unaligned access to the fixed-width integers and floating point
  * numbers represented by those bytes.
- * 
+ *
  * `ByteData` may be used to pack and unpack data from external sources
  * (such as networks or files systems), and to process large quantities
  * of numerical data more efficiently than would be possible
@@ -451,7 +451,7 @@
    * Returns the (possibly negative) integer represented by the byte at the
    * specified [byteOffset] in this object, in two's complement binary
    * representation.
-   * 
+   *
    * The return value will be between -128 and 127, inclusive.
    *
    * Throws [RangeError] if [byteOffset] is negative, or
@@ -463,7 +463,7 @@
    * Sets the byte at the specified [byteOffset] in this object to the
    * two's complement binary representation of the specified [value], which
    * must fit in a single byte.
-   * 
+   *
    * In other words, [value] must be between -128 and 127, inclusive.
    *
    * Throws [RangeError] if [byteOffset] is negative, or
@@ -474,7 +474,7 @@
   /**
    * Returns the positive integer represented by the byte at the specified
    * [byteOffset] in this object, in unsigned binary form.
-   * 
+   *
    * The return value will be between 0 and 255, inclusive.
    *
    * Throws [RangeError] if [byteOffset] is negative, or
@@ -486,7 +486,7 @@
    * Sets the byte at the specified [byteOffset] in this object to the
    * unsigned binary representation of the specified [value], which must fit
    * in a single byte.
-   * 
+   *
    * In other words, [value] must be between 0 and 255, inclusive.
    *
    * Throws [RangeError] if [byteOffset] is negative,
@@ -498,7 +498,7 @@
    * Returns the (possibly negative) integer represented by the two bytes at
    * the specified [byteOffset] in this object, in two's complement binary
    * form.
-   * 
+   *
    * The return value will be between 2<sup>15</sup> and 2<sup>15</sup> - 1,
    * inclusive.
    *
@@ -511,7 +511,7 @@
    * Sets the two bytes starting at the specified [byteOffset] in this
    * object to the two's complement binary representation of the specified
    * [value], which must fit in two bytes.
-   * 
+   *
    * In other words, [value] must lie
    * between 2<sup>15</sup> and 2<sup>15</sup> - 1, inclusive.
    *
@@ -526,7 +526,7 @@
    * Returns the positive integer represented by the two bytes starting
    * at the specified [byteOffset] in this object, in unsigned binary
    * form.
-   * 
+   *
    * The return value will be between 0 and  2<sup>16</sup> - 1, inclusive.
    *
    * Throws [RangeError] if [byteOffset] is negative, or
@@ -538,7 +538,7 @@
    * Sets the two bytes starting at the specified [byteOffset] in this object
    * to the unsigned binary representation of the specified [value],
    * which must fit in two bytes.
-   * 
+   *
    * In other words, [value] must be between
    * 0 and 2<sup>16</sup> - 1, inclusive.
    *
@@ -553,7 +553,7 @@
    * Returns the (possibly negative) integer represented by the four bytes at
    * the specified [byteOffset] in this object, in two's complement binary
    * form.
-   * 
+   *
    * The return value will be between 2<sup>31</sup> and 2<sup>31</sup> - 1,
    * inclusive.
    *
@@ -566,7 +566,7 @@
    * Sets the four bytes starting at the specified [byteOffset] in this
    * object to the two's complement binary representation of the specified
    * [value], which must fit in four bytes.
-   * 
+   *
    * In other words, [value] must lie
    * between 2<sup>31</sup> and 2<sup>31</sup> - 1, inclusive.
    *
@@ -581,7 +581,7 @@
    * Returns the positive integer represented by the four bytes starting
    * at the specified [byteOffset] in this object, in unsigned binary
    * form.
-   * 
+   *
    * The return value will be between 0 and  2<sup>32</sup> - 1, inclusive.
    *
    * Throws [RangeError] if [byteOffset] is negative, or
@@ -593,7 +593,7 @@
    * Sets the four bytes starting at the specified [byteOffset] in this object
    * to the unsigned binary representation of the specified [value],
    * which must fit in four bytes.
-   * 
+   *
    * In other words, [value] must be between
    * 0 and 2<sup>32</sup> - 1, inclusive.
    *
@@ -608,7 +608,7 @@
    * Returns the (possibly negative) integer represented by the eight bytes at
    * the specified [byteOffset] in this object, in two's complement binary
    * form.
-   * 
+   *
    * The return value will be between 2<sup>63</sup> and 2<sup>63</sup> - 1,
    * inclusive.
    *
@@ -621,7 +621,7 @@
    * Sets the eight bytes starting at the specified [byteOffset] in this
    * object to the two's complement binary representation of the specified
    * [value], which must fit in eight bytes.
-   * 
+   *
    * In other words, [value] must lie
    * between 2<sup>63</sup> and 2<sup>63</sup> - 1, inclusive.
    *
@@ -636,7 +636,7 @@
    * Returns the positive integer represented by the eight bytes starting
    * at the specified [byteOffset] in this object, in unsigned binary
    * form.
-   * 
+   *
    * The return value will be between 0 and  2<sup>64</sup> - 1, inclusive.
    *
    * Throws [RangeError] if [byteOffset] is negative, or
@@ -648,7 +648,7 @@
    * Sets the eight bytes starting at the specified [byteOffset] in this object
    * to the unsigned binary representation of the specified [value],
    * which must fit in eight bytes.
-   * 
+   *
    * In other words, [value] must be between
    * 0 and 2<sup>64</sup> - 1, inclusive.
    *
@@ -718,9 +718,13 @@
 
 /**
  * A fixed-length list of 8-bit signed integers.
- * 
+ *
  * For long lists, this implementation can be considerably
  * more space- and time-efficient than the default [List] implementation.
+ *
+ * Integers stored in the list are truncated to their low eight bits,
+ * interpreted as a signed 8-bit two's complement integer with values in the
+ * range -128 to +127.
  */
 abstract class Int8List implements List<int>, TypedData {
   /**
@@ -732,6 +736,9 @@
   /**
    * Creates a [Int8List] with the same length as the [elements] list
    * and copies over the elements.
+   *
+   * Values are truncated to fit in the list when they are copied,
+   * the same way storing values truncates them.
    */
   external factory Int8List.fromList(List<int> elements);
 
@@ -760,9 +767,13 @@
 
 /**
  * A fixed-length list of 8-bit unsigned integers.
- * 
+ *
  * For long lists, this implementation can be considerably
  * more space- and time-efficient than the default [List] implementation.
+ *
+ * Integers stored in the list are truncated to their low eight bits,
+ * interpreted as an unsigned 8-bit integer with values in the
+ * range 0 to 255.
  */
 abstract class Uint8List implements List<int>, TypedData {
   /**
@@ -774,6 +785,9 @@
   /**
    * Creates a [Uint8List] with the same length as the [elements] list
    * and copies over the elements.
+   *
+   * Values are truncated to fit in the list when they are copied,
+   * the same way storing values truncates them.
    */
   external factory Uint8List.fromList(List<int> elements);
 
@@ -802,10 +816,13 @@
 
 /**
  * A fixed-length list of 8-bit unsigned integers.
- * 
+ *
  * For long lists, this implementation can be considerably
  * more space- and time-efficient than the default [List] implementation.
- * Indexed store clamps the value to range 0..0xFF.
+ *
+ * Integers stored in the list are clamped to an unsigned eight bit value.
+ * That is, all values below zero are stored as zero
+ * and all values above 255 are stored as 255.
  */
 abstract class Uint8ClampedList implements List<int>, TypedData {
   /**
@@ -817,6 +834,9 @@
   /**
    * Creates a [Uint8ClampedList] of the same size as the [elements]
    * list and copies over the values clamping when needed.
+   *
+   * Values are clamped to fit in the list when they are copied,
+   * the same way storing values clamps them.
    */
   external factory Uint8ClampedList.fromList(List<int> elements);
 
@@ -847,9 +867,13 @@
 /**
  * A fixed-length list of 16-bit signed integers that is viewable as a
  * [TypedData].
- * 
+ *
  * For long lists, this implementation can be considerably
  * more space- and time-efficient than the default [List] implementation.
+ *
+ * Integers stored in the list are truncated to their low 16 bits,
+ * interpreted as a signed 16-bit two's complement integer with values in the
+ * range -32768 to +32767.
  */
 abstract class Int16List implements List<int>, TypedData {
   /**
@@ -861,6 +885,9 @@
   /**
    * Creates a [Int16List] with the same length as the [elements] list
    * and copies over the elements.
+   *
+   * Values are truncated to fit in the list when they are copied,
+   * the same way storing values truncates them.
    */
   external factory Int16List.fromList(List<int> elements);
 
@@ -893,9 +920,13 @@
 /**
  * A fixed-length list of 16-bit unsigned integers that is viewable as a
  * [TypedData].
- * 
+ *
  * For long lists, this implementation can be considerably
  * more space- and time-efficient than the default [List] implementation.
+ *
+ * Integers stored in the list are truncated to their low 16 bits,
+ * interpreted as an unsigned 16-bit integer with values in the
+ * range 0 to 65536.
  */
 abstract class Uint16List implements List<int>, TypedData {
   /**
@@ -907,6 +938,9 @@
   /**
    * Creates a [Uint16List] with the same length as the [elements] list
    * and copies over the elements.
+   *
+   * Values are truncated to fit in the list when they are copied,
+   * the same way storing values truncates them.
    */
   external factory Uint16List.fromList(List<int> elements);
 
@@ -940,9 +974,13 @@
 /**
  * A fixed-length list of 32-bit signed integers that is viewable as a
  * [TypedData].
- * 
+ *
  * For long lists, this implementation can be considerably
  * more space- and time-efficient than the default [List] implementation.
+ *
+ * Integers stored in the list are truncated to their low 32 bits,
+ * interpreted as a signed 32-bit two's complement integer with values in the
+ * range -2147483648 to 2147483647.
  */
 abstract class Int32List implements List<int>, TypedData {
   /**
@@ -954,6 +992,9 @@
   /**
    * Creates a [Int32List] with the same length as the [elements] list
    * and copies over the elements.
+   *
+   * Values are truncated to fit in the list when they are copied,
+   * the same way storing values truncates them.
    */
   external factory Int32List.fromList(List<int> elements);
 
@@ -986,9 +1027,13 @@
 /**
  * A fixed-length list of 32-bit unsigned integers that is viewable as a
  * [TypedData].
- * 
+ *
  * For long lists, this implementation can be considerably
  * more space- and time-efficient than the default [List] implementation.
+ *
+ * Integers stored in the list are truncated to their low 32 bits,
+ * interpreted as an unsigned 32-bit integer with values in the
+ * range 0 to 4294967295.
  */
 abstract class Uint32List implements List<int>, TypedData {
   /**
@@ -1000,6 +1045,9 @@
   /**
    * Creates a [Uint32List] with the same length as the [elements] list
    * and copies over the elements.
+   *
+   * Values are truncated to fit in the list when they are copied,
+   * the same way storing values truncates them.
    */
   external factory Uint32List.fromList(List<int> elements);
 
@@ -1033,9 +1081,13 @@
 /**
  * A fixed-length list of 64-bit signed integers that is viewable as a
  * [TypedData].
- * 
+ *
  * For long lists, this implementation can be considerably
  * more space- and time-efficient than the default [List] implementation.
+ *
+ * Integers stored in the list are truncated to their low 64 bits,
+ * interpreted as a signed 64-bit two's complement integer with values in the
+ * range -9223372036854775808 to +9223372036854775807.
  */
 abstract class Int64List implements List<int>, TypedData {
   /**
@@ -1047,6 +1099,9 @@
   /**
    * Creates a [Int64List] with the same length as the [elements] list
    * and copies over the elements.
+   *
+   * Values are truncated to fit in the list when they are copied,
+   * the same way storing values truncates them.
    */
   external factory Int64List.fromList(List<int> elements);
 
@@ -1079,9 +1134,13 @@
 /**
  * A fixed-length list of 64-bit unsigned integers that is viewable as a
  * [TypedData].
- * 
+ *
  * For long lists, this implementation can be considerably
  * more space- and time-efficient than the default [List] implementation.
+ *
+ * Integers stored in the list are truncated to their low 64 bits,
+ * interpreted as an unsigned 64-bit integer with values in the
+ * range 0 to 18446744073709551616.
  */
 abstract class Uint64List implements List<int>, TypedData {
   /**
@@ -1093,6 +1152,9 @@
   /**
    * Creates a [Uint64List] with the same length as the [elements] list
    * and copies over the elements.
+   *
+   * Values are truncated to fit in the list when they are copied,
+   * the same way storing values truncates them.
    */
   external factory Uint64List.fromList(List<int> elements);
 
@@ -1125,11 +1187,15 @@
 
 /**
  * A fixed-length list of IEEE 754 single-precision binary floating-point
- * numbers  that is viewable as a [TypedData].
- * 
+ * numbers that is viewable as a [TypedData].
+ *
  * For long lists, this
  * implementation can be considerably more space- and time-efficient than
  * the default [List] implementation.
+ *
+ * Double values stored in the list are converted to the nearest
+ * single-precision value. Values read are converted to a double
+ * value with the same value.
  */
 abstract class Float32List implements List<double>, TypedData {
   /**
@@ -1141,6 +1207,9 @@
   /**
    * Creates a [Float32List] with the same length as the [elements] list
    * and copies over the elements.
+   *
+   * Values are truncated to fit in the list when they are copied,
+   * the same way storing values truncates them.
    */
   external factory Float32List.fromList(List<double> elements);
 
@@ -1173,7 +1242,7 @@
 /**
  * A fixed-length list of IEEE 754 double-precision binary floating-point
  * numbers  that is viewable as a [TypedData].
- * 
+ *
  * For long lists, this
  * implementation can be considerably more space- and time-efficient than
  * the default [List] implementation.
@@ -1220,7 +1289,7 @@
 /**
  * A fixed-length list of Float32x4 numbers that is viewable as a
  * [TypedData].
- * 
+ *
  * For long lists, this implementation will be considerably more
  * space- and time-efficient than the default [List] implementation.
  */
@@ -1266,7 +1335,7 @@
 /**
  * A fixed-length list of Int32x4 numbers that is viewable as a
  * [TypedData].
- * 
+ *
  * For long lists, this implementation will be considerably more
  * space- and time-efficient than the default [List] implementation.
  */
@@ -1312,7 +1381,7 @@
 /**
  * A fixed-length list of Float64x2 numbers that is viewable as a
  * [TypedData].
- * 
+ *
  * For long lists, this implementation will be considerably more
  * space- and time-efficient than the default [List] implementation.
  */
@@ -1357,7 +1426,7 @@
 
 /**
  * Float32x4 immutable value type and operations.
- * 
+ *
  * Float32x4 stores 4 32-bit floating point values in "lanes".
  * The lanes are "x", "y", "z", and "w" respectively.
  */
@@ -1712,7 +1781,7 @@
 
 /**
  * Int32x4 and operations.
- * 
+ *
  * Int32x4 stores 4 32-bit bit-masks in "lanes".
  * The lanes are "x", "y", "z", and "w" respectively.
  */
@@ -2049,7 +2118,7 @@
 
 /**
  * Float64x2 immutable value type and operations.
- * 
+ *
  * Float64x2 stores 2 64-bit floating point values in "lanes".
  * The lanes are "x" and "y" respectively.
  */
diff --git a/sdk/lib/vmservice/asset.dart b/sdk/lib/vmservice/asset.dart
new file mode 100644
index 0000000..7835e74
--- /dev/null
+++ b/sdk/lib/vmservice/asset.dart
@@ -0,0 +1,205 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of dart._vmservice;
+
+class Asset {
+  final String name;
+  final Uint8List data;
+
+  Asset(this.name, this.data);
+
+  String get mimeType {
+    var extensionStart = name.lastIndexOf('.');
+    var extension = name.substring(extensionStart+1);
+    switch (extension) {
+      case 'html':
+        return 'text/html; charset=UTF-8';
+      case 'dart':
+        return 'application/dart; charset=UTF-8';
+      case 'js':
+        return 'application/javascript; charset=UTF-8';
+      case 'css':
+        return 'text/css; charset=UTF-8';
+      case 'gif':
+        return 'image/gif';
+      case 'png':
+        return 'image/png';
+      case 'jpg':
+        return 'image/jpeg';
+      case 'jpeg':
+        return 'image/jpeg';
+      case 'svg':
+        return 'image/svg+xml';
+      default:
+        return 'text/plain';
+    }
+  }
+
+  /// Call to request assets from the embedder.
+  static Map<String, Asset> request() {
+    Map<String, Asset> assets = new Map<String, Asset>();
+    Uint8List tarBytes = _requestAssets();
+    if (tarBytes == null) {
+      return assets;
+    }
+    _TarArchive archive = new _TarArchive(tarBytes);
+    while (archive.hasNext()) {
+      Asset asset = archive.next();
+      if (asset == null) {
+        // Skip over special files.
+        continue;
+      }
+      assets[asset.name] = asset;
+    }
+    return assets;
+  }
+
+  String toString() => '$name ($mimeType)';
+}
+
+
+class _ByteStream {
+  final Uint8List bytes;
+  final int offset;
+  int get length => bytes.length - offset;
+  int _cursor = 0;
+
+  _ByteStream(this.bytes, [this.offset = 0]);
+
+  void reset() {
+    _cursor = 0;
+  }
+
+  int peekByte([int index = 0]) => bytes[offset + _cursor + index];
+
+  int readByte() {
+    int r = peekByte();
+    _advance(1);
+    return r;
+  }
+
+  void skip(int bytes) => _advance(bytes);
+
+  void seekToNextBlock(int blockSize) {
+    int remainder = blockSize - (_cursor % blockSize);
+    _advance(remainder);
+  }
+
+  void _advance(int bytes) {
+    _cursor += bytes;
+    if (_cursor > length) {
+      _cursor = length;
+    }
+  }
+
+  int get remaining => length - _cursor;
+  bool get hasMore => remaining > 0;
+  int get cursor => _cursor;
+  void set cursor(int cursor) {
+    _cursor = cursor;
+    if (_cursor > length) {
+      _cursor = length;
+    }
+  }
+}
+
+class _TarArchive {
+  static const List<int> tarMagic = const [ 0x75, 0x73, 0x74, 0x61, 0x72, 0 ];
+  static const List<int> tarVersion = const [ 0x30, 0x30 ];
+  static const int tarHeaderSize = 512;
+  static const int tarHeaderFilenameSize = 100;
+  static const int tarHeaderFilenameOffset = 0;
+  static const int tarHeaderSizeSize = 12;
+  static const int tarHeaderSizeOffset = 124;
+  static const int tarHeaderTypeSize = 1;
+  static const int tarHeaderTypeOffset = 156;
+  static const int tarHeaderFileType = 0x30;
+
+  static String _readCString(_ByteStream bs, int length) {
+    StringBuffer sb = new StringBuffer();
+    int count = 0;
+    while (bs.hasMore && count < length) {
+      if (bs.peekByte() == 0) {
+        // Null character.
+        break;
+      }
+      sb.writeCharCode(bs.readByte());
+      count++;
+    }
+    return sb.toString();
+  }
+
+  static String _readFilename(_ByteStream bs) {
+    String filename = _readCString(bs, tarHeaderFilenameSize);
+    if (filename.startsWith('/')) {
+      return filename;
+    }
+    return '/' + filename;
+  }
+
+  static Uint8List _readContents(_ByteStream bs, int size) {
+    Uint8List result = new Uint8List(size);
+    int i = 0;
+    while (bs.hasMore && i < size) {
+      result[i] = bs.readByte();
+      i++;
+    }
+    bs.seekToNextBlock(tarHeaderSize);
+    return result;
+  }
+
+  static void _skipContents(_ByteStream bs, int size) {
+    bs.skip(size);
+    bs.seekToNextBlock(tarHeaderSize);
+  }
+
+  static int _readSize(_ByteStream bs) {
+    String octalSize = _readCString(bs, tarHeaderSizeSize);
+    return int.parse(octalSize,
+                     radix: 8,
+                     onError: (_) => 0);
+  }
+
+  static int _readType(_ByteStream bs) {
+    return bs.readByte();
+  }
+
+  static bool _endOfArchive(_ByteStream bs) {
+    if (bs.remaining < (tarHeaderSize * 2)) {
+      return true;
+    }
+    for (int i = 0; i < (tarHeaderSize * 2); i++) {
+      if (bs.peekByte(i) != 0) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  final _ByteStream _bs;
+
+  _TarArchive(Uint8List bytes)
+      : _bs = new _ByteStream(bytes);
+
+  bool hasNext() {
+    return !_endOfArchive(_bs);
+  }
+
+  Asset next() {
+    int startOfBlock = _bs.cursor;
+    String filename = _readFilename(_bs);
+    _bs.cursor = startOfBlock + tarHeaderSizeOffset;
+    int size = _readSize(_bs);
+    _bs.cursor = startOfBlock + tarHeaderTypeOffset;
+    int type = _readType(_bs);
+    _bs.seekToNextBlock(tarHeaderSize);
+    if (type != tarHeaderFileType) {
+      _skipContents(_bs, size);
+      return null;
+    }
+    Uint8List bytes = _readContents(_bs, size);
+    return new Asset(filename, bytes);
+  }
+}
diff --git a/sdk/lib/vmservice/vmservice.dart b/sdk/lib/vmservice/vmservice.dart
index eda4504..6c9e8e5 100644
--- a/sdk/lib/vmservice/vmservice.dart
+++ b/sdk/lib/vmservice/vmservice.dart
@@ -9,6 +9,7 @@
 import 'dart:isolate';
 import 'dart:typed_data';
 
+part 'asset.dart';
 part 'client.dart';
 part 'constants.dart';
 part 'running_isolate.dart';
@@ -329,3 +330,4 @@
 
 external void _vmCancelStream(String streamId);
 
+external Uint8List _requestAssets();
diff --git a/sdk/lib/vmservice/vmservice_sources.gypi b/sdk/lib/vmservice/vmservice_sources.gypi
index 97b2582..869e304 100644
--- a/sdk/lib/vmservice/vmservice_sources.gypi
+++ b/sdk/lib/vmservice/vmservice_sources.gypi
@@ -8,6 +8,7 @@
   'sources': [
     'vmservice.dart',
     # The above file needs to be first as it imports required libraries.
+    'asset.dart',
     'client.dart',
     'constants.dart',
     'running_isolate.dart',
diff --git a/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart b/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart
index 34838d5..433459d 100644
--- a/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart
+++ b/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart
@@ -103,6 +103,8 @@
    *
    * [oldVersion] should match the database's current [version] exactly.
    *
+   * See also:
+   *
    * * [Database.changeVersion](http://www.w3.org/TR/webdatabase/#dom-database-changeversion) from W3C.
    */
   @DomName('Database.changeVersion')
diff --git a/tests/co19/co19-analyzer.status b/tests/co19/co19-analyzer.status
index c11877e..07a8e26 100644
--- a/tests/co19/co19-analyzer.status
+++ b/tests/co19/co19-analyzer.status
@@ -8,28 +8,28 @@
 LayoutTests/fast/forms/checkValidity-001_t01: fail
 
 # TBF: infinite look: class A {const A();final m = const A();}
-Language/12_Expressions/01_Constants_A17_t03: fail
+Language/Expressions/Constants/depending_on_itself_t03: fail
 
 # TBF: when we override "foo([x = 0]) {}" with "foo([x]) {}" we should report warning - different default value
-Language/07_Classes/1_Instance_Methods_A04_t02: MissingStaticWarning
-Language/07_Classes/4_Abstract_Instance_Members_A07_t04: MissingStaticWarning
+Language/Classes/Instance_Methods/override_different_default_values_t02: MissingStaticWarning
+Language/Classes/Abstract_Instance_Members/override_default_value_t04: MissingStaticWarning
 
 # TBF: Static members should not be accessible via subclasses.
-Language/07_Classes/9_Superclasses/1_Inheritance_and_Overriding_A01_t05: MissingStaticWarning
+Language/Classes/Superclasses/Inheritance_and_Overriding/inheritance_t05: MissingStaticWarning
 
 # co19 issue #442, undefined name "Expect"
-Language/15_Types/4_Interface_Types_A08_t03: fail, OK
+Language/Types/Interface_Types/subtype_t12: fail, OK
 
 # co19 issue #438, Static variables are initialized lazily, need not be constants
-Language/12_Expressions/01_Constants_A16_t01: fail, OK
-Language/12_Expressions/01_Constants_A16_t02: fail, OK
+Language/Expressions/Constants/exception_t01: fail, OK
+Language/Expressions/Constants/exception_t02: fail, OK
 
 # co19 issue #543: invocation of a non-function
-Language/12_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A03_t02: fail, OK
+Language/Expressions/Function_Invocation/Function_Expression_Invocation/static_type_t02: fail, OK
 
 # co19 issue #564: URI can be any number adjacent string literals
-Language/14_Libraries_and_Scripts/5_URIs_A01_t24: fail, OK
-Language/14_Libraries_and_Scripts/5_URIs_A01_t25: fail, OK
+Language/Libraries_and_Scripts/URIs/syntax_t14: fail, OK
+Language/Libraries_and_Scripts/URIs/syntax_t15: fail, OK
 
 # co19 issue #615: Expect import missing
 LibTest/collection/LinkedList/LinkedList_A01_t01: Fail, OK
@@ -70,24 +70,24 @@
 LibTest/collection/Queue/Queue_class_A01_t01: Fail, OK
 
 
-Language/12_Expressions/15_Method_Invocation/2_Cascaded_Invocation_A01_t19: MissingStaticWarning
-Language/12_Expressions/29_Assignable_Expressions_A01_t09: MissingStaticWarning
-Language/13_Statements/06_For/1_For_Loop_A01_t07: MissingStaticWarning
-Language/13_Statements/06_For/1_For_Loop_A01_t08: MissingStaticWarning
-Language/13_Statements/09_Switch_A10_t03: MissingStaticWarning
-Language/13_Statements/15_Assert_A04_t04: MissingStaticWarning
+Language/Expressions/Method_Invocation/Cascaded_Invocations/syntax_t19: MissingStaticWarning
+Language/Expressions/Assignable_Expressions/syntax_t09: MissingStaticWarning
+Language/Statements/For/For_Loop/execution_t07: MissingStaticWarning
+Language/Statements/For/For_Loop/execution_t08: MissingStaticWarning
+Language/Statements/Switch/last_statement_t03: MissingStaticWarning
+Language/Statements/Assert/type_t04: MissingStaticWarning
 
-Language/05_Variables/05_Variables_A05_t04: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/05_Variables/05_Variables_A05_t05: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/05_Variables/05_Variables_A05_t06: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/05_Variables/05_Variables_A05_t07: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/05_Variables/05_Variables_A06_t01: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/05_Variables/05_Variables_A06_t02: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/05_Variables/05_Variables_A06_t03: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/12_Expressions/14_Function_Invocation/3_Unqualified_Invocation_A01_t17: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/12_Expressions/14_Function_Invocation/3_Unqualified_Invocation_A01_t18: MissingCompileTimeError # co19-roll r651: Please triage this failure
+Language/Variables/final_t04: MissingCompileTimeError # co19-roll r651: Please triage this failure
+Language/Variables/final_t05: MissingCompileTimeError # co19-roll r651: Please triage this failure
+Language/Variables/final_t06: MissingCompileTimeError # co19-roll r651: Please triage this failure
+Language/Variables/final_t07: MissingCompileTimeError # co19-roll r651: Please triage this failure
+Language/Variables/final_or_static_initialization_t01: MissingCompileTimeError # co19-roll r651: Please triage this failure
+Language/Variables/final_or_static_initialization_t02: MissingCompileTimeError # co19-roll r651: Please triage this failure
+Language/Variables/final_or_static_initialization_t03: MissingCompileTimeError # co19-roll r651: Please triage this failure
+Language/Expressions/Function_Invocation/Unqualified_Invocation/invocation_t17: MissingCompileTimeError # co19-roll r651: Please triage this failure
+Language/Expressions/Function_Invocation/Unqualified_Invocation/invocation_t18: MissingCompileTimeError # co19-roll r651: Please triage this failure
 
-Language/07_Classes/10_Superinterfaces_A07_t05: StaticWarning # co19-roll r667: Please triage this failure
+Language/Classes/Superinterfaces/no_member_A07_t05: StaticWarning # co19-roll r667: Please triage this failure
 LibTest/convert/JsonEncoder/JsonEncoder_A01_t01: StaticWarning # co19-roll r667: Please triage this failure
 
 # co19 issue 656
@@ -101,12 +101,12 @@
 WebPlatformTest/custom-elements/*: Pass, StaticWarning # Issue 18095.
 
 # co19 roll to r706: Please triage all these issues.
-Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A06_t03: StaticWarning # co19-roll r706: Please triage this failure.
-Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A06_t04: StaticWarning # co19-roll r706: Please triage this failure.
-Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A06_t05: StaticWarning # co19-roll r706: Please triage this failure.
-Language/14_Libraries_and_Scripts/3_Parts_A02_t04: CompileTimeError # co19-roll r706: Please triage this failure.
-Language/14_Libraries_and_Scripts/3_Parts_A04_t01: CompileTimeError # co19-roll r706: Please triage this failure.
-Language/14_Libraries_and_Scripts/4_Scripts_A01_t16: CompileTimeError # co19-roll r706: Please triage this failure.
+Language/Expressions/Method_Invocation/Super_Invocation/accessible_instance_member_t03: StaticWarning # co19-roll r706: Please triage this failure.
+Language/Expressions/Method_Invocation/Super_Invocation/accessible_instance_member_t04: StaticWarning # co19-roll r706: Please triage this failure.
+Language/Expressions/Method_Invocation/Super_Invocation/accessible_instance_member_t05: StaticWarning # co19-roll r706: Please triage this failure.
+Language/Libraries_and_Scripts/Parts/compilation_t04: CompileTimeError # co19-roll r706: Please triage this failure.
+Language/Libraries_and_Scripts/Parts/static_warning_t01: CompileTimeError # co19-roll r706: Please triage this failure.
+Language/Libraries_and_Scripts/Scripts/syntax_t11: CompileTimeError # co19-roll r706: Please triage this failure.
 LayoutTests/fast/dom/DOMImplementation/createDocument-namespace-err_t01: StaticWarning # co19-roll r706: Please triage this failure.
 LayoutTests/fast/dom/DOMImplementation/createDocumentType-err_t01: StaticWarning # co19-roll r706: Please triage this failure.
 LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-zoom-and-scroll_t01: StaticWarning # co19-roll r706: Please triage this failure.
@@ -192,8 +192,8 @@
 WebPlatformTest/dom/nodes/Node-parentNode_t01: StaticWarning # co19-roll r722: Please triage this failure.
 
 # co19-roll r738
-Language/07_Classes/4_Abstract_Instance_Members_A07_t02: MissingStaticWarning # co19-roll r738: Please triage this failure.
-Language/07_Classes/07_Classes_A03_t06: MissingStaticWarning # co19-roll r738: Please triage this failure.
+Language/Classes/Abstract_Instance_Members/override_default_value_t02: MissingStaticWarning # co19-roll r738: Please triage this failure.
+Language/Classes/method_definition_t06: MissingStaticWarning # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/StyleSheet/detached-parent-rule-without-wrapper_t01: StaticWarning # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/StyleSheet/detached-stylesheet-without-wrapper_t01: StaticWarning # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/StyleSheet/removed-media-rule-deleted-parent-crash_t01: StaticWarning # co19-roll r738: Please triage this failure.
@@ -289,6 +289,5 @@
 LayoutTests/fast/xpath/4XPath/Core/test_core_functions_t01: StaticWarning # co19 issue 703
 WebPlatformTest/dom/Node-replaceChild_t01: CompileTimeError # co19-roll r761: Please triage this failure.
 WebPlatformTest/html/semantics/forms/the-input-element/email_t02: StaticWarning # co19 issue 701
-Language/12_Expressions/12_Instance_Creation/2_Const_A11_t01: MissingCompileTimeError # Issue 22010
-Language/12_Expressions/12_Instance_Creation/2_Const_A11_t03: MissingCompileTimeError # Issue 22010
-
+Language/Expressions/Instance_Creation/Const/abstract_class_t01: MissingCompileTimeError # Issue 22010
+Language/Expressions/Instance_Creation/Const/abstract_class_t03: MissingCompileTimeError # Issue 22010
diff --git a/tests/co19/co19-analyzer2.status b/tests/co19/co19-analyzer2.status
index aa341d6..3c67e8e 100644
--- a/tests/co19/co19-analyzer2.status
+++ b/tests/co19/co19-analyzer2.status
@@ -6,29 +6,25 @@
 
 WebPlatformTest/html/semantics/forms/the-textarea-element/textarea-type_t01: fail
 LayoutTests/fast/forms/checkValidity-001_t01: fail
-Language/12_Expressions/29_Assignable_Expressions_A01_t08: StaticWarning
-Language/14_Libraries_and_Scripts/3_Parts_A03_t11: fail, pass # Issue 23595
+Language/Expressions/Assignable_Expressions/syntax_t08: StaticWarning
+Language/Libraries_and_Scripts/Parts/compilation_t15: fail, pass # Issue 23595
 
 # TBF: Static members should not be accessible via subclasses.
-Language/07_Classes/9_Superclasses/1_Inheritance_and_Overriding_A01_t05: MissingStaticWarning
-
-# TBF: noSuchMethod can now be inherited
-Language/07_Classes/4_Abstract_Instance_Members_A02_t03: fail, OK
-Language/07_Classes/4_Abstract_Instance_Members_A02_t04: fail, OK
+Language/Classes/Superclasses/Inheritance_and_Overriding/inheritance_t05: MissingStaticWarning
 
 # co19 issue #442, undefined name "Expect"
-Language/15_Types/4_Interface_Types_A08_t03: fail, OK
+Language/Types/Interface_Types/subtype_t12: fail, OK
 
 # co19 issue #438, Static variables are initialized lazily, need not be constants
-Language/12_Expressions/01_Constants_A16_t01: fail, OK
-Language/12_Expressions/01_Constants_A16_t02: fail, OK
+Language/Expressions/Constants/exception_t01: fail, OK
+Language/Expressions/Constants/exception_t02: fail, OK
 
 # co19 issue #543: invocation of a non-function
-Language/12_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A03_t02: fail, OK
+Language/Expressions/Function_Invocation/Function_Expression_Invocation/static_type_t02: fail, OK
 
 # co19 issue #564: URI can be any number adjacent string literals
-Language/14_Libraries_and_Scripts/5_URIs_A01_t24: fail, OK
-Language/14_Libraries_and_Scripts/5_URIs_A01_t25: fail, OK
+Language/Libraries_and_Scripts/URIs/syntax_t14: fail, OK
+Language/Libraries_and_Scripts/URIs/syntax_t15: fail, OK
 
 # co19 issue #615: Expect import missing
 LibTest/collection/LinkedList/LinkedList_A01_t01: Fail, OK
@@ -69,23 +65,23 @@
 LibTest/collection/Queue/Queue_class_A01_t01: Fail, OK
 
 
-Language/12_Expressions/15_Method_Invocation/2_Cascaded_Invocation_A01_t19: MissingStaticWarning
-Language/13_Statements/06_For/1_For_Loop_A01_t07: MissingStaticWarning
-Language/13_Statements/06_For/1_For_Loop_A01_t08: MissingStaticWarning
-Language/13_Statements/09_Switch_A10_t03: MissingStaticWarning
-Language/13_Statements/15_Assert_A04_t04: MissingStaticWarning
+Language/Expressions/Method_Invocation/Cascaded_Invocations/syntax_t19: MissingStaticWarning
+Language/Statements/For/For_Loop/execution_t07: MissingStaticWarning
+Language/Statements/For/For_Loop/execution_t08: MissingStaticWarning
+Language/Statements/Switch/last_statement_t03: MissingStaticWarning
+Language/Statements/Assert/type_t04: MissingStaticWarning
 
-Language/05_Variables/05_Variables_A05_t04: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/05_Variables/05_Variables_A05_t05: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/05_Variables/05_Variables_A05_t06: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/05_Variables/05_Variables_A05_t07: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/05_Variables/05_Variables_A06_t01: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/05_Variables/05_Variables_A06_t02: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/05_Variables/05_Variables_A06_t03: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/12_Expressions/14_Function_Invocation/3_Unqualified_Invocation_A01_t17: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/12_Expressions/14_Function_Invocation/3_Unqualified_Invocation_A01_t18: MissingCompileTimeError # co19-roll r651: Please triage this failure
+Language/Variables/final_t04: MissingCompileTimeError # co19-roll r651: Please triage this failure
+Language/Variables/final_t05: MissingCompileTimeError # co19-roll r651: Please triage this failure
+Language/Variables/final_t06: MissingCompileTimeError # co19-roll r651: Please triage this failure
+Language/Variables/final_t07: MissingCompileTimeError # co19-roll r651: Please triage this failure
+Language/Variables/final_or_static_initialization_t01: MissingCompileTimeError # co19-roll r651: Please triage this failure
+Language/Variables/final_or_static_initialization_t02: MissingCompileTimeError # co19-roll r651: Please triage this failure
+Language/Variables/final_or_static_initialization_t03: MissingCompileTimeError # co19-roll r651: Please triage this failure
+Language/Expressions/Function_Invocation/Unqualified_Invocation/invocation_t17: MissingCompileTimeError # co19-roll r651: Please triage this failure
+Language/Expressions/Function_Invocation/Unqualified_Invocation/invocation_t18: MissingCompileTimeError # co19-roll r651: Please triage this failure
 
-Language/07_Classes/10_Superinterfaces_A07_t05: StaticWarning # co19-roll r667: Please triage this failure
+Language/Classes/Superinterfaces/no_member_t05: StaticWarning # co19-roll r667: Please triage this failure
 LibTest/convert/JsonEncoder/JsonEncoder_A01_t01: StaticWarning # co19-roll r667: Please triage this failure
 
 # co19 issue 656
@@ -99,12 +95,12 @@
 WebPlatformTest/custom-elements/*: Pass, StaticWarning # Issue 18095.
 
 # co19 roll to r706: Please triage all these issues.
-Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A06_t03: StaticWarning # co19-roll r706: Please triage this failure.
-Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A06_t04: StaticWarning # co19-roll r706: Please triage this failure.
-Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A06_t05: StaticWarning # co19-roll r706: Please triage this failure.
-Language/14_Libraries_and_Scripts/3_Parts_A02_t04: CompileTimeError # co19-roll r706: Please triage this failure.
-Language/14_Libraries_and_Scripts/3_Parts_A04_t01: CompileTimeError # co19-roll r706: Please triage this failure.
-Language/14_Libraries_and_Scripts/4_Scripts_A01_t16: CompileTimeError # co19-roll r706: Please triage this failure.
+Language/Expressions/Method_Invocation/Super_Invocation/accessible_instance_member_t03: StaticWarning # co19-roll r706: Please triage this failure.
+Language/Expressions/Method_Invocation/Super_Invocation/accessible_instance_member_t04: StaticWarning # co19-roll r706: Please triage this failure.
+Language/Expressions/Method_Invocation/Super_Invocation/accessible_instance_member_t05: StaticWarning # co19-roll r706: Please triage this failure.
+Language/Libraries_and_Scripts/Parts/compilation_t04: CompileTimeError # co19-roll r706: Please triage this failure.
+Language/Libraries_and_Scripts/Parts/static_warning_t01: CompileTimeError # co19-roll r706: Please triage this failure.
+Language/Libraries_and_Scripts/Scripts/syntax_t11: CompileTimeError # co19-roll r706: Please triage this failure.
 LayoutTests/fast/dom/DOMImplementation/createDocument-namespace-err_t01: StaticWarning # co19-roll r706: Please triage this failure.
 LayoutTests/fast/dom/DOMImplementation/createDocumentType-err_t01: StaticWarning # co19-roll r706: Please triage this failure.
 LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-zoom-and-scroll_t01: StaticWarning # co19-roll r706: Please triage this failure.
@@ -190,7 +186,7 @@
 WebPlatformTest/dom/nodes/Node-parentNode_t01: StaticWarning # co19-roll r722: Please triage this failure.
 
 # co19-roll r738
-Language/07_Classes/07_Classes_A03_t06: MissingStaticWarning # co19-roll r738: Please triage this failure.
+Language/Classes/Classes/method_definition_t06: MissingStaticWarning # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/StyleSheet/detached-parent-rule-without-wrapper_t01: StaticWarning # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/StyleSheet/detached-stylesheet-without-wrapper_t01: StaticWarning # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/StyleSheet/removed-media-rule-deleted-parent-crash_t01: StaticWarning # co19-roll r738: Please triage this failure.
@@ -286,34 +282,119 @@
 LayoutTests/fast/xpath/4XPath/Core/test_core_functions_t01: StaticWarning # co19 issue 703
 WebPlatformTest/dom/Node-replaceChild_t01: CompileTimeError # co19-roll r761: Please triage this failure.
 WebPlatformTest/html/semantics/forms/the-input-element/email_t02: StaticWarning # co19 issue 701
-Language/12_Expressions/12_Instance_Creation/2_Const_A11_t01: MissingCompileTimeError # Issue 22010
-Language/12_Expressions/12_Instance_Creation/2_Const_A11_t03: MissingCompileTimeError # Issue 22010
-Language/15_Types/4_Interface_Types_A10_t03: StaticWarning # co19 issue 745
-Language/15_Types/4_Interface_Types_A10_t07: StaticWarning # co19 issue 745
-Language/15_Types/4_Interface_Types_A10_t09: StaticWarning # co19 issue 745
-Language/13_Statements/15_Assert_A04_t07: StaticWarning # Issue 23663
-Language/13_Statements/15_Assert_A03_t08: StaticWarning # Issue 23663
+Language/Expressions/Instance_Creation/Const/abstract_class_t01: MissingCompileTimeError # Issue 22010
+Language/Expressions/Instance_Creation/Const/abstract_class_t03: MissingCompileTimeError # Issue 22010
+Language/Types/Interface_Types/subtype_t19: StaticWarning # co19 issue 745
+Language/Types/Interface_Types/subtype_t22: StaticWarning # co19 issue 745
+Language/Types/Interface_Types/subtype_t24: StaticWarning # co19 issue 745
+Language/Statements/Assert/type_t07: StaticWarning # Issue 23663
+Language/Statements/Assert/execution_t08: StaticWarning # Issue 23663
 
 # isProtocolHandlerRegistered and unregisterProtocolHandler don't exist
-LayoutTests/fast/dom/navigatorcontentutils/is-protocol-handler-registered_t01: Skip
-WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t01: StaticWarning
-WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t02: StaticWarning
-WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t03: StaticWarning
-WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t04: StaticWarning
-WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t05: StaticWarning
-WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t06: StaticWarning
-LayoutTests/fast/dom/navigatorcontentutils/unregister-protocol-handler_t01: StaticWarning
+LayoutTests/fast/dom/navigatorcontentutils/is-protocol-handler-registered_t01: Skip # Please triage this failure.
+WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t01: StaticWarning # Please triage this failure.
+WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t02: StaticWarning # Please triage this failure.
+WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t03: StaticWarning # Please triage this failure.
+WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t04: StaticWarning # Please triage this failure.
+WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t05: StaticWarning # Please triage this failure.
+WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t06: StaticWarning # Please triage this failure.
+LayoutTests/fast/dom/navigatorcontentutils/unregister-protocol-handler_t01: StaticWarning # Please triage this failure.
 
 # Missing concrete implementation of setter 'XPathNSResolver.blink_jsObject' and getter 'XPathNSResolver.blink_jsObject'
 # TODO(terry): Dartium only because of implements instead of extends consider fixing by making blink_jsObject private
 #              with private wrap_jso and unwrap_jso in each library that delegates to the public wrap/unwrap_jso.
-LayoutTests/fast/xpath/4XPath/Core/test_core_functions_t02: StaticWarning
-LayoutTests/fast/xpath/4XPath/Core/test_node_test_t01: StaticWarning
-LayoutTests/fast/xpath/4XPath/Core/test_node_test_t02: StaticWarning
-LayoutTests/fast/xpath/attr-namespace_t01: StaticWarning
-LayoutTests/fast/xpath/attr-namespace_t02: StaticWarning
-LayoutTests/fast/xpath/node-name-case-sensitivity_t01: StaticWarning
-LayoutTests/fast/xpath/node-name-case-sensitivity_t02: StaticWarning
-LayoutTests/fast/xpath/py-dom-xpath/data_t01: StaticWarning
-LayoutTests/fast/svg/getbbox_t01: StaticWarning
+LayoutTests/fast/xpath/4XPath/Core/test_core_functions_t02: StaticWarning # Please triage this failure.
+LayoutTests/fast/xpath/4XPath/Core/test_node_test_t01: StaticWarning # Please triage this failure.
+LayoutTests/fast/xpath/4XPath/Core/test_node_test_t02: StaticWarning # Please triage this failure.
+LayoutTests/fast/xpath/attr-namespace_t01: StaticWarning # Please triage this failure.
+LayoutTests/fast/xpath/attr-namespace_t02: StaticWarning # Please triage this failure.
+LayoutTests/fast/xpath/node-name-case-sensitivity_t01: StaticWarning # Please triage this failure.
+LayoutTests/fast/xpath/node-name-case-sensitivity_t02: StaticWarning # Please triage this failure.
+LayoutTests/fast/xpath/py-dom-xpath/data_t01: StaticWarning # Please triage this failure.
+LayoutTests/fast/svg/getbbox_t01: StaticWarning # Please triage this failure.
 
+# co19 roll to Sep 29 2015 (3ed795ea02e022ef19c77cf1b6095b7c8f5584d0)
+Language/Classes/Abstract_Instance_Members/invocation_t03: MissingStaticWarning # Please triage this failure.
+Language/Classes/Abstract_Instance_Members/invocation_t04: MissingStaticWarning # Please triage this failure.
+Language/Classes/Getters/static_t01: StaticWarning # Please triage this failure.
+Language/Classes/Getters/type_object_t01: StaticWarning # Please triage this failure.
+Language/Classes/Getters/type_object_t02: StaticWarning # Please triage this failure.
+Language/Classes/Instance_Variables/definition_t03: StaticWarning # Please triage this failure.
+Language/Classes/Setters/syntax_t04: StaticWarning # Please triage this failure.
+Language/Classes/Setters/type_object_t01: StaticWarning # Please triage this failure.
+Language/Classes/Setters/type_object_t02: StaticWarning # Please triage this failure.
+Language/Classes/Static_Methods/same_name_method_and_setter_t01: MissingStaticWarning # Please triage this failure.
+Language/Classes/Static_Methods/type_object_t01: StaticWarning # Please triage this failure.
+Language/Classes/Static_Methods/type_object_t02: StaticWarning # Please triage this failure.
+Language/Classes/method_definition_t06: MissingStaticWarning # Please triage this failure.
+Language/Enums/declaration_equivalent_t03: StaticWarning # Please triage this failure.
+Language/Enums/declaration_equivalent_t05: StaticWarning # Please triage this failure.
+Language/Enums/declaration_equivalent_t08: StaticWarning # Please triage this failure.
+Language/Expressions/Lookup/Method_Lookup/superclass_t07: StaticWarning # Please triage this failure.
+Language/Expressions/Lookup/Method_Lookup/superclass_t08: StaticWarning # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/expression_evaluation_t01: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/expression_evaluation_t02: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/expression_evaluation_t03: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t01: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t02: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t03: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t04: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t01: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t02: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t03: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t04: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t01: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t02: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t03: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t04: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t05: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t06: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t07: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t08: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t01: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t02: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t03: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t04: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/static_type_t01: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/static_type_t02: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/static_type_t03: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/static_type_t04: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/static_type_t05: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t01: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t02: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t03: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t04: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t05: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t06: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t07: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t08: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/expression_evaluation_t07: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/no_such_method_t01: StaticWarning # Please triage this failure.
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/proxy_annotation_t05: StaticWarning # Please triage this failure.
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/proxy_annotation_t06: StaticWarning # Please triage this failure.
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/proxy_annotation_t07: StaticWarning # Please triage this failure.
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/proxy_annotation_t08: StaticWarning # Please triage this failure.
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/deferred_type_t01: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/malformed_type_t01: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/malformed_type_t02: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/not_class_t01: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/not_class_t02: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/not_class_t03: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Super_Getter_Access_and_Method_Closurization/no_such_method_t01: StaticWarning # Please triage this failure.
+Language/Expressions/Property_Extraction/Super_Getter_Access_and_Method_Closurization/static_type_t01: StaticWarning # Please triage this failure.
+Language/Expressions/Property_Extraction/Super_Getter_Access_and_Method_Closurization/static_type_t02: StaticWarning # Please triage this failure.
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/inheritance_t03: StaticWarning # Please triage this failure.
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_getters_type_t07: StaticWarning # Please triage this failure.
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_method_and_getter_t01: CompileTimeError # Please triage this failure.
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_method_and_getter_t02: CompileTimeError # Please triage this failure.
+Language/Libraries_and_Scripts/Imports/namespace_changes_t10: CompileTimeError # Please triage this failure.
+Language/Libraries_and_Scripts/URIs/syntax_t04: CompileTimeError # Please triage this failure.
+Language/Libraries_and_Scripts/URIs/syntax_t05: CompileTimeError # Please triage this failure.
+Language/Libraries_and_Scripts/URIs/syntax_t09: CompileTimeError # Please triage this failure.
+Language/Libraries_and_Scripts/URIs/syntax_t10: CompileTimeError # Please triage this failure.
+Language/Mixins/Mixin_Application/abstract_t01: StaticWarning # Please triage this failure.
+Language/Mixins/Mixin_Application/abstract_t02: StaticWarning # Please triage this failure.
+Language/Mixins/Mixin_Application/error_t01: MissingCompileTimeError # Please triage this failure.
+Language/Mixins/Mixin_Application/error_t02: MissingCompileTimeError # Please triage this failure.
+Language/Mixins/Mixin_Application/warning_t01: MissingStaticWarning # Please triage this failure.
+Language/Mixins/Mixin_Application/warning_t02: MissingStaticWarning # Please triage this failure.
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index c28d8d8..3c1347e 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -22,7 +22,6 @@
 Language/12_Expressions/30_Identifier_Reference_A01_t03: Skip
 
 LibTest/typed_data/ByteData/buffer_A01_t01: Fail # co19 r736 bug - sent comment.
-LayoutTests/fast/mediastream/getusermedia_t01: Fail # co19 issue 738.
 
 LibTest/core/RegExp/firstMatch_A01_t01: Fail # co19 issue 742
 
@@ -43,16 +42,16 @@
 
 LibTest/core/Symbol/Symbol_A01_t04: RuntimeError # co19-roll r607: Please triage this failure
 
-Language/07_Classes/07_Classes_A13_t01: Pass, MissingCompileTimeError, Fail # co19-roll r623: Please triage this failure
-Language/07_Classes/07_Classes_A13_t04: Pass, MissingCompileTimeError, Fail # co19-roll r623: Please triage this failure
-Language/07_Classes/07_Classes_A13_t07: Pass, MissingCompileTimeError, Fail # co19-roll r623: Please triage this failure
+Language/Classes/same_name_type_variable_t01: Pass, MissingCompileTimeError, Fail # co19-roll r623: Please triage this failure
+Language/Classes/same_name_type_variable_t04: Pass, MissingCompileTimeError, Fail # co19-roll r623: Please triage this failure
+Language/Classes/same_name_type_variable_t07: Pass, MissingCompileTimeError, Fail # co19-roll r623: Please triage this failure
 
 LibTest/math/acos_A01_t01: PASS, FAIL, OK # co19 issue 44
 LibTest/math/asin_A01_t01: PASS, FAIL, OK # co19 issue 44
 LibTest/math/atan_A01_t01: PASS, FAIL, OK # co19 issue 44
 
 LibTest/math/cos_A01_t01: PASS, FAIL, OK # co19 issue 44
-LibTest/math/tan_A01_t01: PASS, FAIL, OK  # co19 issue 44
+LibTest/math/tan_A01_t01: PASS, FAIL, OK # co19 issue 44
 
 LibTest/core/Expando/Expando_A03_t01: RuntimeError # Issue 17735
 LibTest/core/Expando/Expando_A03_t03: RuntimeError # Issue 17735
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index ee0adbe..7b463d9 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -3,48 +3,147 @@
 # BSD-style license that can be found in the LICENSE file.
 
 [ $compiler == dart2js ]
-Language/12_Expressions/00_Object_Identity/1_Object_Identity_A05_t02: RuntimeError # Issue 1533 (int/double related)
-Language/03_Overview/1_Scoping_A02_t05: RuntimeError # co19 issue 3
-Language/03_Overview/1_Scoping_A02_t06: RuntimeError # co19 issue 3
-Language/03_Overview/1_Scoping_A02_t28: fail # Issue 21092 and co19 issue 713
-Language/05_Variables/05_Variables_A05_t01: fail # Issue 21093
-Language/05_Variables/05_Variables_A05_t02: fail # Issue 21093
-Language/05_Variables/05_Variables_A11_t01: MissingCompileTimeError # Issue 21050
-Language/06_Functions/4_External_Functions_A01_t01: CompileTimeError, OK # Issue 5021
-Language/07_Classes/07_Classes_A13_t02: Fail # Missing CT error on member with same name a type parameter
-Language/07_Classes/07_Classes_A13_t03: Fail # Missing CT error on member with same name a type parameter
-Language/07_Classes/07_Classes_A13_t05: Fail # Missing CT error on member with same name a type parameter
-Language/07_Classes/07_Classes_A13_t06: Fail # Missing CT error on member with same name a type parameter
-Language/07_Classes/07_Classes_A13_t08: Fail # Missing CT error on member with same name a type parameter
-Language/07_Classes/07_Classes_A13_t09: Fail # Missing CT error on member with same name a type parameter
-Language/07_Classes/1_Instance_Methods_A07_t01: fail # Issue 21201
-Language/07_Classes/3_Setters_A04_t01: CompileTimeError # Issue 5023
-Language/07_Classes/3_Setters_A04_t02: CompileTimeError # Issue 5023
-Language/07_Classes/3_Setters_A04_t03: RuntimeError # Issue 5023
-Language/07_Classes/3_Setters_A04_t07: CompileTimeError # Issue 5023
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A12_t02: fail # Issue 13363
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A13_t01: RuntimeError # compiler cancelled: cannot resolve type T
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A13_t01: RuntimeError, OK # co19 issue 258
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A20_t02: fail # Issue 13363
-Language/10_Generics/09_Generics_A01_t17: fail # Issue 21203
-Language/12_Expressions/00_Object_Identity/1_Object_Identity_A02_t02: fail # Issue 11551, also related to issue 563, 18738
-Language/12_Expressions/00_Object_Identity/1_Object_Identity_A06_t01: fail # Issue 11551, also related to issue 563, 18738
-Language/12_Expressions/01_Constants_A03_t01: CompileTimeError # Issue 13652
-Language/12_Expressions/03_Numbers_A01_t06: fail # Issue 21098
-Language/12_Expressions/03_Numbers_A01_t09: fail # Issue 21098
-Language/12_Expressions/07_Maps_A11_t01: CompileTimeError # Maybe ok. Issue 17207
-Language/12_Expressions/12_Instance_Creation/2_Const_A11_t01: fail # Issue 21134 and co19 issue 714
-Language/12_Expressions/12_Instance_Creation/2_Const_A11_t03: fail # Issue 21134 and co19 issue 714
-Language/12_Expressions/30_Identifier_Reference_A02_t01: fail # Issue 21154
-Language/13_Statements/04_Local_Function_Declaration_A04_t01: MissingCompileTimeError # Issue 21050
-Language/13_Statements/04_Local_Function_Declaration_A04_t03: MissingCompileTimeError # Issue 21050
-Language/14_Libraries_and_Scripts/1_Imports_A03_t08: fail # Issue 21171
-Language/14_Libraries_and_Scripts/1_Imports_A03_t28: fail # Issue 21171
-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_A11_t04: fail # Issue 14654
-Language/16_Reference/1_Lexical_Rules/1_Reserved_Words_A40_t04: MissingCompileTimeError # Checks that other Unicode whitespaces are not allowed:  check NO-BREAK SPACE (U+00A0)
-Language/16_Reference/1_Lexical_Rules_A02_t06: MissingCompileTimeError # Checks that Unicode whitespaces other than WHITESPACE are not permitted in the source code. Checks symbol U+00a0.
+
+Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t01: MissingCompileTimeError # Please triage this failure
+Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t02: MissingCompileTimeError # Please triage this failure
+Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t03: MissingCompileTimeError # Please triage this failure
+Language/Classes/Constructors/Constant_Constructors/not_a_constant_in_superclass_t01: MissingCompileTimeError # Please triage this failure
+Language/Classes/Constructors/Constant_Constructors/not_a_constant_in_superclass_t02: MissingCompileTimeError # Please triage this failure
+Language/Classes/Constructors/Generative_Constructors/execution_of_a_superinitializer_t01: RuntimeError # compiler cancelled: cannot resolve type T
+Language/Classes/Constructors/Generative_Constructors/execution_of_a_superinitializer_t01: RuntimeError, OK # co19 issue 258
+Language/Classes/Constructors/Generative_Constructors/execution_of_an_initializer_t02: fail # Issue 13363
+Language/Classes/Constructors/Generative_Constructors/initializing_formals_execution_t02: fail # Issue 13363
+Language/Classes/Getters/type_object_t01: RuntimeError # Please triage this failure
+Language/Classes/Getters/type_object_t02: RuntimeError # Please triage this failure
+Language/Classes/Instance_Methods/same_name_setter_t01: fail # Issue 21201
+Language/Classes/Setters/name_t01: CompileTimeError # Issue 5023
+Language/Classes/Setters/name_t02: CompileTimeError # Issue 5023
+Language/Classes/Setters/name_t03: RuntimeError # Issue 5023
+Language/Classes/Setters/name_t07: CompileTimeError # Issue 5023
+Language/Classes/Setters/syntax_t04: RuntimeError # Please triage this failure
+Language/Classes/Setters/type_object_t01: RuntimeError # Please triage this failure
+Language/Classes/Setters/type_object_t02: RuntimeError # Please triage this failure
+Language/Classes/Static_Methods/same_name_method_and_setter_t01: CompileTimeError # Please triage this failure
+Language/Classes/Static_Methods/type_object_t01: RuntimeError # Please triage this failure
+Language/Classes/Static_Methods/type_object_t02: RuntimeError # Please triage this failure
+Language/Classes/Superclasses/wrong_superclass_t04: MissingCompileTimeError # Please triage this failure
+Language/Classes/Superclasses/wrong_superclass_t07: MissingCompileTimeError # Please triage this failure
+Language/Classes/Superclasses/wrong_superclass_t08: MissingCompileTimeError # Please triage this failure
+Language/Classes/Superinterfaces/wrong_type_t04: MissingCompileTimeError # Please triage this failure
+Language/Classes/Superinterfaces/wrong_type_t05: MissingCompileTimeError # Please triage this failure
+Language/Classes/same_name_type_variable_t02: Fail # Missing CT error on member with same name a type parameter
+Language/Classes/same_name_type_variable_t03: Fail # Missing CT error on member with same name a type parameter
+Language/Classes/same_name_type_variable_t05: Fail # Missing CT error on member with same name a type parameter
+Language/Classes/same_name_type_variable_t06: Fail # Missing CT error on member with same name a type parameter
+Language/Classes/same_name_type_variable_t08: Fail # Missing CT error on member with same name a type parameter
+Language/Classes/same_name_type_variable_t09: Fail # Missing CT error on member with same name a type parameter
+Language/Enums/restrictions_t01: MissingCompileTimeError # Please triage this failure
+Language/Enums/restrictions_t02: MissingCompileTimeError # Please triage this failure
+Language/Enums/restrictions_t05: MissingCompileTimeError # Please triage this failure
+Language/Enums/restrictions_t06: MissingCompileTimeError # Please triage this failure
+Language/Enums/restrictions_t07: MissingCompileTimeError # Please triage this failure
+Language/Enums/syntax_t02: MissingCompileTimeError # Please triage this failure
+Language/Errors_and_Warnings/compile_error_t06: MissingCompileTimeError # Please triage this failure
+Language/Errors_and_Warnings/compile_error_t07: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Identifier_Reference/syntax_built_in_t01: fail # Issue 21154
+Language/Expressions/Maps/static_type_dynamic_t01: CompileTimeError # Maybe ok. Issue 17207
+Language/Expressions/Numbers/syntax_t06: fail # Issue 21098
+Language/Expressions/Numbers/syntax_t09: fail # Issue 21098
+Language/Expressions/Object_Identity/Object_Identity/constant_objects_t01: fail # Issue 11551, also related to issue 563, 18738
+Language/Expressions/Object_Identity/Object_Identity/double_t02: fail # Issue 11551, also related to issue 563, 18738
+Language/Expressions/Object_Identity/constant_objects_t01: RuntimeError # Please triage this failure
+Language/Expressions/Object_Identity/double_t02: RuntimeError # Please triage this failure
+Language/Expressions/Object_Identity/object_t02: RuntimeError # Issue 1533 (int/double related)
+Language/Expressions/Property_Extraction/General_Closurization/expression_evaluation_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/expression_evaluation_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/expression_evaluation_t03: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t03: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t04: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t03: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t04: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t03: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t04: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t05: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t06: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t07: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t08: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t03: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t04: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/static_type_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/static_type_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/static_type_t03: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/static_type_t04: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/static_type_t05: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t01: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t02: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t03: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t04: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t05: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t06: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t07: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t08: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/expression_evaluation_t07: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/no_such_method_t01: RuntimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/deferred_type_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/malformed_type_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/malformed_type_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/not_class_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/not_class_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/not_class_t03: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Super_Getter_Access_and_Method_Closurization/no_such_method_t01: RuntimeError # Please triage this failure
+Language/Functions/External_Functions/not_connected_to_a_body_t01: CompileTimeError, OK # Issue 5021
+Language/Generics/syntax_t17: fail # Issue 21203
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_method_and_getter_t01: CompileTimeError # Please triage this failure
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_method_and_getter_t02: CompileTimeError # Please triage this failure
+Language/Libraries_and_Scripts/Imports/namespace_changes_t10: CompileTimeError # Please triage this failure
+Language/Libraries_and_Scripts/Imports/same_name_t08: fail # Issue 21171
+Language/Libraries_and_Scripts/Imports/same_name_t18: fail # Issue 21171
+Language/Libraries_and_Scripts/URIs/syntax_t04: CompileTimeError # Please triage this failure
+Language/Libraries_and_Scripts/URIs/syntax_t05: CompileTimeError # Please triage this failure
+Language/Libraries_and_Scripts/URIs/syntax_t09: CompileTimeError # Please triage this failure
+Language/Libraries_and_Scripts/URIs/syntax_t10: CompileTimeError # Please triage this failure
+Language/Libraries_and_Scripts/URIs/syntax_t14: CompileTimeError # Please triage this failure
+Language/Libraries_and_Scripts/URIs/syntax_t15: CompileTimeError # Please triage this failure
+Language/Metadata/before_export_t01: RuntimeError # Please triage this failure
+Language/Metadata/before_import_t01: RuntimeError # Please triage this failure
+Language/Metadata/before_library_t01: RuntimeError # Please triage this failure
+Language/Metadata/before_param_t09: RuntimeError # Please triage this failure
+Language/Metadata/before_type_param_t01: CompileTimeError # Please triage this failure
+Language/Metadata/before_typedef_t01: RuntimeError # Please triage this failure
+Language/Metadata/before_variable_t01: RuntimeError # Please triage this failure
+Language/Metadata/compilation_t10: MissingCompileTimeError # Please triage this failure
+Language/Mixins/Mixin_Application/error_t01: MissingCompileTimeError # Please triage this failure
+Language/Mixins/Mixin_Application/error_t02: MissingCompileTimeError # Please triage this failure
+Language/Mixins/Mixin_Application/wrong_mixin_type_t01: MissingCompileTimeError # Please triage this failure
+Language/Mixins/Mixin_Application/wrong_mixin_type_t02: MissingCompileTimeError # Please triage this failure
+Language/Mixins/Mixin_Application/wrong_mixin_type_t03: MissingCompileTimeError # Please triage this failure
+Language/Mixins/Mixin_Application/wrong_mixin_type_t04: MissingCompileTimeError # Please triage this failure
+Language/Mixins/Mixin_Application/wrong_type_t01: MissingCompileTimeError # Please triage this failure
+Language/Mixins/Mixin_Application/wrong_type_t02: MissingCompileTimeError # Please triage this failure
+Language/Mixins/declaring_constructor_t01: MissingCompileTimeError # Please triage this failure
+Language/Mixins/deferred_t01: MissingCompileTimeError # Please triage this failure
+Language/Mixins/not_object_superclass_t01: MissingCompileTimeError # Please triage this failure
+Language/Mixins/reference_to_super_t01: MissingCompileTimeError # Please triage this failure
+Language/Reference/Lexical_Rules/Reserved_Words/whitespace_t04: MissingCompileTimeError # Checks that other Unicode whitespaces are not allowed:  check NO-BREAK SPACE (U+00A0)
+Language/Reference/Lexical_Rules/whitespace_t06: MissingCompileTimeError # Checks that Unicode whitespaces other than WHITESPACE are not permitted in the source code. Checks symbol U+00a0.
+Language/Statements/Local_Function_Declaration/reference_before_declaration_t01: MissingCompileTimeError # Issue 21050
+Language/Statements/Local_Function_Declaration/reference_before_declaration_t03: MissingCompileTimeError # Issue 21050
+Language/Types/Interface_Types/subtype_t27: Skip # Times out or crashes. Issue 21174
+Language/Types/Interface_Types/subtype_t28: crash # Issue 21174
+Language/Types/Interface_Types/subtype_t30: fail # Issue 14654
+Language/Variables/final_t01: fail # Issue 21093
+Language/Variables/final_t02: fail # Issue 21093
+Language/Variables/local_variable_t01: MissingCompileTimeError # Issue 21050
+LayoutTests/fast/dom/css-innerHTML_t01: SkipByDesign # Test is incorrect.
+LayoutTests/fast/loader/loadInProgress_t01: Skip # Issue 23466
 LibTest/collection/LinkedList/add_A01_t01: Pass, Slow # Slow tests that needs extra time to finish.
 LibTest/collection/ListBase/ListBase_class_A01_t01: RuntimeError # Please triage this failure
 LibTest/collection/ListMixin/ListMixin_class_A01_t01: RuntimeError # Please triage this failure
@@ -198,19 +297,23 @@
 LibTest/typed_data/Uint8List/Uint8List_A02_t01: fail # co19-roll r576: Please triage this failure
 Utils/tests/Expect/identical_A01_t01: fail # co19-roll r546: Please triage this failure
 WebPlatformTest/Utils/test/testFail_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Document-createElement_t01: CompileTimeError # co19-roll r722: Please triage this failure.
 WebPlatformTest/dom/nodes/DOMImplementation-createHTMLDocument_t01: CompileTimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Document-createElement_t01: CompileTimeError # co19-roll r722: Please triage this failure.
 WebPlatformTest/dom/nodes/Element-childElementCount-nochild_t01: CompileTimeError # co19-roll r722: Please triage this failure.
 WebPlatformTest/webstorage/storage_session_setitem_quotaexceedederr_t01: Pass, Slow
-LayoutTests/fast/loader/loadInProgress_t01: Skip # Issue 23466
-LayoutTests/fast/dom/css-innerHTML_t01: SkipByDesign # Test is incorrect.
 
 [ $compiler == dart2js && $checked ]
-Language/13_Statements/09_Switch_A05_t01: Fail # Missing type check in switch expression
-Language/13_Statements/09_Switch_A09_t01: RuntimeError # Issue 16089
-Language/15_Types/1_Static_Types_A03_t01: RuntimeError # Issue 21089
-Language/15_Types/2_Dynamic_Type_System_A01_t02: RuntimeError # Issue 21088
-Language/15_Types/8_Parameterized_Types_A03_t07: RuntimeError # Issue 21088
+Language/Errors_and_Warnings/static_warning_t01: RuntimeError # Please triage this failure
+Language/Errors_and_Warnings/static_warning_t02: RuntimeError # Please triage this failure
+Language/Errors_and_Warnings/static_warning_t03: RuntimeError # Please triage this failure
+Language/Errors_and_Warnings/static_warning_t04: RuntimeError # Please triage this failure
+Language/Errors_and_Warnings/static_warning_t05: RuntimeError # Please triage this failure
+Language/Errors_and_Warnings/static_warning_t06: RuntimeError # Please triage this failure
+Language/Statements/Switch/execution_t01: Fail # Missing type check in switch expression
+Language/Statements/Switch/type_t01: RuntimeError # Issue 16089
+Language/Types/Static_Types/malformed_type_t01: RuntimeError # Issue 21089
+Language/Types/Dynamic_Type_System/malbounded_type_error_t01: RuntimeError # Issue 21088
+Language/Types/Parameterized_Types/malbounded_t06: RuntimeError # Issue 21088
 LibTest/core/Map/Map_class_A01_t04: Slow, Pass
 LibTest/core/Uri/Uri_A06_t03: Slow, Pass
 LibTest/math/Point/operator_mult_A02_t01: RuntimeError # Issue 1533
@@ -322,6 +425,9 @@
 *: Skip
 
 [ $compiler == dart2js && $browser ]
+Language/Classes/deсlarations_t01: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t34: Skip # Times out. Please triage this failure.
+LayoutTests/fast/mediastream/getusermedia_t01: Pass, RuntimeError, Timeout # Please triage this failure.
 LayoutTests/fast/css-generated-content/bug91547_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/filesystem/file-after-reload-crash_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/dom/HTMLButtonElement/change-type_t01: Skip # Test reloads itself. Issue 18558.
@@ -341,7 +447,6 @@
 LayoutTests/fast/forms/submit-form-with-dirname-attribute-with-nonhtml-ancestor_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/forms/submit-nil-value-field-assert_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/forms/textarea-submit-crash_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/innerHTML/innerHTML-svg-write_t01: Fail # Test uses foreignObject tag, which sanitizer removes. co19 issue #746
 LibTest/html/IFrameElement/appendHtml_A01_t01: Pass, RuntimeError # Issue 23462
 LibTest/html/IFrameElement/appendHtml_A01_t02: Pass, RuntimeError # Issue 23462
 #
@@ -372,16 +477,8 @@
 LayoutTests/fast/multicol/vertical-lr/break-properties_t01: RuntimeError
 LayoutTests/fast/multicol/orphans-relayout_t01: Pass, RuntimeError
 LayoutTests/fast/multicol/zeroColumnCount_t01: RuntimeError
-LayoutTests/fast/media/media-query-serialization_t01: RuntimeError
-LayoutTests/fast/media/mq-append-delete_t01: RuntimeError
-LayoutTests/fast/media/mq-color-index_t02: RuntimeError
-LayoutTests/fast/media/mq-js-media-except_t02: RuntimeError
-LayoutTests/fast/media/mq-js-media-except_t01: RuntimeError
-LayoutTests/fast/media/mq-js-media-except_t03: RuntimeError
-LayoutTests/fast/media/mq-js-update-media_t01: RuntimeError
 LayoutTests/fast/media/mq-parsing_t01: Pass, RuntimeError # False passes on Firefox, but trying to keep these grouped with the issue.
 LayoutTests/fast/mediastream/RTCPeerConnection-AddRemoveStream_t01: Skip # Passes on Safari, Issue 23475
-LayoutTests/fast/loader/local-css-allowed-in-strict-mode_t01: RuntimeError
 LayoutTests/fast/overflow/replaced-child-100percent-height-inside-fixed-container-with-overflow-auto_t01: Pass, RuntimeError # False pass on Safari
 LayoutTests/fast/lists/marker-preferred-margins_t01: RuntimeError
 LayoutTests/fast/lists/item-not-in-list-line-wrapping_t01: RuntimeError
@@ -408,16 +505,12 @@
 LayoutTests/fast/text/line-breaks-after-hyphen-before-number_t01: RuntimeError
 LayoutTests/fast/text/line-breaks-after-ideographic-comma-or-full-stop_t01: RuntimeError
 LayoutTests/fast/text/regional-indicator-symobls_t01: Pass, Fail
-LayoutTests/fast/text-autosizing/inline-width_t01: RuntimeError
-LayoutTests/fast/text-autosizing/text-removal_t01: RuntimeError
-LayoutTests/fast/text-autosizing/table-inline-width_t01: RuntimeError
 LayoutTests/fast/text/container-align-with-inlines_t01: RuntimeError
 LayoutTests/fast/text/font-fallback-synthetic-italics_t01: RuntimeError
 LayoutTests/fast/text/font-ligatures-linebreak_t01: Skip
 LayoutTests/fast/text/font-ligatures-linebreak-word_t01: Skip
 LayoutTests/fast/text/ipa-tone-letters_t01: Pass, RuntimeError
 LayoutTests/fast/text/pre-wrap-trailing-tab_t01: RuntimeError
-LayoutTests/fast/text-autosizing/display-type-change-lineHeight_t01: RuntimeError
 LayoutTests/fast/url/trivial_t01: RuntimeError
 LayoutTests/fast/url/trivial-segments_t01: RuntimeError
 LayoutTests/fast/url/scheme_t01: RuntimeError
@@ -446,39 +539,18 @@
 LayoutTests/fast/table/hittest-tablecell-bottom-edge_t01: Skip
 LayoutTests/fast/table/hittest-tablecell-with-borders-bottom-edge_t01: Skip
 LayoutTests/fast/table/table-width-exceeding-max-width_t01: Pass, RuntimeError
-LayoutTests/fast/table/table-size-integer-overflow_t01: RuntimeError
 LayoutTests/fast/table/table-sections-border-spacing_t01: RuntimeError
-LayoutTests/fast/table/switch-table-layout_t01: RuntimeError
 LayoutTests/fast/table/switch-table-layout-multiple-section_t01: RuntimeError
-LayoutTests/fast/table/switch-table-layout-dynamic-cells_t01: RuntimeError
 LayoutTests/fast/table/resize-table-row_t01: RuntimeError
-LayoutTests/fast/table/resize-table-cell_t01: RuntimeError
-LayoutTests/fast/table/resize-table-binding-cell_t01: RuntimeError
 LayoutTests/fast/table/min-max-width-preferred-size_t01: Pass, RuntimeError
 LayoutTests/fast/table/margins-flipped-text-direction_t01: Pass, RuntimeError
 LayoutTests/fast/table/html-table-width-max-width-constrained_t01: Pass, RuntimeError
 LayoutTests/fast/table/fixed-table-layout-width-change_t01: Pass, RuntimeError # False passes on Firefox
-LayoutTests/fast/table/fixed-table-with-percent-width-inside-extra-large-div_t01: RuntimeError
 LayoutTests/fast/table/absolute-table-percent-lengths_t01: RuntimeError
-LayoutTests/fast/svg/whitespace-length_t01: RuntimeError
-LayoutTests/fast/svg/whitespace-number_t01: RuntimeError
-LayoutTests/fast/svg/whitespace-length-invalid_t01: RuntimeError
-LayoutTests/fast/svg/whitespace-angle_t01: RuntimeError
-LayoutTests/fast/svg/tabindex-focus_t01: RuntimeError
-LayoutTests/fast/svg/whitespace-integer_t01: RuntimeError
-LayoutTests/fast/sub-pixel/shadows-computed-style_t01: RuntimeError
-LayoutTests/fast/sub-pixel/tiled-canvas-elements_t01: RuntimeError
-LayoutTests/fast/sub-pixel/float-list-inside_t01: RuntimeError
-LayoutTests/fast/sub-pixel/float-with-margin-in-container_t01: RuntimeError
-LayoutTests/fast/sub-pixel/float-percentage-widths_t01: RuntimeError
-LayoutTests/fast/sub-pixel/computedstylemargin_t01: RuntimeError
-LayoutTests/fast/sub-pixel/block-preferred-widths-with-sub-pixel-floats_t01: RuntimeError
-LayoutTests/fast/sub-pixel/auto-table-layout-should-avoid-text-wrapping_t01: RuntimeError
 LayoutTests/fast/sub-pixel/float-containing-block-with-margin_t01: RuntimeError
 LayoutTests/fast/sub-pixel/replaced-element-baseline_t01: Pass, RuntimeError # Fails on Safari, false pass on others
 LayoutTests/fast/selectors/style-sharing-last-child_t01: RuntimeError
 LayoutTests/fast/selectors/specificity-overflow_t01: RuntimeError
-LayoutTests/fast/scrolling/scroll-element-into-view_t01: RuntimeError
 LayoutTests/fast/ruby/parse-rp_t01: Pass, RuntimeError
 LayoutTests/fast/replaced/table-replaced-element_t01: RuntimeError
 LayoutTests/fast/replaced/table-percent-height-text-controls_t01: RuntimeError
@@ -491,7 +563,6 @@
 LayoutTests/fast/parser/stray-param_t01: RuntimeError
 LayoutTests/fast/replaced/available-height-for-content_t01: RuntimeError
 LayoutTests/fast/parser/parse-wbr_t01: Pass, RuntimeError
-LayoutTests/fast/overflow/height-during-simplified-layout_t01: RuntimeError
 LayoutTests/fast/overflow/child-100percent-height-inside-fixed-container-with-overflow-auto_t01: RuntimeError
 WebPlatformTest/html-imports/link-import-null_t01: RuntimeError
 WebPlatformTest/html/syntax/parsing/Document.getElementsByTagName-foreign_t01: RuntimeError
@@ -518,7 +589,7 @@
 #
 
 [ $compiler == dart2js && $runtime == chromeOnAndroid ]
-Language/12_Expressions/05_Strings_A06_t01: Pass, Slow # Please triage this failure.
+Language/Expressions/Strings/escape_backspace_t01: Pass, Slow # Please triage this failure.
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: Fail # Issue 22200.
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: Fail # Issue 22200.
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t06: Fail # Issue 22200.
@@ -1581,7 +1652,7 @@
 LayoutTests/fast/xpath/py-dom-xpath/abbreviations_t01: RuntimeError # Dartium JSInterop failure
 
 [ $compiler == dart2js && $runtime == ff ]
-Language/12_Expressions/28_Postfix_Expressions_A07_t02: Skip # Times out. Please triage this failure
+Language/Expressions/Postfix_Expressions/property_decrement_t02: Skip # Times out. Please triage this failure
 LayoutTests/fast/alignment/parse-align-items_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/alignment/parse-align-self_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/alignment/parse-justify-self_t01: RuntimeError # Please triage this failure
@@ -2024,7 +2095,6 @@
 LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-hash_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-host_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-hostname_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-pathname_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-port_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-protocol_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-search_t01: RuntimeError # Please triage this failure
@@ -3096,6 +3166,7 @@
 [ $compiler == dart2js && $runtime == ff && $system != windows ]
 LayoutTests/fast/canvas/canvas-resetTransform_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-setTransform_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-pathname_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xpath/4XPath/Core/test_parser_t01: RuntimeError # Dartium JSInterop failure
 LayoutTests/fast/xpath/py-dom-xpath/abbreviations_t01: RuntimeError # Dartium JSInterop failure
 
@@ -5666,7 +5737,7 @@
 LayoutTests/fast/table/hittest-tablecell-with-borders-bottom-edge_t01: RuntimeError, Pass # Issue 22752. Please triage this failure.
 
 [ $compiler == dart2js && $runtime == ie10 ]
-Language/12_Expressions/17_Getter_Invocation_A03_t02: Skip # Times out. Please triage this failure
+Language/Expressions/Top_level_Getter_Invocation/17_Getter_Invocation_A03_t02: Skip # Times out. Please triage this failure
 LayoutTests/fast/alignment/parse-align-items_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/alignment/parse-align-self_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/alignment/parse-justify-self_t01: RuntimeError # Please triage this failure
@@ -7687,13 +7758,13 @@
 WebPlatformTest/webstorage/storage_local_setitem_quotaexceedederr_t01: Skip # Times out. Please triage this failure
 
 [ $compiler == dart2js && $runtime == ie11 ]
-Language/05_Variables/05_Variables_A14_t07: Skip # Times out. Please triage this failure
-Language/06_Functions/2_Formal_Parameters_A02_t01: Skip # Times out. Please triage this failure
-Language/12_Expressions/19_Conditional_A06_t04: Skip # Times out. Please triage this failure
-Language/12_Expressions/30_Identifier_Reference_A10_t02: Skip # Times out. Please triage this failure
-Language/13_Statements/03_Variable_Declaration_A01_t18: Skip # Times out. Please triage this failure
-Language/15_Types/4_Interface_Types_A12_t07: Skip # Times out. Please triage this failure
-Language/15_Types/5_Function_Types_A01_t03: Skip # Times out. Please triage this failure
+Language/Variables/implicit_setter_void_t07: Skip # Times out. Please triage this failure
+Language/Functions/Formal_Parameters/scope_t01: Skip # Times out. Please triage this failure
+Language/Expressions/Conditional/type_t04: Skip # Times out. Please triage this failure
+Language/Expressions/Identifier_Reference/evaluation_function_t02: Skip # Times out. Please triage this failure
+Language/Statements/Local_Variable_Declaration/syntax_t18: Skip # Times out. Please triage this failure
+Language/Types/Interface_Types/subtype_t37: Skip # Times out. Please triage this failure
+Language/Types/Function_Types/subtype_no_args_t03: Skip # Times out. Please triage this failure
 LayoutTests/fast/alignment/parse-align-items_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/alignment/parse-align-self_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/alignment/parse-justify-self_t01: RuntimeError # Please triage this failure
@@ -9547,17 +9618,14 @@
 WebPlatformTest/webstorage/storage_local_setitem_quotaexceedederr_t01: Skip # Times out. Please triage this failure
 
 [ $compiler == dart2js && $cps_ir ]
-Language/12_Expressions/12_Instance_Creation/1_New_A06_t12: RuntimeError # Please triage this failure.
-Language/12_Expressions/13_Property_Extraction_A03_t01: RuntimeError # Cannot read property 'call' of undefined
-Language/12_Expressions/13_Property_Extraction_A03_t02: RuntimeError # Cannot read property 'call' of undefined
-Language/12_Expressions/13_Property_Extraction_A03_t03: RuntimeError # Cannot read property 'call' of undefined
-Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A01_t01: RuntimeError # Cannot read property 'call' of undefined
-Language/12_Expressions/30_Identifier_Reference_A09_t03: Crash # (i=0): For-loop variable captured in loop header
-Language/13_Statements/06_For_A01_t07: Crash # unsupported operation on erroneous element
-Language/13_Statements/12_Labels_A03_t04: Crash # (switch (i){L:case 0:flag=true;break;case 2:continue L;}): continue to a labeled switch case
-Language/13_Statements/14_Continue_A02_t12: Crash # (switch (2){L:case 1:flag=true;break;case 2:continue L;}): continue to a labeled switch case
-Language/13_Statements/14_Continue_A02_t13: Crash # (switch (2){case 2:continue L;L:case 1:flag=true;}): continue to a labeled switch case
-Language/15_Types/4_Interface_Types_A12_t09: RuntimeError # Please triage this failure.
+Language/Expressions/Instance_Creation/New/evaluation_t12: RuntimeError # Please triage this failure.
+Language/Expressions/Method_Invocation/Super_Invocation/syntax_t01: RuntimeError # Cannot read property 'call' of undefined
+Language/Expressions/Identifier_Reference/evaluation_variable_or_parameter_t03.dart: Crash # (i=0): For-loop variable captured in loop header
+Language/Statements/For/syntax_t07: Crash # unsupported operation on erroneous element
+Language/Statements/Labels/scope_t04: Crash # (switch (i){L:case 0:flag=true;break;case 2:continue L;}): continue to a labeled switch case
+Language/Statements/Continue/label_t12: Crash # (switch (2){L:case 1:flag=true;break;case 2:continue L;}): continue to a labeled switch case
+Language/Statements/Continue/label_t13: Crash # (switch (2){case 2:continue L;L:case 1:flag=true;}): continue to a labeled switch case
+Language/Types/Interface_Types/subtype_t39: RuntimeError # Please triage this failure.
 LibTest/async/DeferredLibrary/DeferredLibrary_A01_t01: Crash # (lazy.method()): deferred access is not implemented
 LibTest/collection/ListBase/ListBase_class_A01_t02: Pass, Timeout
 LibTest/core/Invocation/isAccessor_A01_t01: Crash # Class 'PartialMethodElement' has no instance getter 'initializer'.
diff --git a/tests/co19/co19-dartium.status b/tests/co19/co19-dartium.status
index 5136124..97e699d 100644
--- a/tests/co19/co19-dartium.status
+++ b/tests/co19/co19-dartium.status
@@ -13,6 +13,7 @@
 
 [ $compiler == none && $runtime == dartium && $system == windows ]
 LayoutTests/fast/writing-mode/vertical-inline-block-hittest_t01: Pass, RuntimeError # Issue 21605
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-002_t01: RuntimeError # Please triage this failure.
 
 [ $compiler == none && $runtime == dartium ]
 LayoutTests/fast/dom/custom/document-register-basic_t01: RuntimeError # Bad test can't register HtmlElement.
@@ -27,68 +28,791 @@
 WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t01: Pass, RuntimeError # Flaky with Dartium JsInterop. Seems like timing issues in the test.
 LibTest/html/IFrameElement/IFrameElement.created_A01_t01: RuntimeError # Issue 24568
 LibTest/html/Window/requestFileSystem_A02_t01: Skip # Issue 24585.
+LibTest/html/Window/document_A01_t01: Skip # accesses window.document from a cross-frame window
+WebPlatformTest/html/browsers/browsing-the-web/read-text/load-text-plain_t01: Skip # accesses window.document from a cross-frame window
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-002_t01: Pass, Fail # https://github.com/dart-lang/co19/issues/12
 
 [ $compiler == none && $runtime == dartium && $checked ]
 LayoutTests/fast/css/style-scoped/style-scoped-scoping-nodes-different-order_t01: RuntimeError # Dartium JSInterop failure
 
 [ $compiler == none && ($runtime == dartium || $runtime == ContentShellOnAndroid) ]
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba4444_t01: Skip # Issue 20540
+Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t01: Fail # Please triage this failure.
+Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t02: Fail # Please triage this failure.
+Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t03: Fail # Please triage this failure.
+Language/Classes/Constructors/Constant_Constructors/not_a_constant_in_superclass_t01: Fail # Please triage this failure.
+Language/Classes/Constructors/Constant_Constructors/not_a_constant_in_superclass_t02: Fail # Please triage this failure.
+Language/Classes/Constructors/Generative_Constructors/final_variables_t01: Pass, Fail #: Please triage this failure.
+Language/Classes/Getters/type_object_t01: RuntimeError # Please triage this failure.
+Language/Classes/Getters/type_object_t02: RuntimeError # Please triage this failure.
+Language/Classes/Setters/syntax_t04: RuntimeError # Please triage this failure.
+Language/Classes/Setters/type_object_t01: RuntimeError # Please triage this failure.
+Language/Classes/Setters/type_object_t02: RuntimeError # Please triage this failure.
+Language/Classes/Static_Methods/type_object_t01: RuntimeError # Please triage this failure.
+Language/Classes/Static_Methods/type_object_t02: RuntimeError # Please triage this failure.
+Language/Classes/deсlarations_t01: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t02: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t03: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t04: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t06: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t08: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t12: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t13: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t14: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t15: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t16: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t17: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t18: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t19: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t20: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t21: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t22: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t23: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t24: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t25: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t26: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t27: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t28: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t29: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t30: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t31: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t32: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t33: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t34: Skip # Times out. Please triage this failure.
+Language/Expressions/Instance_Creation/Const/abstract_class_t01: Fail # Issue 22007
+Language/Expressions/Instance_Creation/Const/abstract_class_t03: Fail # Issue 22007
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/not_class_t01: RuntimeError # Please triage this failure.
+Language/Expressions/Spawning_an_Isolate/new_isolate_t01: RuntimeError # co19-roll r667: Please triage this failure
+Language/Libraries_and_Scripts/Imports/namespace_changes_t10: RuntimeError # Please triage this failure.
+Language/Libraries_and_Scripts/Parts/compilation_t02: Skip # Please triage this failure.
+Language/Libraries_and_Scripts/Parts/syntax_t05: Skip # Times out flakily. Issue 20881
+Language/Libraries_and_Scripts/Scripts/top_level_main_t03: Pass # Issue 14478: This should break.
+Language/Libraries_and_Scripts/Scripts/top_level_main_t03: RuntimeError # co19-roll r786: Please triage this failure.
+Language/Libraries_and_Scripts/URIs/syntax_t04: RuntimeError # Please triage this failure.
+Language/Libraries_and_Scripts/URIs/syntax_t05: RuntimeError # Please triage this failure.
+Language/Libraries_and_Scripts/URIs/syntax_t09: RuntimeError # Please triage this failure.
+Language/Libraries_and_Scripts/URIs/syntax_t10: RuntimeError # Please triage this failure.
+Language/Libraries_and_Scripts/URIs/syntax_t14: RuntimeError # Please triage this failure.
+Language/Libraries_and_Scripts/URIs/syntax_t15: RuntimeError # Please triage this failure.
+Language/Metadata/before_variable_t01: RuntimeError # Please triage this failure.
+Language/Mixins/not_object_superclass_t01: Fail # Please triage this failure.
+Language/Mixins/reference_to_super_t01: Fail # Please triage this failure.
+LayoutTests/fast/alignment/parse-align-items_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/alignment/parse-align-self_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/alignment/parse-justify-self_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/backgrounds/repeat/parsing-background-repeat_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/borders/border-radius-child_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/borders/border-radius-child_t01: Skip # co19 issue 732.
+LayoutTests/fast/canvas/2d.fillText.gradient_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.gradient_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.negative_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.veryLarge_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.verySmall_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/canvas-arc-negative-radius_t01: Skip # Times out. co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/canvas-blending-text_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/canvas-empty-image-pattern_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/canvas-getImageData-invalid_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/canvas-large-dimensions_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/canvas-large-fills_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/canvas-lose-restore-googol-size_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/canvas-lose-restore-max-int-size_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/draw-custom-focus-ring_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/drawImage-with-broken-image_t01: Timeout, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/getPutImageDataPairTest_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/bad-arguments-test_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/canvas-resize-crash_t01: Skip # Causes following tests to fail. co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/canvas-test_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias-t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/context-lost_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/copy-tex-image-and-sub-image-2d_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/draw-webgl-to-canvas-2d_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/drawingbuffer-test_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/gl-object-get-calls_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/incorrect-context-object-behaviour_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/is-object_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/null-object-behaviour_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/oes-element-index-uint_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/canvas/webgl/premultiplyalpha-test_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/renderbuffer-initialization_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
 LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgb565_t01: Skip # Issue 20540
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba4444_t01: Skip # Issue 20540
 LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba5551_t01: Skip # Issue 20540
 LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video_t01: Skip # Issue 20540
-Language/12_Expressions/12_Instance_Creation/2_Const_A11_t01: Fail # Issue 22007
-Language/12_Expressions/12_Instance_Creation/2_Const_A11_t03: Fail # Issue 22007
-Language/14_Libraries_and_Scripts/3_Parts_A01_t05: Skip # Times out flakily. Issue 20881
-LayoutTests/fast/speechsynthesis/*: Skip # Times out on Dartium. Fails elsewhere. Issue 22017
-LayoutTests/fast/mediastream/RTCPeerConnection-AddRemoveStream_t01: Skip # Issue 22111
-
-LayoutTests/fast/borders/border-radius-child_t01: Skip # co19 issue 732.
-LayoutTests/fast/css-generated-content/hit-test-generated-content_t01: Skip # co19 issue 732.
-LayoutTests/fast/css/collapsed-whitespace-reattach-in-style-recalc_t01: Skip # co19 issue 732.
-LayoutTests/fast/events/document-elementFromPoint_t01: Skip # co19 issue 732.
-LayoutTests/fast/innerHTML/innerHTML-svg-write_t01: Fail # Test uses foreignObject tag, which sanitizer removes. co19 issue #746
-LayoutTests/fast/sub-pixel/float-containing-block-with-margin_t01: Skip # co19 issue 732.
-LayoutTests/fast/sub-pixel/table-rows-have-stable-height_t01: Skip # co19 issue 732.
-LayoutTests/fast/table/col-width-span-expand_t01: Skip # co19 issue 732.
-LayoutTests/fast/text-autosizing/vertical-writing-mode_t01: Skip # co19 issue 732.
-LayoutTests/fast/text/international/rtl-text-wrapping_t01: Skip # co19 issue 732.
-LayoutTests/fast/writing-mode/positionForPoint_t01: Skip # co19 issue 732.
-LayoutTests/fast/css/computed-offset-with-zoom_t01: Skip # co19 issue 732.
-LayoutTests/fast/sub-pixel/inline-block-with-padding_t01: Skip # co19 issue 732.
-LayoutTests/fast/sub-pixel/size-of-span-with-different-positions_t01: Skip # co19 issue 732.
-LayoutTests/fast/text/international/complex-text-rectangle_t01: Skip # co19 issue 732.
-LayoutTests/fast/text/line-breaks-after-hyphen-before-number_t01: Skip # co19 issue 732.
+LayoutTests/fast/canvas/webgl/triangle_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/uniform-location_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/css-generated-content/bug91547_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/filesystem/file-after-reload-crash_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/css-generated-content/hit-test-generated-content_t01: Skip # co19 issue 732.
+LayoutTests/fast/css-generated-content/malformed-url_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-generated-content/pseudo-animation-before-onload_t01: Pass, RuntimeError # Please triage this failure
+LayoutTests/fast/css-generated-content/pseudo-animation_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-generated-content/pseudo-element-events_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-generated-content/pseudo-transition-event_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-generated-content/pseudo-transition_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/auto-content-resolution-rows_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/breadth-size-resolution-grid_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/calc-resolution-grid-item_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/display-grid-set-get_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/flex-and-minmax-content-resolution-rows_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/flex-content-resolution-columns_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/flex-content-resolution-rows_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-auto-columns-rows-get-set_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-auto-flow-get-set_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-auto-flow-update_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-container-change-explicit-grid-recompute-child_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-element-border-grid-item_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-element-border-padding-grid-item_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-element-empty-row-column_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-element-min-max-height_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-element-padding-grid-item_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-element-padding-margin_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-element-shrink-to-fit_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-item-area-get-set_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-item-bad-named-area-auto-placement_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-item-bad-resolution-double-span_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-item-change-order-auto-flow_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-item-display_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows-horiz-bt_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows-vert-lr_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows-vert-rl_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-item-margin-resolution_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-item-order-auto-flow-resolution_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-template-areas-get-set_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/implicit-rows-auto-resolution_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/justify-self-cell_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/minmax-fixed-logical-height-only_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/minmax-fixed-logical-width-only_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track-in-percent-grid_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track-update_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/percent-padding-margin-resolution-grid-item-update_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/percent-padding-margin-resolution-grid-item_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/percent-resolution-grid-item_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/place-cell-by-index_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css/add-remove-stylesheets-at-once-minimal-recalc-style_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/checked-pseudo-selector_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/collapsed-whitespace-reattach-in-style-recalc_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/collapsed-whitespace-reattach-in-style-recalc_t01: Skip # co19 issue 732.
+LayoutTests/fast/css/computed-offset-with-zoom_t01: Skip # co19 issue 732.
+LayoutTests/fast/css/content/content-none_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/content/content-normal_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/counters/complex-before_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/css-properties-case-insensitive_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/css3-nth-tokens-style_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/cursor-parsing-quirks_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/deprecated-flexbox-auto-min-size_t01: Pass, RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/first-child-display-change-inverse_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/focus-display-block-inline_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/font-face-cache-bug_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/font-face-insert-link_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css/font-face-multiple-ranges-for-unicode-range_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css/font-face-unicode-range-load_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/font-face-unicode-range-overlap-load_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/fontfaceset-loadingdone_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/html-attr-case-sensitivity_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/id-or-class-before-stylesheet_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/inherit-initial-shorthand-values_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/invalid-predefined-color_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/link-alternate-stylesheet-1_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/link-alternate-stylesheet-2_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/link-alternate-stylesheet-3_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/link-alternate-stylesheet-4_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/link-alternate-stylesheet-5_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/media-query-recovery_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/parsing-at-rule-recovery_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/parsing-page-rule_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/parsing-selector-error-recovery_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/pseudo-any_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/pseudo-target-indirect-sibling-001_t01: Skip # Times out. co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/pseudo-target-indirect-sibling-002_t01: Skip # Times out. co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/readonly-pseudoclass-opera-001_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/readonly-pseudoclass-opera-002_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/readonly-pseudoclass-opera-003_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/readonly-pseudoclass-opera-004_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/readonly-pseudoclass-opera-005_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/sticky/parsing-position-sticky_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/style-element-process-crash_t01: Skip # Times out. co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/style-scoped/style-scoped-nested_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css/style-scoped/style-scoped-with-dom-operation_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css/style-scoped/style-scoped-with-important-rule_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css/stylesheet-enable-first-alternate-on-load-sheet_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/stylesheet-enable-second-alternate-link_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/webkit-keyframes-errors_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css3-text/css3-text-align-last/getComputedStyle/getComputedStyle-text-align-last-inherited_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css3-text/css3-text-align-last/getComputedStyle/getComputedStyle-text-align-last_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css3-text/css3-text-decoration/getComputedStyle/getComputedStyle-text-decoration-color_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css3-text/css3-text-decoration/getComputedStyle/getComputedStyle-text-decoration-line_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css3-text/css3-text-decoration/getComputedStyle/getComputedStyle-text-decoration-style_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css3-text/css3-text-decoration/getComputedStyle/getComputedStyle-text-underline-position_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css3-text/css3-text-indent/getComputedStyle/getComputedStyle-text-indent-inherited_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css3-text/css3-text-indent/getComputedStyle/getComputedStyle-text-indent_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css3-text/css3-text-justify/getComputedStyle/getComputedStyle-text-justify_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/dom/52776_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/DOMImplementation/createDocument-namespace-err_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/dom/Document/CaretRangeFromPoint/basic_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-strict-mode-wtih-checkbox_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-zoom-and-scroll_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/dom/Document/CaretRangeFromPoint/hittest-relative-to-viewport_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/dom/Document/CaretRangeFromPoint/replace-element_t01: Pass, RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/dom/Document/createElementNS-namespace-err_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/dom/Element/attribute-uppercase_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/dom/Element/getClientRects_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/dom/Element/setAttributeNS-namespace-err_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/dom/HTMLAnchorElement/remove-href-from-focused-anchor_t01: Skip # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-hash_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-host_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-hostname_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-pathname_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-port_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-protocol_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-search_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
 LayoutTests/fast/dom/HTMLButtonElement/change-type_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/dom/HTMLDialogElement/dialog-autofocus_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLDialogElement/dialog-scrolled-viewport_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLDialogElement/dialog-show-modal_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLDialogElement/inert-node-is-unfocusable_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLDialogElement/inert-node-is-unselectable_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLDialogElement/multiple-centered-dialogs_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLDialogElement/non-anchored-dialog-positioning_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLDialogElement/show-modal-focusing-steps_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLDocument/active-element-gets-unforcusable_t01: Skip # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLDocument/set-focus-on-valid-element_t01: Skip # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLElement/insertAdjacentHTML-errors_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/dom/HTMLElement/set-inner-outer-optimization_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLElement/spellcheck_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLFormElement/move-option-between-documents_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLImageElement/image-alt-text_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLImageElement/parse-src_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLInputElement/input-image-alt-text_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLLinkElement/link-and-subresource-test_t01: Skip # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLLinkElement/link-beforeload-recursive_t01: Skip # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLLinkElement/prefetch-onload_t01: Skip # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLLinkElement/prefetch_t01: Skip # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLLinkElement/resolve-url-on-insertion_t01: RuntimeError # co19-roll r722: Issue 18010
+LayoutTests/fast/dom/HTMLObjectElement/beforeload-set-text-crash_t01: Skip # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLOptionElement/collection-setter-getter_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLOutputElement/dom-settable-token-list_t01: RuntimeError # Issue 18931
+LayoutTests/fast/dom/HTMLScriptElement/async-false-inside-async-false-load_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLScriptElement/async-inline-script_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLScriptElement/async-onbeforeload_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLScriptElement/defer-inline-script_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLScriptElement/defer-onbeforeload_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLScriptElement/remove-in-beforeload_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLScriptElement/script-set-src_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLSelectElement/selected-index-preserved-when-option-text-changes_t01: RuntimeError # co19-roll r722: Issue 18127
+LayoutTests/fast/dom/HTMLTemplateElement/custom-element-wrapper-gc_t01: RuntimeError # co19-roll r722: Issue 18250
+LayoutTests/fast/dom/HTMLTemplateElement/innerHTML_t01: RuntimeError # co19-roll r722: Issue 18249
+LayoutTests/fast/dom/HTMLTemplateElement/ownerDocumentXHTML_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/MutationObserver/database-callback-delivery_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/dom/MutationObserver/observe-childList_t01: RuntimeError # co19-roll r722: Issue 18253
+LayoutTests/fast/dom/MutationObserver/weak-callback-gc-crash_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/Node/fragment-mutation_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/Node/initial-values_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/Range/bug-19527_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/Range/insertNode-empty-fragment-crash_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/Range/mutation_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/Range/range-constructor_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/Range/range-created-during-remove-children_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/Range/range-detached-exceptions_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/Range/range-expand_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/Range/range-insertNode-separate-endContainer_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/Range/range-insertNode-splittext_t01: RuntimeError # Please triage this failure.
 LayoutTests/fast/dom/StyleSheet/discarded-sheet-owner-null_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/dom/Window/window-resize-contents_t01: Pass, RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/Window/window-resize_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/Window/window-scroll-arguments_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/anchor-without-content_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/attribute-namespaces-get-set_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/blur-contenteditable_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/characterdata-api-arguments_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/client-width-height-quirks_t01: RuntimeError # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/css-cached-import-rule_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/dom/css-innerHTML_t01: RuntimeError # Test is incorrect.
 LayoutTests/fast/dom/cssTarget-crash_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/dom/custom/document-register-svg-extends_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/dataset-xhtml_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/dataset_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/document-importNode-arguments_t01: RuntimeError # Please triage this failure.
 LayoutTests/fast/dom/empty-hash-and-search_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/dom/focus-contenteditable_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/getElementsByClassName/011_t01: RuntimeError # Chrome 39 roll. Please triage this failure
+LayoutTests/fast/dom/horizontal-scrollbar-in-rtl-doesnt-fire-onscroll_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/horizontal-scrollbar-in-rtl_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/horizontal-scrollbar-when-dir-change_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/location-hash_t01: Pass, RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/option-properties_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/partial-layout-overlay-scrollbars_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/set-innerHTML_t01: RuntimeError # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/shadow/form-in-shadow_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/dom/shadow/no-renderers-for-light-children_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/shadow/pseudoclass-update-checked-option_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/shadow/pseudoclass-update-disabled-optgroup_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/shadow/pseudoclass-update-disabled-option_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/shadow/pseudoclass-update-enabled-optgroup_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/shadow/pseudoclass-update-enabled-option_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/shadow/shadow-content-crash_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/shadow/shadow-removechild-and-blur-event_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dynamic/crash-generated-counter_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/dynamic/crash-generated-image_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/dynamic/crash-generated-quote_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/dynamic/crash-generated-text_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/dynamic/insertAdjacentElement_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
+LayoutTests/fast/dynamic/insertAdjacentHTML_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/dynamic/recursive-layout_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/add-event-without-document_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/change-overflow-on-overflow-change_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/events/clipboard-clearData_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/clipboard-dataTransferItemList_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/div-focus_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/document-elementFromPoint_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/document-elementFromPoint_t01: Skip # co19 issue 732.
+LayoutTests/fast/events/event-creation_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/event-listener-html-non-html-confusion_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/initkeyboardevent-crash_t01: RuntimeError, Timeout # co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/input-focus-no-duplicate-events_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/invalid-003_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/invalid-004_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/label-focus_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/mutation-during-replace-child-2_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/mutation-during-replace-child_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/nested-event-remove-node-crash_t01: Skip # Flaky timeout. co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/scoped/editing-commands_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/scroll-event-does-not-bubble_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/tabindex-removal-from-focused-element_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/exclusions/parsing/parsing-wrap-flow_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/exclusions/parsing/parsing-wrap-through_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/files/blob-close-read_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/files/blob-close_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/files/xhr-response-blob_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/filesystem/async-operations_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/filesystem/directory-entry-to-uri_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/filesystem/file-after-reload-crash_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/filesystem/file-entry-to-uri_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/filesystem/file-writer-abort-continue_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/filesystem/file-writer-abort-depth_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/filesystem/file-writer-events_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/filesystem/file-writer-gc-blob_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/filesystem/file-writer-write-overlapped_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/filesystem/filesystem-reference_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/filesystem/read-directory-many_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/filesystem/simple-readonly_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/HTMLOptionElement_selected2_t01: Skip # Times out. co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/autofocus-focus-only-once_t01: Skip # Times out. co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/autofocus-input-css-style-change_t01: Skip # Times out. co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/autofocus-opera-007_t01: Skip # Times out. co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/autofocus-readonly-attribute_t01: Skip # Times out. co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/button-baseline-and-collapsing_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/button/button-disabled-blur_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/clone-input-with-dirty-value_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-change-layout-by-value_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-onblur-setvalue-onfocusremoved_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-change-layout-by-value_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/datetimelocal/datetimelocal-interactive-validation-required_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/forms/focus-style-pending_t01: Skip # Times out. co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/focus_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/form-submission-create-crash_t01.dart: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/forms/formmethod-attribute-button-html_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/formmethod-attribute-button-html_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/forms/formmethod-attribute-input-html_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/forms/formmethod-attribute-input-2_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/forms/formmethod-attribute-input-html_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/formmethod-attribute-input-html_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/forms/input-appearance-elementFromPoint_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/input-hit-test-border_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/input-width-height-attributes-without-renderer-loaded-image_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/listbox-select-all_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/listbox-selection-2_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/menulist-disabled-selected-option_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/menulist-selection-reset_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/menulist-submit-without-selection_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/missing-action_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/forms/submit-form-with-dirname-attribute_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/forms/multiple-selected-options-innerHTML_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/option-change-single-selected_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/option-strip-unicode-spaces_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/parser-associated-form-removal_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/search-popup-crasher_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/select-change-popup-to-listbox-in-event-handler_t01: Skip # Times out. co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/select-clientheight-large-size_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/select-clientheight-with-multiple-attr_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/select-list-box-mouse-focus_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/submit-form-with-dirname-attribute-with-ancestor-dir-attribute_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/forms/submit-form-with-dirname-attribute-with-nonhtml-ancestor_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/forms/submit-form-with-dirname-attribute_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/forms/submit-nil-value-field-assert_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/submit-nil-value-field-assert_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/forms/textarea-scrollbar-height_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/textarea-submit-crash_t01: Skip # Test reloads itself. Issue 18558.
-
+LayoutTests/fast/forms/textfield-focus-out_t01: Skip # Times out. co19-roll r801: Please triage this failure.
+LayoutTests/fast/html/adjacent-html-context-element_t01:RuntimeError # co19 issue 11.
+LayoutTests/fast/html/hidden-attr_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/html/imports/import-element-removed-flag_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/html/imports/import-element-removed-flag_t01: Skip # co19-roll r722: Please triage this failure.
+LayoutTests/fast/html/imports/import-events_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/html/select-dropdown-consistent-background-color_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/inline/boundingBox-with-continuation_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/inline/empty-inline-before-collapsed-space_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/inline/fixed-pos-moves-with-abspos-inline-parent_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/inline/fixed-pos-moves-with-abspos-parent-relative-ancestor_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/inline/fixed-pos-moves-with-abspos-parent_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/inline/fixed-pos-with-transform-container-moves-with-abspos-parent_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/inline/inline-position-top-align_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/inline/inline-relative-offset-boundingbox_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/inline/inline-with-empty-inline-children_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/inline/out-of-flow-objects-and-whitespace-after-empty-inline_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/inline/parent-inline-element-padding-contributes-width_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/inline/positioned-element-padding-contributes-width_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/inline/reattach-inlines-in-anonymous-blocks-with-out-of-flow-siblings_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/innerHTML/innerHTML-special-elements_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/layers/normal-flow-hit-test_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/layers/normal-flow-hit-test_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/layers/zindex-hit-test_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/layers/zindex-hit-test_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/lists/item-not-in-list-line-wrapping_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/lists/list-style-position-inside_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/lists/marker-preferred-margins_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/loader/about-blank-hash-change_t01: Skip # Times out. co19-roll r801: Please triage this failure.
+LayoutTests/fast/loader/about-blank-hash-kept_t01: Skip # Times out. co19-roll r801: Please triage this failure.
+LayoutTests/fast/loader/hashchange-event-properties_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/loader/loadInProgress_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/loader/onhashchange-attribute-listeners_t01: Skip # Times out. co19-roll r801: Please triage this failure.
+LayoutTests/fast/loader/scroll-position-restored-on-back_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/loader/scroll-position-restored-on-reload-at-load-event_t01: Skip # Times out. co19-roll r801: Please triage this failure.
+LayoutTests/fast/loader/stateobjects/replacestate-in-onunload_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/masking/parsing-clip-path-shape_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/masking/parsing-mask-source-type_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/masking/parsing-mask_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/media/media-query-list-syntax_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/media/mq-parsing_t01: Pass, RuntimeError # False passes on Firefox, but trying to keep these grouped with the issue. # co19 issue 11.
+LayoutTests/fast/mediastream/RTCPeerConnection-AddRemoveStream_t01: Skip # Issue 22111
+LayoutTests/fast/mediastream/RTCPeerConnection-AddRemoveStream_t01: Skip # Passes on Safari, Issue 23475 # co19 issue 11.
 LayoutTests/fast/mediastream/getusermedia_t01: Skip # co19 issue 738
-
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A09_t01: Pass, Fail #: Please triage this failure.
-Language/14_Libraries_and_Scripts/3_Parts_A02_t02: Skip # Please triage this failure.
-Language/14_Libraries_and_Scripts/4_Scripts_A03_t03: Pass # Issue 14478: This should break.
+LayoutTests/fast/multicol/balance-short-trailing-empty-block_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/balance-trailing-border_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/balance-trailing-border_t02: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/balance-unbreakable_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/break-after-always-bottom-margin_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/break-properties_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/column-width-zero_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/cssom-view_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/fixed-column-percent-logical-height-orthogonal-writing-mode_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/flipped-blocks-hit-test_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/float-truncation_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/hit-test-above-or-below_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/hit-test-end-of-column-with-line-height_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/hit-test-end-of-column_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/hit-test-float_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/hit-test-gap-between-pages-flipped_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/hit-test-gap-between-pages_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/image-inside-nested-blocks-with-border_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/inherit-column-values_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/inline-getclientrects_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/newmulticol/balance-images_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/newmulticol/balance-maxheight_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/newmulticol/balance-maxheight_t02: RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/newmulticol/balance_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/newmulticol/balance_t02: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/newmulticol/balance_t04: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/newmulticol/balance_t04: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/newmulticol/balance_t05: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/newmulticol/balance_t06: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/newmulticol/balance_t07: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/newmulticol/balance_t07: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/newmulticol/balance_t08: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/newmulticol/balance_t08: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/newmulticol/balance_t09: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/newmulticol/balance_t09: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/newmulticol/balance_t10: Pass, RuntimeError # I don't understand how, but sometimes passes. # co19 issue 11.
+LayoutTests/fast/multicol/newmulticol/balance_t10: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/orphans-relayout_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/vertical-lr/break-properties_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/vertical-lr/float-truncation_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/vertical-rl/break-properties_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/vertical-rl/float-truncation_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/vertical-rl/image-inside-nested-blocks-with-border_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/widows_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/widows_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/widows_t02: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/zeroColumnCount_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/overflow/child-100percent-height-inside-fixed-container-with-overflow-auto_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/overflow/child-100percent-height-inside-fixed-container-with-overflow-auto_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/overflow/overflow-rtl-vertical-origin_t01: Pass, RuntimeError # False passes on Firefox, but trying to keep these grouped with the issue. # co19 issue 11.
+LayoutTests/fast/overflow/replaced-child-100percent-height-inside-fixed-container-with-overflow-auto_t01: Pass, RuntimeError # False pass on Safari # co19 issue 11.
+LayoutTests/fast/overflow/replaced-child-100percent-height-inside-fixed-container-with-overflow-auto_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/overflow/scroll-vertical-not-horizontal_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/overflow/scrollbar-restored_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/parser/foster-parent-adopted_t02: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/parser/fragment-parser-doctype_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/parser/innerhtml-with-prefixed-elements_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/parser/parse-wbr_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/parser/pre-first-line-break_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/parser/stray-param_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/replaced/available-height-for-content_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor_t01: Pass # False pass # co19 issue 11.
+LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr_t01: RuntimeError, Pass # Spurious intermittent pass # co19 issue 11.
+LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor_t01: RuntimeError, Pass # Spurious intermittent pass # co19 issue 11.
+LayoutTests/fast/replaced/container-width-zero_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-anonymous-table-cell_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-anonymous-table-cell_t01: RuntimeError, Pass # Spurious intermittent pass. # co19 issue 11.
+LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-table-cell-ignore-height_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-table-cell-ignore-height_t01: RuntimeError, Pass # Spurious intermittent pass # co19 issue 11.
+LayoutTests/fast/replaced/preferred-widths_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/replaced/table-percent-height-text-controls_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/replaced/table-percent-height_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/replaced/table-percent-width_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/replaced/table-replaced-element_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/ruby/parse-rp_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/ruby/ruby-line-height_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/selectors/specificity-overflow_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/selectors/style-sharing-last-child_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/shapes/parsing/parsing-shape-lengths_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/shapes/shape-outside-floats/shape-outside-big-box-border-radius_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-diamond-margin-polygon_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-margin-left_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-margin-right_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-image-margin_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-image-margin_t02: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-inset-rounded-different-writing-modes-left_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-inset-rounded-different-writing-modes-right_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/shapes/shape-outside-floats/shape-outside-rounded-boxes_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/shapes/shape-outside-floats/shape-outside-rounded-boxes_t02: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/speechsynthesis/*: Skip # Times out on Dartium. Fails elsewhere. Issue 22017
+LayoutTests/fast/storage/disallowed-storage_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/storage/storage-disallowed-in-data-url_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/sub-pixel/cssom-subpixel-precision_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/sub-pixel/float-containing-block-with-margin_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/sub-pixel/float-containing-block-with-margin_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/sub-pixel/float-containing-block-with-margin_t01: Skip # co19 issue 732.
+LayoutTests/fast/sub-pixel/inline-block-with-padding_t01: Skip # co19 issue 732.
+LayoutTests/fast/sub-pixel/replaced-element-baseline_t01: Pass, RuntimeError # Fails on Safari, false pass on others # co19 issue 11.
+LayoutTests/fast/sub-pixel/replaced-element-baseline_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/sub-pixel/size-of-span-with-different-positions_t01: Skip # co19 issue 732.
+LayoutTests/fast/sub-pixel/table-rows-have-stable-height_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/sub-pixel/table-rows-have-stable-height_t01: Skip # co19 issue 732.
+LayoutTests/fast/table/absolute-table-percent-lengths_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/table/anonymous-table-section-removed_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/anonymous-table-section-removed_t01: Skip # co19 issue 11.
+LayoutTests/fast/table/caption-orthogonal-writing-mode-sizing_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/col-width-span-expand_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/col-width-span-expand_t01: Skip # co19 issue 11.
+LayoutTests/fast/table/col-width-span-expand_t01: Skip # co19 issue 732.
+LayoutTests/fast/table/computeLogicalWidth-table-needsSectionRecalc_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/css-table-max-height_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/css-table-max-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/css-table-width-with-border-padding_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/fixed-table-layout-width-change_t01: Pass, RuntimeError # False passes on Firefox # co19 issue 11.
+LayoutTests/fast/table/hittest-tablecell-bottom-edge_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/hittest-tablecell-bottom-edge_t01: Skip # co19 issue 11.
+LayoutTests/fast/table/hittest-tablecell-right-edge_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/hittest-tablecell-with-borders-bottom-edge_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/hittest-tablecell-with-borders-right-edge_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/html-table-width-max-width-constrained_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/table/large-shrink-wrapped-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/margins-flipped-text-direction_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/table/margins-perpendicular-containing-block_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/min-max-width-preferred-size_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/table/min-width-css-block-table_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/min-width-css-inline-table_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/min-width-html-block-table_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/min-width-html-inline-table_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/nested-tables-with-div-offset_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/table/padding-height-and-override-height_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/resize-table-row_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/table/switch-table-layout-multiple-section_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/table/table-all-rowspans-height-distribution-in-rows-except-overlapped_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/table-all-rowspans-height-distribution-in-rows_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/table-cell-offset-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/table-colgroup-present-after-table-row_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/table-rowspan-cell-with-empty-cell_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/table-rowspan-height-distribution-in-rows_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/table-rowspan-height-distribution-in-rows_t02: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/table-sections-border-spacing_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/table/table-width-exceeding-max-width_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/table/table-with-content-width-exceeding-max-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text-autosizing/vertical-writing-mode_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text-autosizing/vertical-writing-mode_t01: Skip # co19 issue 732.
+LayoutTests/fast/text/container-align-with-inlines_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/text/container-align-with-inlines_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/text/find-soft-hyphen_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/find-spaces_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/font-fallback-synthetic-italics_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/text/font-fallback-synthetic-italics_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/text/font-ligatures-linebreak-word_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/font-ligatures-linebreak-word_t01: Skip # co19 issue 11.
+LayoutTests/fast/text/font-ligatures-linebreak-word_t01: Skip # co19 issue 11.
+LayoutTests/fast/text/font-ligatures-linebreak_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/glyph-reordering_t01: Pass, RuntimeError # This is a false pass. The font gets sanitized, so whether it works or not probably depends on default sizes. # co19 issue 11.
+LayoutTests/fast/text/international/cjk-segmentation_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/international/complex-text-rectangle_t01: Skip # co19 issue 732.
+LayoutTests/fast/text/international/iso-8859-8_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/international/listbox-width-rtl_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/text/international/rtl-text-wrapping_t01: Pass # This is a false pass. All the content gets sanitized, so there's nothing to assert fail on. If the code did anything it would fail. # co19 issue 11.
+LayoutTests/fast/text/international/rtl-text-wrapping_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/international/rtl-text-wrapping_t01: Skip # co19 issue 732.
+LayoutTests/fast/text/international/thai-offsetForPosition-inside-character_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/ipa-tone-letters_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/text/ipa-tone-letters_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/line-break-after-empty-inline-hebrew_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/text/line-break-after-inline-latin1_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/text/line-break-after-question-mark_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/line-breaks-after-closing-punctuations_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/text/line-breaks-after-hyphen-before-number_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/text/line-breaks-after-hyphen-before-number_t01: Skip # co19 issue 732.
+LayoutTests/fast/text/line-breaks-after-ideographic-comma-or-full-stop_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/text/offsetForPosition-cluster-at-zero_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/pre-wrap-trailing-tab_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/text/regional-indicator-symobls_t01: Pass, Fail # co19 issue 11.
+LayoutTests/fast/text/regional-indicator-symobls_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/remove-zero-length-run_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/sub-pixel/text-scaling-ltr_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/sub-pixel/text-scaling-pixel_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/sub-pixel/text-scaling-rtl_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/sub-pixel/text-scaling-vertical_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/sub-pixel/text-scaling-webfont_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/text-combine-shrink-to-fit_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/transforms/bounding-rect-zoom_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/transforms/bounding-rect-zoom_t01: RuntimeError, Pass # Erratic, but only passes because divs have been entirely removed. # co19 issue 11.
+LayoutTests/fast/transforms/hit-test-large-scale_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/transforms/scrollIntoView-transformed_t01: Pass, RuntimeError # False passes on Firefox. # co19 issue 11.
+LayoutTests/fast/transforms/topmost-becomes-bottomost-for-scrolling_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/transforms/transform-hit-test-flipped_t01: Pass, RuntimeError # Passes on Firefox, but is clearly not testing what it's trying to test. # co19 issue 11.
+LayoutTests/fast/transforms/transform-inside-overflow-scroll_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/url/anchor_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/url/file-http-base_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/file_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/host-lowercase-per-scheme_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/url/host_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/idna2003_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/idna2008_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/invalid-urls-utf8_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/ipv4_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/ipv6_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/mailto_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/url/path-url_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/url/path_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/port_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/url/query_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/relative-unix_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/relative-win_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/relative_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/safari-extension_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/url/safari-extension_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/url/scheme_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/url/segments-from-data-url_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/segments_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/standard-url_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/trivial-segments_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/url/trivial_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/writing-mode/auto-margins-across-boundaries_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/writing-mode/auto-sizing-orthogonal-flows_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/writing-mode/block-formatting-context_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/writing-mode/display-mutation_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/writing-mode/percentage-margins-absolute-replaced_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/writing-mode/percentage-padding_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/writing-mode/positionForPoint_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/writing-mode/positionForPoint_t01: Skip # co19 issue 732.
+LayoutTests/fast/writing-mode/relative-positioning-percentages_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/writing-mode/table-hit-test_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/writing-mode/vertical-font-vmtx-units-per-em_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-abort_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
+LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-arraybuffer_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
+LayoutTests/fast/xpath/4XPath/Borrowed/cz_20030217_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xpath/4XPath/Borrowed/namespace-nodes_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xpath/4XPath/Core/test_core_functions_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xpath/4XPath/Core/test_core_functions_t02: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/xpath/4XPath/Core/test_node_test_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xpath/4XPath/Core/test_node_test_t02: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/xpath/ambiguous-operators_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xpath/attr-namespace_t02: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/xpath/ensure-null-namespace_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xpath/implicit-node-args_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xpath/invalid-resolver_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xpath/node-name-case-sensitivity_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xpath/node-name-case-sensitivity_t02: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/xpath/position_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xpath/py-dom-xpath/data_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/xpath/py-dom-xpath/expressions_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/xpath/py-dom-xpath/paths_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/xpath/reverse-axes_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xsl/default-html_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LibTest/async/Completer/completeError_A02_t01: Pass, Fail # Please triage this failure.
+LibTest/async/Stream/Stream.periodic_A01_t01: Pass, RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/async/Timer/Timer_A01_t01: RuntimeError, Pass # Issue 16475
+LibTest/collection/ListBase/ListBase_class_A01_t01: Skip # co19-roll r722: Please triage this failure.
+LibTest/collection/ListMixin/ListMixin_class_A01_t01: Skip # co19-roll r722: Please triage this failure.
+LibTest/collection/ListMixin/ListMixin_class_A01_t02: Skip # co19-roll r722: Please triage this failure.
 LibTest/core/int/operator_left_shift_A01_t02: Pass, Fail # Please triage this failure.
-LibTest/isolate/SendPort/send_A02_t01: Fail # Issue 13921
-LibTest/isolate/SendPort/send_A02_t04: Fail # Issue 13921
-LibTest/isolate/SendPort/send_A02_t05: Fail # Issue 13921
-LibTest/isolate/SendPort/send_A02_t06: Fail # Issue 13921
+LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t03: RuntimeError # co19-roll r722: Please triage this failure.
+LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t06: RuntimeError # co19-roll r722: Please triage this failure.
+LibTest/html/Document/childNodes_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Document/clone_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Document/clone_A01_t02: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Document/securityPolicy_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Element/blur_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/Element/borderEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
+LibTest/html/Element/contentEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
+LibTest/html/Element/dataset_A02_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Element/focus_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/Element/getAttributeNS_A01_t01: RuntimeError # co19-roll r706.  Issue 16395
+LibTest/html/Element/getAttributeNS_A01_t02: RuntimeError # Please triage this failure.
+LibTest/html/Element/getClientRects_A01_t02: RuntimeError # co19-roll r706.  Issue 16575
+LibTest/html/Element/getNamespacedAttributes_A01_t01: RuntimeError # co19-roll r706.  Issue 16395
+LibTest/html/Element/isContentEditable_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Element/isContentEditable_A02_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Element/marginEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
+LibTest/html/Element/paddingEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
+LibTest/html/Element/querySelectorAll_A01_t02: RuntimeError # co19-roll r761: Please triage this failure.
+LibTest/html/Element/replaceWith_A01_t02: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/HttpRequest/onError_A01_t02: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/HttpRequest/responseText_A01_t02: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/HttpRequest/responseType_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/HttpRequest/responseType_A01_t03: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/HttpRequest/statusText_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/HttpRequestUpload/onError_A01_t02: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/HttpRequestUpload/onLoadEnd_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/HttpRequestUpload/onLoadStart_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/HttpRequestUpload/onLoad_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/appendHtml_A01_t01: Pass, RuntimeError # Issue 23462
+LibTest/html/IFrameElement/appendHtml_A01_t01: RuntimeError # Issue 23462
+LibTest/html/IFrameElement/appendHtml_A01_t02: Pass, RuntimeError # Issue 23462
+LibTest/html/IFrameElement/appendHtml_A01_t02: RuntimeError # Issue 23462
+LibTest/html/IFrameElement/attributeChanged_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/attributes_setter_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/blur_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/borderEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
+LibTest/html/IFrameElement/clone_A01_t02: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/createFragment_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/createFragment_A01_t02: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/createFragment_A01_t03: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/createShadowRoot_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/enteredView_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/focus_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/getClientRects_A01_t02: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/getNamespacedAttributes_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/innerHtml_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/isContentEditable_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/leftView_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/marginEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
+LibTest/html/IFrameElement/offsetTo_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/outerHtml_setter_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LibTest/html/IFrameElement/paddingEdge_A01_t01: RuntimeError # co19-roll r722: Issue 16574
+LibTest/html/IFrameElement/querySelector_A01_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LibTest/html/IFrameElement/setInnerHtml_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Node/addEventListener_A01_t06: RuntimeError # co19-roll r722: Please triage this failure.
+LibTest/html/Node/append_A01_t02: RuntimeError # co19-roll r722: Please triage this failure.
+LibTest/html/Node/nodes_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LibTest/html/Node/nodes_A01_t02: RuntimeError # co19-roll r722: Please triage this failure.
+LibTest/html/Node/parent_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LibTest/html/Node/previousNode_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LibTest/html/Window/close_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Window/find_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Window/find_A03_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Window/find_A06_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Window/moveTo_A01_t01: RuntimeError, Pass # co19-roll r706.  Please triage this failure.
+LibTest/html/Window/moveTo_A02_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Window/postMessage_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Window/requestFileSystem_A01_t02: RuntimeError,Pass # co19-roll r722: Please triage this failure.
+LibTest/html/Window/resizeBy_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Window/resizeTo_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
 LibTest/isolate/Isolate/spawnUri_A01_t01: RuntimeError # Dart issue 15974
 LibTest/isolate/Isolate/spawnUri_A01_t02: Skip # Dart issue 15974
 LibTest/isolate/Isolate/spawnUri_A01_t03: Skip # Dart issue 15974
@@ -96,13 +820,16 @@
 LibTest/isolate/Isolate/spawnUri_A01_t05: RuntimeError # Dart issue 15974
 LibTest/isolate/Isolate/spawnUri_A02_t01: RuntimeError # Dart issue 15974
 LibTest/isolate/Isolate/spawnUri_A02_t04: Skip # Dart issue 15974
-
+LibTest/isolate/Isolate/spawn_A01_t01: RuntimeError # co19-roll r667: Please triage this failure
+LibTest/isolate/Isolate/spawn_A01_t02: RuntimeError # co19-roll r667: Please triage this failure
+LibTest/isolate/Isolate/spawn_A01_t03: RuntimeError # co19-roll r667: Please triage this failure
+LibTest/isolate/Isolate/spawn_A01_t04: RuntimeError # co19-roll r667: Please triage this failure
+LibTest/isolate/Isolate/spawn_A01_t05: RuntimeError # co19-roll r667: Please triage this failure
 LibTest/isolate/RawReceivePort/RawReceivePort_A01_t01: RuntimeError # Issue 13921
 LibTest/isolate/RawReceivePort/RawReceivePort_A01_t02: RuntimeError # Issue 13921
 LibTest/isolate/RawReceivePort/close_A01_t01: RuntimeError # Issue 13921
 LibTest/isolate/RawReceivePort/handler_A01_t01: RuntimeError # Issue 13921
 LibTest/isolate/RawReceivePort/sendPort_A01_t01: RuntimeError # Issue 13921
-
 LibTest/isolate/ReceivePort/any_A01_t01: RuntimeError # Issue 13921
 LibTest/isolate/ReceivePort/any_A01_t02: RuntimeError # Issue 13921
 LibTest/isolate/ReceivePort/asBroadcastStream_A01_t01: RuntimeError # Issue 13921
@@ -167,140 +894,163 @@
 LibTest/isolate/ReceivePort/transform_A01_t02: RuntimeError # Issue 13921
 LibTest/isolate/ReceivePort/where_A01_t01: RuntimeError # Issue 13921
 LibTest/isolate/ReceivePort/where_A01_t02: RuntimeError # Issue 13921
-LibTest/html/Element/blur_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/blur_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/Element/focus_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/focus_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/enteredView_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/leftView_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/HttpRequest/onError_A01_t02: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/HttpRequest/responseText_A01_t02: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/HttpRequestUpload/onError_A01_t02: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/HttpRequestUpload/onLoadEnd_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/HttpRequestUpload/onLoadStart_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/HttpRequestUpload/onLoad_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-WebPlatformTest/dom/events/event_constants/constants_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-WebPlatformTest/dom/events/event_constructors/Event_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-WebPlatformTest/dom/events/event_constructors/Event_A02_t01: Skip # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/dom/DOMImplementation/createDocument-namespace-err_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/dom/Document/CaretRangeFromPoint/basic_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-zoom-and-scroll_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/dom/Document/CaretRangeFromPoint/hittest-relative-to-viewport_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/dom/Document/CaretRangeFromPoint/replace-element_t01: Pass, RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/dom/Document/createElementNS-namespace-err_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/dom/Element/attribute-uppercase_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/dom/Element/getClientRects_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/dom/Element/setAttributeNS-namespace-err_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/html/hidden-attr_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/html/imports/import-element-removed-flag_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/html/imports/import-events_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/async/Stream/Stream.periodic_A01_t01: Pass, RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Document/childNodes_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Document/clone_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Document/clone_A01_t02: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Document/securityPolicy_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Element/borderEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
-LibTest/html/Element/contentEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
-LibTest/html/Element/dataset_A02_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Element/getAttributeNS_A01_t01: RuntimeError # co19-roll r706.  Issue 16395
-LibTest/html/Element/getAttributeNS_A01_t02: RuntimeError # Please triage this failure.
-LibTest/html/Element/getClientRects_A01_t02: RuntimeError # co19-roll r706.  Issue 16575
-LibTest/html/Element/getNamespacedAttributes_A01_t01: RuntimeError # co19-roll r706.  Issue 16395
-LibTest/html/Element/isContentEditable_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Element/isContentEditable_A02_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Element/marginEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
-LibTest/html/Element/paddingEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
-LibTest/html/Element/replaceWith_A01_t02: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/HttpRequest/responseType_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/HttpRequest/responseType_A01_t03: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/HttpRequest/statusText_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/appendHtml_A01_t01: RuntimeError # Issue 23462
-LibTest/html/IFrameElement/appendHtml_A01_t02: RuntimeError # Issue 23462
-LibTest/html/IFrameElement/attributeChanged_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/attributes_setter_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/borderEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
-LibTest/html/IFrameElement/clone_A01_t02: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/createFragment_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/createFragment_A01_t02: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/createFragment_A01_t03: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/createShadowRoot_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/getClientRects_A01_t02: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/getNamespacedAttributes_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/innerHtml_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/isContentEditable_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/marginEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
-LibTest/html/IFrameElement/offsetTo_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/setInnerHtml_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Window/close_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Window/find_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Window/find_A03_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Window/find_A06_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Window/moveTo_A01_t01: RuntimeError, Pass # co19-roll r706.  Please triage this failure.
-LibTest/html/Window/moveTo_A02_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Window/postMessage_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Window/resizeBy_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Window/resizeTo_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
 LibTest/isolate/SendPort/send_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
 LibTest/isolate/SendPort/send_A01_t02: RuntimeError # co19-roll r706.  Please triage this failure.
 LibTest/isolate/SendPort/send_A01_t03: RuntimeError # co19-roll r706.  Please triage this failure.
 LibTest/isolate/SendPort/send_A01_t04: RuntimeError # co19-roll r706.  Please triage this failure.
-Language/12_Expressions/13_Spawning_an_Isolate_A01_t01: RuntimeError # co19-roll r667: Please triage this failure
-LibTest/isolate/Isolate/spawn_A01_t01: RuntimeError # co19-roll r667: Please triage this failure
-LibTest/isolate/Isolate/spawn_A01_t02: RuntimeError # co19-roll r667: Please triage this failure
-LibTest/isolate/Isolate/spawn_A01_t03: RuntimeError # co19-roll r667: Please triage this failure
-LibTest/isolate/Isolate/spawn_A01_t04: RuntimeError # co19-roll r667: Please triage this failure
-LibTest/isolate/Isolate/spawn_A01_t05: RuntimeError # co19-roll r667: Please triage this failure
-LibTest/async/Timer/Timer_A01_t01: RuntimeError, Pass # Issue 16475
-LayoutTests/fast/dom/HTMLAnchorElement/remove-href-from-focused-anchor_t01: Skip # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-hash_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-host_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-hostname_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-pathname_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-port_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-protocol_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-search_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/dialog-autofocus_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/dialog-scrolled-viewport_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/dialog-show-modal_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/inert-node-is-unfocusable_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/inert-node-is-unselectable_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/multiple-centered-dialogs_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/non-anchored-dialog-positioning_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLOutputElement/dom-settable-token-list_t01: RuntimeError # Issue 18931
-LayoutTests/fast/dom/HTMLDialogElement/show-modal-focusing-steps_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLElement/set-inner-outer-optimization_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLElement/spellcheck_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLFormElement/move-option-between-documents_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLImageElement/image-alt-text_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLImageElement/parse-src_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLInputElement/input-image-alt-text_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLLinkElement/link-and-subresource-test_t01: Skip # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLLinkElement/link-beforeload-recursive_t01: Skip # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLLinkElement/prefetch-onload_t01: Skip # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLLinkElement/prefetch_t01: Skip # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLLinkElement/resolve-url-on-insertion_t01: RuntimeError # co19-roll r722: Issue 18010
-LayoutTests/fast/dom/HTMLObjectElement/beforeload-set-text-crash_t01: Skip # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLScriptElement/script-set-src_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
-LibTest/html/IFrameElement/outerHtml_setter_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LibTest/html/IFrameElement/paddingEdge_A01_t01: RuntimeError # co19-roll r722: Issue 16574
-LibTest/html/Node/addEventListener_A01_t06: RuntimeError # co19-roll r722: Please triage this failure.
-LibTest/html/Node/append_A01_t02: RuntimeError # co19-roll r722: Please triage this failure.
-LibTest/html/Node/nodes_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LibTest/html/Node/nodes_A01_t02: RuntimeError # co19-roll r722: Please triage this failure.
-LibTest/html/Node/parent_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LibTest/html/Node/previousNode_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LibTest/isolate/SendPort/send_A02_t01: Fail # Issue 13921
+LibTest/isolate/SendPort/send_A02_t04: Fail # Issue 13921
+LibTest/isolate/SendPort/send_A02_t05: Fail # Issue 13921
+LibTest/isolate/SendPort/send_A02_t06: Fail # Issue 13921
+WebPlatformTest/DOMEvents/approved/EventObject.after.dispatchEvenr_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/DOMEvents/approved/EventObject.multiple.dispatchEvent_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/DOMEvents/approved/ProcessingInstruction.DOMCharacterDataModified_t01: Skip # Times out. co19-roll r738: Please triage this failure.
+WebPlatformTest/DOMEvents/approved/addEventListener.optional.useCapture_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/Utils/test/asyncTestFail_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/Utils/test/asyncTestFail_t02: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/Utils/test/asyncTestTimeout_t01: Skip # co19-roll r722: Please triage this failure.
+WebPlatformTest/Utils/test/testFail_t01: RuntimeError # co19-roll r722: Please triage this failure.
 WebPlatformTest/custom-elements/concepts/type_A03_t01: RuntimeError # Please triage this failure.
 WebPlatformTest/custom-elements/concepts/type_A05_t01: RuntimeError # co19-roll r722: Please triage this failure.
 WebPlatformTest/custom-elements/concepts/type_A06_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/EventTarget/dispatchEvent_A02_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/EventTarget/dispatchEvent_A03_t01: Skip # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/Node-replaceChild_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/dom/events/event_constants/constants_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+WebPlatformTest/dom/events/event_constructors/Event_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+WebPlatformTest/dom/events/event_constructors/Event_A02_t01: Skip # co19-roll r706.  Please triage this failure.
+WebPlatformTest/dom/events/type_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/DOMImplementation-createDocumentType_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/DOMImplementation-createDocument_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/DOMImplementation-createHTMLDocument_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Document-adoptNode_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Document-createElementNS_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Document-createElement_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Document-getElementsByTagName_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Element-childElementCount-nochild_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Element-childElementCount_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Node-appendChild_t02: RuntimeError, Pass # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Node-insertBefore_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Node-isEqualNode_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Node-nodeName_t01: RuntimeError # Please triage this failure.
+WebPlatformTest/dom/nodes/Node-replaceChild_t01: RuntimeError # co19-roll r722: Please triage this failure
+WebPlatformTest/dom/nodes/Node-textContent_t01: RuntimeError # Please triage this failure.
+WebPlatformTest/dom/nodes/attributes/setAttributeNS_A05_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/attributes/setAttributeNS_A06_t03: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/attributes/setAttributeNS_A07_t02: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/attributes/setAttributeNS_A07_t03: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/attributes/setAttributeNS_A08_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/attributes/setAttribute_A03_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/html-imports/link-import-null_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html-imports/link-import_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html-imports/link-import_t02: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html-imports/loading-import_t01: RuntimeError # co19-roll r761: Please triage this failure.
 WebPlatformTest/html-templates/innerhtml-on-templates/innerhtml_t01: RuntimeError # co19-roll r722: Please triage this failure.
 WebPlatformTest/html-templates/parsing-html-templates/additions-to-the-in-head-insertion-mode/generating-of-implied-end-tags_t01: RuntimeError # co19-roll r722: Please triage this failure.
 WebPlatformTest/html-templates/parsing-html-templates/creating-an-element-for-the-token/template-owner-document_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/html/browsers/browsing-the-web/read-media/pageload-image_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/browsers/browsing-the-web/read-media/pageload-video_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/document.body-getter_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/document.body-setter_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/document.getElementsByName-case_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/document.getElementsByName-namespace_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/document.getElementsByName-newelements_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/document.getElementsByName-param_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/document.title_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/document.title_t05: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/document.title_t07: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/nameditem_t02: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/nameditem_t03: RuntimeError # co19 issue 11.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/nameditem_t05: RuntimeError # co19 issue 11.
+WebPlatformTest/html/dom/elements/global-attributes/dataset-delete_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/dom/elements/global-attributes/dataset-get_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/dom/elements/global-attributes/dataset-set_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/disabled-elements/disabledElement_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/semantics/document-metadata/styling/LinkStyle_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/semantics/document-metadata/styling/LinkStyle_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/embedded-content/media-elements/error-codes/error_t01: Skip # Times out and fails. # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLMediaElement/addTextTrack_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/src_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/cues_t01: Skip # Times out and fails. # co19-roll r738: Please triage this failure.LayoutTests/fast/dom/Window/window-resize-contents_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/mode_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/forms/attributes-common-to-form-controls/formAction_document_address_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/forms/attributes-common-to-form-controls/formaction_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/forms/textfieldselection/textfieldselection-setRangeText_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/forms/textfieldselection/textfieldselection-setSelectionRange_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.  Pass on macos.
+WebPlatformTest/html/semantics/forms/the-button-element/button-validation_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-fieldset-element/disabled_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-form-element/form-autocomplete_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-form-element/form-elements-matches_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-form-element/form-elements-nameditem_t02: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-form-element/form-nameditem_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/semantics/forms/the-input-element/date_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/datetime-local_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/datetime_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/datetime_t02: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/email_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/email_t02: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/input-textselection_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/month_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/password_t01: RuntimeError # co19-roll r786: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/pattern_attribute_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/semantics/forms/the-input-element/range_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/time_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/time_t02: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/type-change-state_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/url_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/valueMode_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/week_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-meter-element/meter_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-option-element/option-text-recurse_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-option-element/option-text-spaces_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/grouping-content/the-blockquote-element/grouping-blockquote_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/grouping-content/the-ol-element/ol.start-reflection_t02: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/grouping-content/the-ol-element/ol.start-reflection_t02: Skip # co19 issue 11.
+WebPlatformTest/html/semantics/interactive-elements/the-dialog-element/dialog-close_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/interactive-elements/the-dialog-element/dialog-showModal_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/scripting-1/the-script-element/async_t11: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/scripting-1/the-script-element/async_t11: Skip # co19 issue 11.
+WebPlatformTest/html/semantics/scripting-1/the-script-element/script-text_t02: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/checked_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/default_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/dir_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/disabled_t01: Pass, RuntimeError # Spurious pass # co19 issue 11.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/disabled_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/enabled_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/focus_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/focus_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/indeterminate_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/inrange-outofrange_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/link_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/link_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/valid-invalid_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/valid-invalid_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/tabular-data/the-table-element/table-rows_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/tabular-data/the-tr-element/rowIndex_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/text-level-semantics/the-a-element/a.text-getter_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/syntax/parsing/Document.getElementsByTagName-foreign_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/syntax/parsing/Document.getElementsByTagName-foreign_t02: RuntimeError # co19-roll r786: Please triage this failure.
+WebPlatformTest/html/syntax/parsing/math-parse_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/syntax/parsing/math-parse_t03: RuntimeError # co19 issue 11.
+WebPlatformTest/html/syntax/serializing-html-fragments/outerHTML_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t01: RuntimeError # Tests APIs that aren't yet visible. Tests should be deleted.
+WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t02: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t03: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t04: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t05: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t06: RuntimeError # co19-roll r761: Please triage this failure.
 WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
 WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-004_t01: RuntimeError # co19-roll r722: Please triage this failure.
 WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-004_t02: RuntimeError # co19-roll r722: Please triage this failure.
 WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/methods/elements-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-005_t01: RuntimeError # Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-006_t01: RuntimeError # Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-004_t01: RuntimeError # Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-004_t02: RuntimeError # Please triage this failure.
 WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-006_t01: RuntimeError # co19-roll r722: Please triage this failure.
 WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-003_t01: RuntimeError # Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-003_t02: RuntimeError # Please triage this failure.
 WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-005_t01: RuntimeError # co19-roll r722: Please triage this failure.
 WebPlatformTest/shadow-dom/events/event-dispatch/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
 WebPlatformTest/shadow-dom/events/event-dispatch/test-003_t01: RuntimeError # co19-roll r722: Please triage this failure.
@@ -320,267 +1070,7 @@
 WebPlatformTest/shadow-dom/shadow-trees/distributed-pseudo-element/test-002_t01: RuntimeError # co19-roll r722: Please triage this failure.
 WebPlatformTest/shadow-dom/shadow-trees/lower-boundary-encapsulation/test-004_t01: RuntimeError # co19-roll r722: Please triage this failure.
 WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/ownerdocument-002_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDocument/active-element-gets-unforcusable_t01: Skip # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDocument/set-focus-on-valid-element_t01: Skip # co19-roll r722: Please triage this failure.
-LibTest/html/Window/requestFileSystem_A01_t02: RuntimeError,Pass # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLOptionElement/collection-setter-getter_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLScriptElement/async-false-inside-async-false-load_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLScriptElement/async-inline-script_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLScriptElement/async-onbeforeload_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLScriptElement/defer-inline-script_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLScriptElement/defer-onbeforeload_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLScriptElement/remove-in-beforeload_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLSelectElement/selected-index-preserved-when-option-text-changes_t01: RuntimeError # co19-roll r722: Issue 18127
-LayoutTests/fast/dom/HTMLTemplateElement/custom-element-wrapper-gc_t01: RuntimeError # co19-roll r722: Issue 18250
-LayoutTests/fast/dom/HTMLTemplateElement/innerHTML_t01: RuntimeError # co19-roll r722: Issue 18249
-LayoutTests/fast/dom/HTMLTemplateElement/ownerDocumentXHTML_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/MutationObserver/observe-childList_t01: RuntimeError # co19-roll r722: Issue 18253
-LayoutTests/fast/dom/MutationObserver/weak-callback-gc-crash_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/Node/initial-values_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/Range/range-created-during-remove-children_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/Range/range-detached-exceptions_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/html/imports/import-element-removed-flag_t01: Skip # co19-roll r722: Please triage this failure.
-LibTest/collection/ListBase/ListBase_class_A01_t01: Skip # co19-roll r722: Please triage this failure.
-LibTest/collection/ListMixin/ListMixin_class_A01_t01: Skip # co19-roll r722: Please triage this failure.
-LibTest/collection/ListMixin/ListMixin_class_A01_t02: Skip # co19-roll r722: Please triage this failure.
-LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t03: RuntimeError # co19-roll r722: Please triage this failure.
-LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t06: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/Utils/test/asyncTestFail_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/Utils/test/asyncTestFail_t02: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/Utils/test/asyncTestTimeout_t01: Skip # co19-roll r722: Please triage this failure.
-WebPlatformTest/Utils/test/testFail_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/EventTarget/dispatchEvent_A02_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/EventTarget/dispatchEvent_A03_t01: Skip # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/events/type_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/DOMImplementation-createDocument_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/DOMImplementation-createDocumentType_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/DOMImplementation-createHTMLDocument_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Document-adoptNode_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Document-createElement_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Document-createElementNS_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Document-getElementsByTagName_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Element-childElementCount-nochild_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Element-childElementCount_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Node-appendChild_t02: RuntimeError, Pass # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Node-insertBefore_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Node-isEqualNode_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Node-nodeName_t01: RuntimeError # Please triage this failure.
-WebPlatformTest/dom/nodes/Node-replaceChild_t01: RuntimeError # co19-roll r722: Please triage this failure
-WebPlatformTest/dom/nodes/Node-textContent_t01: RuntimeError # Please triage this failure.
-WebPlatformTest/dom/nodes/attributes/setAttributeNS_A05_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/attributes/setAttributeNS_A06_t03: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/attributes/setAttributeNS_A07_t02: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/attributes/setAttributeNS_A07_t03: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/attributes/setAttributeNS_A08_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/attributes/setAttribute_A03_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-005_t01: RuntimeError # Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-006_t01: RuntimeError # Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-004_t01: RuntimeError # Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-004_t02: RuntimeError # Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-003_t01: RuntimeError # Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-003_t02: RuntimeError # Please triage this failure.
 WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-009_t01: RuntimeError # Please triage this failure.
-
-LayoutTests/fast/dom/css-innerHTML_t01: RuntimeError # Test is incorrect.
-
-# co19-roll r738.
-WebPlatformTest/DOMEvents/approved/ProcessingInstruction.DOMCharacterDataModified_t01: Skip # Times out. co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/embedded-content/media-elements/error-codes/error_t01: Skip # Times out and fails. # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/cues_t01: Skip # Times out and fails. # co19-roll r738: Please triage this failure.LayoutTests/fast/dom/Window/window-resize-contents_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/Window/window-resize_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/Window/window-resize-contents_t01: Pass, RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/Window/window-scroll-arguments_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/anchor-without-content_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/attribute-namespaces-get-set_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/blur-contenteditable_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/characterdata-api-arguments_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/client-width-height-quirks_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/custom/document-register-svg-extends_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/dataset-xhtml_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/dataset_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/focus-contenteditable_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/horizontal-scrollbar-in-rtl-doesnt-fire-onscroll_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/horizontal-scrollbar-when-dir-change_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/location-hash_t01: Pass, RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/option-properties_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/partial-layout-overlay-scrollbars_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/set-innerHTML_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/no-renderers-for-light-children_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/pseudoclass-update-checked-option_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/pseudoclass-update-disabled-optgroup_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/pseudoclass-update-disabled-option_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/pseudoclass-update-enabled-optgroup_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/pseudoclass-update-enabled-option_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/shadow-content-crash_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/shadow-removechild-and-blur-event_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
-WebPlatformTest/DOMEvents/approved/EventObject.after.dispatchEvenr_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/DOMEvents/approved/EventObject.multiple.dispatchEvent_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/DOMEvents/approved/addEventListener.optional.useCapture_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/browsers/browsing-the-web/read-media/pageload-image_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/browsers/browsing-the-web/read-media/pageload-video_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.body-getter_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.body-setter_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.getElementsByName-namespace_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.title_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.title_t05: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.title_t07: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/nameditem_t02: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/elements/global-attributes/dataset-delete_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/elements/global-attributes/dataset-get_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/elements/global-attributes/dataset-set_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/document-metadata/styling/LinkStyle_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLMediaElement/addTextTrack_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/src_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/mode_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/forms/attributes-common-to-form-controls/formAction_document_address_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/forms/attributes-common-to-form-controls/formaction_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/forms/textfieldselection/textfieldselection-setRangeText_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/forms/textfieldselection/textfieldselection-setSelectionRange_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.  Pass on macos.
-WebPlatformTest/html/semantics/forms/the-button-element/button-validation_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-fieldset-element/disabled_t01: RuntimeError # co19-roll r738: Please triage this failure.
-
-# co19-roll r761
-LayoutTests/fast/alignment/parse-align-items_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/alignment/parse-align-self_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/alignment/parse-justify-self_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/backgrounds/repeat/parsing-background-repeat_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/borders/border-radius-child_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/2d.fillText.gradient_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.gradient_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.negative_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.veryLarge_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.verySmall_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/canvas-arc-negative-radius_t01: Skip # Times out. co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/canvas-blending-text_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/canvas-empty-image-pattern_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/canvas-getImageData-invalid_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/canvas-large-dimensions_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/canvas-large-fills_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/canvas-lose-restore-googol-size_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/canvas-lose-restore-max-int-size_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/draw-custom-focus-ring_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/drawImage-with-broken-image_t01: Timeout, Pass # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/getPutImageDataPairTest_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/bad-arguments-test_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/canvas-resize-crash_t01: Skip # Causes following tests to fail. co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias-t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/context-lost_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/copy-tex-image-and-sub-image-2d_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/draw-webgl-to-canvas-2d_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/drawingbuffer-test_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/gl-object-get-calls_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/incorrect-context-object-behaviour_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/is-object_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/null-object-behaviour_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/premultiplyalpha-test_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/renderbuffer-initialization_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/triangle_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/uniform-location_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/add-remove-stylesheets-at-once-minimal-recalc-style_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/checked-pseudo-selector_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/collapsed-whitespace-reattach-in-style-recalc_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/content/content-none_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/content/content-normal_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/counters/complex-before_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/css-properties-case-insensitive_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/css3-nth-tokens-style_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/cursor-parsing-quirks_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/deprecated-flexbox-auto-min-size_t01: Pass, RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/first-child-display-change-inverse_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/focus-display-block-inline_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/font-face-cache-bug_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/font-face-unicode-range-load_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/font-face-unicode-range-overlap-load_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/fontfaceset-loadingdone_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/html-attr-case-sensitivity_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/id-or-class-before-stylesheet_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/inherit-initial-shorthand-values_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/invalid-predefined-color_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/link-alternate-stylesheet-1_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/link-alternate-stylesheet-2_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/link-alternate-stylesheet-3_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/link-alternate-stylesheet-4_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/link-alternate-stylesheet-5_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/media-query-recovery_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/parsing-at-rule-recovery_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/parsing-page-rule_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/parsing-selector-error-recovery_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/pseudo-any_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/pseudo-target-indirect-sibling-001_t01: Skip # Times out. co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/pseudo-target-indirect-sibling-002_t01: Skip # Times out. co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/readonly-pseudoclass-opera-001_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/readonly-pseudoclass-opera-002_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/readonly-pseudoclass-opera-003_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/readonly-pseudoclass-opera-004_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/readonly-pseudoclass-opera-005_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/sticky/parsing-position-sticky_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/style-element-process-crash_t01: Skip # Times out. co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/stylesheet-enable-first-alternate-on-load-sheet_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/stylesheet-enable-second-alternate-link_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/webkit-keyframes-errors_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/4XPath/Borrowed/cz_20030217_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/4XPath/Borrowed/namespace-nodes_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/4XPath/Core/test_core_functions_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/4XPath/Core/test_node_test_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/ambiguous-operators_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/ensure-null-namespace_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/implicit-node-args_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/invalid-resolver_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/node-name-case-sensitivity_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/position_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/reverse-axes_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LibTest/html/Element/querySelectorAll_A01_t02: RuntimeError # co19-roll r761: Please triage this failure.
-LibTest/html/IFrameElement/querySelector_A01_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/dom/Node-replaceChild_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html-imports/link-import_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html-imports/link-import_t02: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html-imports/loading-import_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-form-element/form-autocomplete_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-form-element/form-elements-matches_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-form-element/form-elements-nameditem_t02: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/date_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/datetime-local_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/datetime_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/datetime_t02: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/email_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/email_t02: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/input-textselection_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/month_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/range_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/time_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/time_t02: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/type-change-state_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/url_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/valueMode_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/week_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-meter-element/meter_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-option-element/option-text-recurse_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-option-element/option-text-spaces_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/grouping-content/the-blockquote-element/grouping-blockquote_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/grouping-content/the-ol-element/ol.start-reflection_t02: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/interactive-elements/the-dialog-element/dialog-close_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/interactive-elements/the-dialog-element/dialog-showModal_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/scripting-1/the-script-element/async_t11: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/scripting-1/the-script-element/script-text_t02: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/checked_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/default_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/dir_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/disabled_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/enabled_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/focus_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/indeterminate_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/inrange-outofrange_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/link_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/valid-invalid_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/tabular-data/the-table-element/table-rows_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/tabular-data/the-tr-element/rowIndex_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/syntax/serializing-html-fragments/outerHTML_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t01: RuntimeError # Tests APIs that aren't yet visible. Tests should be deleted.
-WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t02: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t03: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t05: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t06: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t04: RuntimeError # co19-roll r761: Please triage this failure.
 WebPlatformTest/webstorage/event_constructor_t01: RuntimeError # co19-roll r761: Please triage this failure.
 WebPlatformTest/webstorage/event_constructor_t02: RuntimeError # co19-roll r761: Please triage this failure.
 WebPlatformTest/webstorage/event_local_key_t01: RuntimeError # co19-roll r761: Please triage this failure.
@@ -588,528 +1078,16 @@
 WebPlatformTest/webstorage/storage_local_setitem_quotaexceedederr_t01: Skip # Times out flakily. co19-roll r761: Please triage this failure.
 WebPlatformTest/webstorage/storage_session_setitem_quotaexceedederr_t01: Skip # Times out flakily. co19-roll r761: Please triage this failure.
 
-# co19-roll r786
-Language/14_Libraries_and_Scripts/4_Scripts_A03_t03: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css/font-face-insert-link_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css/font-face-multiple-ranges-for-unicode-range_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-generated-content/malformed-url_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-generated-content/pseudo-animation_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-generated-content/pseudo-animation-before-onload_t01: Pass, RuntimeError # Please triage this failure
-LayoutTests/fast/css-generated-content/pseudo-element-events_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-generated-content/pseudo-transition-event_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-generated-content/pseudo-transition_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/auto-content-resolution-rows_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/breadth-size-resolution-grid_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/calc-resolution-grid-item_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/display-grid-set-get_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/flex-and-minmax-content-resolution-rows_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/flex-content-resolution-columns_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/flex-content-resolution-rows_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-auto-columns-rows-get-set_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-auto-flow-get-set_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-auto-flow-update_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-container-change-explicit-grid-recompute-child_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-element-border-grid-item_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-element-border-padding-grid-item_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-element-empty-row-column_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-element-min-max-height_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-element-padding-grid-item_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-element-padding-margin_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-element-shrink-to-fit_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-item-area-get-set_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-item-bad-named-area-auto-placement_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-item-bad-resolution-double-span_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-item-change-order-auto-flow_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-item-display_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows-horiz-bt_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows-vert-lr_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows-vert-rl_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-item-margin-resolution_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-item-order-auto-flow-resolution_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-template-areas-get-set_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/implicit-rows-auto-resolution_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/justify-self-cell_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/minmax-fixed-logical-height-only_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/minmax-fixed-logical-width-only_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track-in-percent-grid_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track-update_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/percent-padding-margin-resolution-grid-item-update_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/percent-padding-margin-resolution-grid-item_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/percent-resolution-grid-item_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/place-cell-by-index_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css/style-scoped/style-scoped-nested_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css/style-scoped/style-scoped-with-dom-operation_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css/style-scoped/style-scoped-with-important-rule_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css3-text/css3-text-align-last/getComputedStyle/getComputedStyle-text-align-last-inherited_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css3-text/css3-text-align-last/getComputedStyle/getComputedStyle-text-align-last_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css3-text/css3-text-decoration/getComputedStyle/getComputedStyle-text-decoration-color_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css3-text/css3-text-decoration/getComputedStyle/getComputedStyle-text-decoration-line_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css3-text/css3-text-decoration/getComputedStyle/getComputedStyle-text-decoration-style_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css3-text/css3-text-decoration/getComputedStyle/getComputedStyle-text-underline-position_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css3-text/css3-text-indent/getComputedStyle/getComputedStyle-text-indent-inherited_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css3-text/css3-text-indent/getComputedStyle/getComputedStyle-text-indent_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css3-text/css3-text-justify/getComputedStyle/getComputedStyle-text-justify_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/dynamic/crash-generated-counter_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/dynamic/crash-generated-image_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/dynamic/crash-generated-quote_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/dynamic/crash-generated-text_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/dynamic/insertAdjacentElement_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
-LayoutTests/fast/dynamic/recursive-layout_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/add-event-without-document_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/clipboard-clearData_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/clipboard-dataTransferItemList_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/div-focus_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/document-elementFromPoint_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/event-creation_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/event-listener-html-non-html-confusion_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/initkeyboardevent-crash_t01: RuntimeError, Timeout # co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/input-focus-no-duplicate-events_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/invalid-003_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/invalid-004_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/label-focus_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/mutation-during-replace-child-2_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/mutation-during-replace-child_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/nested-event-remove-node-crash_t01: Skip # Flaky timeout. co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/scoped/editing-commands_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/scroll-event-does-not-bubble_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/tabindex-removal-from-focused-element_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/exclusions/parsing/parsing-wrap-flow_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/exclusions/parsing/parsing-wrap-through_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/files/blob-close-read_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/files/blob-close_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/files/xhr-response-blob_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/filesystem/async-operations_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/filesystem/directory-entry-to-uri_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/filesystem/file-entry-to-uri_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/filesystem/filesystem-reference_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/storage/disallowed-storage_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/storage/storage-disallowed-in-data-url_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/sub-pixel/cssom-subpixel-precision_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/sub-pixel/float-containing-block-with-margin_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/sub-pixel/replaced-element-baseline_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/sub-pixel/table-rows-have-stable-height_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/anonymous-table-section-removed_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/caption-orthogonal-writing-mode-sizing_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/col-width-span-expand_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/computeLogicalWidth-table-needsSectionRecalc_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/css-table-max-height_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/css-table-max-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/css-table-width-with-border-padding_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/hittest-tablecell-bottom-edge_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/hittest-tablecell-right-edge_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/hittest-tablecell-with-borders-bottom-edge_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/hittest-tablecell-with-borders-right-edge_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/large-shrink-wrapped-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/margins-perpendicular-containing-block_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/min-width-css-block-table_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/min-width-css-inline-table_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/min-width-html-block-table_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/min-width-html-inline-table_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/padding-height-and-override-height_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/table-all-rowspans-height-distribution-in-rows-except-overlapped_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/table-all-rowspans-height-distribution-in-rows_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/table-cell-offset-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/table-colgroup-present-after-table-row_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/table-rowspan-cell-with-empty-cell_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/table-rowspan-height-distribution-in-rows_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/table-rowspan-height-distribution-in-rows_t02: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/table-with-content-width-exceeding-max-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text-autosizing/vertical-writing-mode_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/find-soft-hyphen_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/find-spaces_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/font-ligatures-linebreak_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/font-ligatures-linebreak-word_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/international/cjk-segmentation_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/international/iso-8859-8_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/international/rtl-text-wrapping_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/international/thai-offsetForPosition-inside-character_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/ipa-tone-letters_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/line-break-after-question-mark_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/offsetForPosition-cluster-at-zero_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/regional-indicator-symobls_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/remove-zero-length-run_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/sub-pixel/text-scaling-ltr_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/sub-pixel/text-scaling-pixel_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/sub-pixel/text-scaling-rtl_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/sub-pixel/text-scaling-vertical_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/sub-pixel/text-scaling-webfont_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/text-combine-shrink-to-fit_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/transforms/bounding-rect-zoom_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/transforms/hit-test-large-scale_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/file-http-base_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/file_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/host_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/idna2003_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/idna2008_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/invalid-urls-utf8_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/ipv4_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/ipv6_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/path_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/query_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/relative-unix_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/relative-win_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/relative_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/segments-from-data-url_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/segments_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/standard-url_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/writing-mode/auto-sizing-orthogonal-flows_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/writing-mode/positionForPoint_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/writing-mode/table-hit-test_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/writing-mode/vertical-font-vmtx-units-per-em_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-abort_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
-LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-arraybuffer_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
-LayoutTests/fast/xpath/4XPath/Core/test_core_functions_t02: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/xpath/4XPath/Core/test_node_test_t02: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/xpath/attr-namespace_t02: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/xpath/node-name-case-sensitivity_t02: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/xpath/py-dom-xpath/data_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/xpath/py-dom-xpath/expressions_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/xpath/py-dom-xpath/paths_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/xsl/default-html_t01: RuntimeError # co19-roll r786: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/password_t01: RuntimeError # co19-roll r786: Please triage this failure.
-WebPlatformTest/html/syntax/parsing/Document.getElementsByTagName-foreign_t02: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/dom/52776_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/Node/fragment-mutation_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/Range/bug-19527_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/Range/insertNode-empty-fragment-crash_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/Range/mutation_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/Range/range-constructor_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/Range/range-expand_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/Range/range-insertNode-separate-endContainer_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/Range/range-insertNode-splittext_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/document-importNode-arguments_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/horizontal-scrollbar-in-rtl_t01: RuntimeError # Please triage this failure.
-
-
-# co19-roll r801
-LayoutTests/fast/canvas/webgl/canvas-test_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/canvas/webgl/oes-element-index-uint_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-strict-mode-wtih-checkbox_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/dom/MutationObserver/database-callback-delivery_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/events/change-overflow-on-overflow-change_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/filesystem/file-writer-abort-continue_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/filesystem/file-writer-abort-depth_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/filesystem/file-writer-events_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/filesystem/file-writer-gc-blob_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/filesystem/file-writer-write-overlapped_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/filesystem/read-directory-many_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/filesystem/simple-readonly_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/HTMLOptionElement_selected2_t01: Skip # Times out. co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/autofocus-focus-only-once_t01: Skip # Times out. co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/autofocus-input-css-style-change_t01: Skip # Times out. co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/autofocus-opera-007_t01: Skip # Times out. co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/autofocus-readonly-attribute_t01: Skip # Times out. co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/button-baseline-and-collapsing_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/button/button-disabled-blur_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/clone-input-with-dirty-value_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-change-layout-by-value_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-onblur-setvalue-onfocusremoved_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-change-layout-by-value_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/focus-style-pending_t01: Skip # Times out. co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/focus_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/formmethod-attribute-button-html_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/formmethod-attribute-input-html_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/input-appearance-elementFromPoint_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/input-hit-test-border_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/input-width-height-attributes-without-renderer-loaded-image_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/listbox-select-all_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/listbox-selection-2_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/menulist-disabled-selected-option_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/menulist-selection-reset_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/menulist-submit-without-selection_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/multiple-selected-options-innerHTML_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/option-change-single-selected_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/option-strip-unicode-spaces_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/parser-associated-form-removal_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/search-popup-crasher_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/select-change-popup-to-listbox-in-event-handler_t01: Skip # Times out. co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/select-clientheight-large-size_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/select-clientheight-with-multiple-attr_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/select-list-box-mouse-focus_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/submit-nil-value-field-assert_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/textarea-scrollbar-height_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/textfield-focus-out_t01: Skip # Times out. co19-roll r801: Please triage this failure.
-LayoutTests/fast/html/select-dropdown-consistent-background-color_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/inline/boundingBox-with-continuation_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/inline/inline-position-top-align_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/inline/inline-with-empty-inline-children_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/inline/out-of-flow-objects-and-whitespace-after-empty-inline_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/inline/parent-inline-element-padding-contributes-width_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/inline/positioned-element-padding-contributes-width_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/layers/normal-flow-hit-test_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/layers/zindex-hit-test_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/loader/about-blank-hash-change_t01: Skip # Times out. co19-roll r801: Please triage this failure.
-LayoutTests/fast/loader/about-blank-hash-kept_t01: Skip # Times out. co19-roll r801: Please triage this failure.
-LayoutTests/fast/loader/hashchange-event-properties_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/loader/loadInProgress_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/loader/onhashchange-attribute-listeners_t01: Skip # Times out. co19-roll r801: Please triage this failure.
-LayoutTests/fast/loader/scroll-position-restored-on-back_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/loader/scroll-position-restored-on-reload-at-load-event_t01: Skip # Times out. co19-roll r801: Please triage this failure.
-LayoutTests/fast/loader/stateobjects/replacestate-in-onunload_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/masking/parsing-clip-path-shape_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/masking/parsing-mask-source-type_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/masking/parsing-mask_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/media/media-query-list-syntax_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/balance-short-trailing-empty-block_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/balance-trailing-border_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/balance-trailing-border_t02: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/break-after-always-bottom-margin_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/break-properties_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/cssom-view_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/flipped-blocks-hit-test_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/float-truncation_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/hit-test-above-or-below_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/hit-test-end-of-column-with-line-height_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/hit-test-end-of-column_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/hit-test-float_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/hit-test-gap-between-pages_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/hit-test-gap-between-pages-flipped_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/newmulticol/balance-images_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/newmulticol/balance-maxheight_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/newmulticol/balance_t04: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/newmulticol/balance_t07: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/newmulticol/balance_t08: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/newmulticol/balance_t09: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/newmulticol/balance_t10: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/vertical-lr/float-truncation_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/vertical-rl/break-properties_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/vertical-rl/float-truncation_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/vertical-rl/image-inside-nested-blocks-with-border_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/widows_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/widows_t02: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/overflow/child-100percent-height-inside-fixed-container-with-overflow-auto_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/overflow/replaced-child-100percent-height-inside-fixed-container-with-overflow-auto_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/overflow/scroll-vertical-not-horizontal_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/overflow/scrollbar-restored_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/parser/foster-parent-adopted_t02: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/parser/fragment-parser-doctype_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/parser/innerhtml-with-prefixed-elements_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/parser/pre-first-line-break_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/replaced/container-width-zero_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-anonymous-table-cell_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-table-cell-ignore-height_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/replaced/preferred-widths_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/replaced/table-percent-height_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/replaced/table-percent-width_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/ruby/ruby-line-height_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/parsing/parsing-shape-lengths_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/shape-outside-floats/shape-outside-big-box-border-radius_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-diamond-margin-polygon_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-margin-left_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-margin-right_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-image-margin_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-image-margin_t02: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-inset-rounded-different-writing-modes-left_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-inset-rounded-different-writing-modes-right_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/shape-outside-floats/shape-outside-rounded-boxes_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/shape-outside-floats/shape-outside-rounded-boxes_t02: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/table/nested-tables-with-div-offset_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/dom/getElementsByClassName/011_t01: RuntimeError # Chrome 39 roll. Please triage this failure
-
-#
-# Everything below this point is associated with co19 Issue 747
-#
-LayoutTests/fast/dynamic/insertAdjacentHTML_t01: Pass, RuntimeError
-LayoutTests/fast/layers/zindex-hit-test_t01: RuntimeError
-LayoutTests/fast/layers/normal-flow-hit-test_t01: RuntimeError
-LayoutTests/fast/multicol/balance-unbreakable_t01: Pass, RuntimeError
-LayoutTests/fast/multicol/fixed-column-percent-logical-height-orthogonal-writing-mode_t01: RuntimeError
-LayoutTests/fast/multicol/image-inside-nested-blocks-with-border_t01: RuntimeError
-LayoutTests/fast/multicol/inherit-column-values_t01: RuntimeError
-LayoutTests/fast/multicol/inline-getclientrects_t01: RuntimeError
-LayoutTests/fast/multicol/newmulticol/balance_t01: Pass, RuntimeError
-LayoutTests/fast/multicol/newmulticol/balance-maxheight_t02: RuntimeError
-LayoutTests/fast/multicol/newmulticol/balance_t02: Pass, RuntimeError
-LayoutTests/fast/multicol/newmulticol/balance_t04: Pass, RuntimeError
-LayoutTests/fast/multicol/newmulticol/balance_t05: Pass, RuntimeError
-LayoutTests/fast/multicol/newmulticol/balance_t06: Pass, RuntimeError
-LayoutTests/fast/multicol/newmulticol/balance_t07: Pass, RuntimeError
-LayoutTests/fast/multicol/newmulticol/balance_t08: Pass, RuntimeError
-LayoutTests/fast/multicol/newmulticol/balance_t09: Pass, RuntimeError
-LayoutTests/fast/multicol/newmulticol/balance_t10: Pass, RuntimeError # I don't understand how, but sometimes passes.
-LayoutTests/fast/multicol/column-width-zero_t01: Pass, RuntimeError
-LayoutTests/fast/multicol/widows_t01: Pass, RuntimeError
-LayoutTests/fast/multicol/vertical-lr/break-properties_t01: RuntimeError
-LayoutTests/fast/multicol/orphans-relayout_t01: Pass, RuntimeError
-LayoutTests/fast/multicol/zeroColumnCount_t01: RuntimeError
-LayoutTests/fast/media/media-query-serialization_t01: RuntimeError
-LayoutTests/fast/media/mq-append-delete_t01: RuntimeError
-LayoutTests/fast/media/mq-color-index_t02: RuntimeError
-LayoutTests/fast/media/mq-js-media-except_t02: RuntimeError
-LayoutTests/fast/media/mq-js-media-except_t01: RuntimeError
-LayoutTests/fast/media/mq-js-media-except_t03: RuntimeError
-LayoutTests/fast/media/mq-js-update-media_t01: RuntimeError
-LayoutTests/fast/media/mq-parsing_t01: Pass, RuntimeError # False passes on Firefox, but trying to keep these grouped with the issue.
-LayoutTests/fast/mediastream/RTCPeerConnection-AddRemoveStream_t01: Skip # Passes on Safari, Issue 23475
-LayoutTests/fast/loader/local-css-allowed-in-strict-mode_t01: RuntimeError
-LayoutTests/fast/overflow/replaced-child-100percent-height-inside-fixed-container-with-overflow-auto_t01: Pass, RuntimeError # False pass on Safari
-LayoutTests/fast/lists/marker-preferred-margins_t01: RuntimeError
-LayoutTests/fast/lists/item-not-in-list-line-wrapping_t01: RuntimeError
-LayoutTests/fast/lists/list-style-position-inside_t01: Pass, RuntimeError
-LayoutTests/fast/innerHTML/innerHTML-special-elements_t01: RuntimeError
-LayoutTests/fast/inline/fixed-pos-moves-with-abspos-inline-parent_t01: RuntimeError
-LayoutTests/fast/inline/fixed-pos-moves-with-abspos-parent-relative-ancestor_t01: RuntimeError
-LayoutTests/fast/inline/inline-relative-offset-boundingbox_t01: RuntimeError
-LayoutTests/fast/inline/fixed-pos-moves-with-abspos-parent_t01: RuntimeError
-LayoutTests/fast/inline/fixed-pos-with-transform-container-moves-with-abspos-parent_t01: RuntimeError
-LayoutTests/fast/inline/empty-inline-before-collapsed-space_t01: RuntimeError
-LayoutTests/fast/inline/reattach-inlines-in-anonymous-blocks-with-out-of-flow-siblings_t01: RuntimeError
-LayoutTests/fast/overflow/overflow-rtl-vertical-origin_t01: Pass, RuntimeError # False passes on Firefox, but trying to keep these grouped with the issue.
-LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor_t01: Pass # False pass
-LayoutTests/fast/table/col-width-span-expand_t01: Skip
-LayoutTests/fast/text/container-align-with-inlines_t01: RuntimeError
-LayoutTests/fast/text/font-fallback-synthetic-italics_t01: Pass, RuntimeError
-LayoutTests/fast/text/international/listbox-width-rtl_t01: RuntimeError
-LayoutTests/fast/text/glyph-reordering_t01: Pass, RuntimeError # This is a false pass. The font gets sanitized, so whether it works or not probably depends on default sizes.
-LayoutTests/fast/text/international/rtl-text-wrapping_t01: Pass # This is a false pass. All the content gets sanitized, so there's nothing to assert fail on. If the code did anything it would fail.
-LayoutTests/fast/text/line-break-after-empty-inline-hebrew_t01: Pass, RuntimeError
-LayoutTests/fast/text/line-break-after-inline-latin1_t01: RuntimeError
-LayoutTests/fast/text/line-breaks-after-closing-punctuations_t01: RuntimeError
-LayoutTests/fast/text/line-breaks-after-hyphen-before-number_t01: RuntimeError
-LayoutTests/fast/text/line-breaks-after-ideographic-comma-or-full-stop_t01: RuntimeError
-LayoutTests/fast/text/regional-indicator-symobls_t01: Pass, Fail
-LayoutTests/fast/text-autosizing/inline-width_t01: RuntimeError
-LayoutTests/fast/text-autosizing/text-removal_t01: RuntimeError
-LayoutTests/fast/text-autosizing/table-inline-width_t01: RuntimeError
-LayoutTests/fast/text/container-align-with-inlines_t01: RuntimeError
-LayoutTests/fast/text/font-fallback-synthetic-italics_t01: RuntimeError
-LayoutTests/fast/text/font-ligatures-linebreak-word_t01: Skip
-LayoutTests/fast/text/ipa-tone-letters_t01: Pass, RuntimeError
-LayoutTests/fast/text/pre-wrap-trailing-tab_t01: RuntimeError
-LayoutTests/fast/text-autosizing/display-type-change-lineHeight_t01: RuntimeError
-LayoutTests/fast/url/trivial_t01: RuntimeError
-LayoutTests/fast/url/trivial-segments_t01: RuntimeError
-LayoutTests/fast/url/scheme_t01: RuntimeError
-LayoutTests/fast/url/host-lowercase-per-scheme_t01: RuntimeError
-LayoutTests/fast/url/safari-extension_t01: RuntimeError
-LayoutTests/fast/url/safari-extension_t01: RuntimeError
-LayoutTests/fast/url/port_t01: RuntimeError
-LayoutTests/fast/url/mailto_t01: RuntimeError
-LayoutTests/fast/url/path-url_t01: RuntimeError
-LayoutTests/fast/url/anchor_t01: RuntimeError
-LayoutTests/fast/writing-mode/auto-margins-across-boundaries_t01: RuntimeError
-LayoutTests/fast/writing-mode/display-mutation_t01: RuntimeError
-LayoutTests/fast/writing-mode/percentage-padding_t01: RuntimeError
-LayoutTests/fast/writing-mode/relative-positioning-percentages_t01: RuntimeError
-LayoutTests/fast/writing-mode/block-formatting-context_t01: RuntimeError
-LayoutTests/fast/writing-mode/percentage-margins-absolute-replaced_t01: Pass, RuntimeError
-LayoutTests/fast/text/font-ligatures-linebreak-word_t01: Skip
-LayoutTests/fast/html/adjacent-html-context-element_t01:RuntimeError
-LayoutTests/fast/dom/HTMLElement/insertAdjacentHTML-errors_t01: RuntimeError
-LayoutTests/fast/transforms/transform-inside-overflow-scroll_t01: RuntimeError
-LayoutTests/fast/transforms/transform-hit-test-flipped_t01: Pass, RuntimeError # Passes on Firefox, but is clearly not testing what it's trying to test.
-LayoutTests/fast/transforms/scrollIntoView-transformed_t01: Pass, RuntimeError # False passes on Firefox.
-LayoutTests/fast/transforms/bounding-rect-zoom_t01: RuntimeError, Pass # Erratic, but only passes because divs have been entirely removed.
-LayoutTests/fast/transforms/topmost-becomes-bottomost-for-scrolling_t01: RuntimeError
-LayoutTests/fast/table/anonymous-table-section-removed_t01: Skip
-LayoutTests/fast/table/hittest-tablecell-bottom-edge_t01: Skip
-LayoutTests/fast/table/table-width-exceeding-max-width_t01: Pass, RuntimeError
-LayoutTests/fast/table/table-size-integer-overflow_t01: RuntimeError
-LayoutTests/fast/table/table-sections-border-spacing_t01: RuntimeError
-LayoutTests/fast/table/switch-table-layout_t01: RuntimeError
-LayoutTests/fast/table/switch-table-layout-multiple-section_t01: RuntimeError
-LayoutTests/fast/table/switch-table-layout-dynamic-cells_t01: RuntimeError
-LayoutTests/fast/table/resize-table-row_t01: RuntimeError
-LayoutTests/fast/table/resize-table-cell_t01: RuntimeError
-LayoutTests/fast/table/resize-table-binding-cell_t01: RuntimeError
-LayoutTests/fast/table/min-max-width-preferred-size_t01: Pass, RuntimeError
-LayoutTests/fast/table/margins-flipped-text-direction_t01: Pass, RuntimeError
-LayoutTests/fast/table/html-table-width-max-width-constrained_t01: Pass, RuntimeError
-LayoutTests/fast/table/fixed-table-layout-width-change_t01: Pass, RuntimeError # False passes on Firefox
-LayoutTests/fast/table/fixed-table-with-percent-width-inside-extra-large-div_t01: RuntimeError
-LayoutTests/fast/table/absolute-table-percent-lengths_t01: RuntimeError
-LayoutTests/fast/svg/whitespace-length_t01: RuntimeError
-LayoutTests/fast/svg/whitespace-number_t01: RuntimeError
-LayoutTests/fast/svg/whitespace-length-invalid_t01: RuntimeError
-LayoutTests/fast/svg/whitespace-angle_t01: RuntimeError
-LayoutTests/fast/svg/tabindex-focus_t01: RuntimeError
-LayoutTests/fast/svg/whitespace-integer_t01: RuntimeError
-LayoutTests/fast/sub-pixel/shadows-computed-style_t01: RuntimeError
-LayoutTests/fast/sub-pixel/tiled-canvas-elements_t01: RuntimeError
-LayoutTests/fast/sub-pixel/float-list-inside_t01: RuntimeError
-LayoutTests/fast/sub-pixel/float-with-margin-in-container_t01: RuntimeError
-LayoutTests/fast/sub-pixel/float-percentage-widths_t01: RuntimeError
-LayoutTests/fast/sub-pixel/computedstylemargin_t01: RuntimeError
-LayoutTests/fast/sub-pixel/block-preferred-widths-with-sub-pixel-floats_t01: RuntimeError
-LayoutTests/fast/sub-pixel/auto-table-layout-should-avoid-text-wrapping_t01: RuntimeError
-LayoutTests/fast/sub-pixel/float-containing-block-with-margin_t01: RuntimeError
-LayoutTests/fast/sub-pixel/replaced-element-baseline_t01: Pass, RuntimeError # Fails on Safari, false pass on others
-LayoutTests/fast/selectors/style-sharing-last-child_t01: RuntimeError
-LayoutTests/fast/selectors/specificity-overflow_t01: RuntimeError
-LayoutTests/fast/scrolling/scroll-element-into-view_t01: RuntimeError
-LayoutTests/fast/ruby/parse-rp_t01: Pass, RuntimeError
-LayoutTests/fast/replaced/table-replaced-element_t01: RuntimeError
-LayoutTests/fast/replaced/table-percent-height-text-controls_t01: RuntimeError
-LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-table-cell-ignore-height_t01: RuntimeError, Pass # Spurious intermittent pass
-LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-anonymous-table-cell_t01: RuntimeError, Pass # Spurious intermittent pass.
-LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor_t01: RuntimeError, Pass # Spurious intermittent pass
-LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr_t01: RuntimeError, Pass # Spurious intermittent pass
-LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor_t01: Pass, RuntimeError
-LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr_t01: Pass, RuntimeError
-LayoutTests/fast/parser/stray-param_t01: RuntimeError
-LayoutTests/fast/replaced/available-height-for-content_t01: RuntimeError
-LayoutTests/fast/parser/parse-wbr_t01: Pass, RuntimeError
-LayoutTests/fast/overflow/height-during-simplified-layout_t01: RuntimeError
-LayoutTests/fast/overflow/child-100percent-height-inside-fixed-container-with-overflow-auto_t01: RuntimeError
-WebPlatformTest/html-imports/link-import-null_t01: RuntimeError
-WebPlatformTest/html/syntax/parsing/Document.getElementsByTagName-foreign_t01: RuntimeError
-WebPlatformTest/html/syntax/parsing/math-parse_t03: RuntimeError
-WebPlatformTest/html/syntax/parsing/math-parse_t01: RuntimeError
-WebPlatformTest/html/semantics/document-metadata/styling/LinkStyle_t01: RuntimeError
-WebPlatformTest/html/semantics/grouping-content/the-ol-element/ol.start-reflection_t02: Skip
-WebPlatformTest/html/semantics/text-level-semantics/the-a-element/a.text-getter_t01: RuntimeError
-WebPlatformTest/html/semantics/scripting-1/the-script-element/async_t11: Skip
-WebPlatformTest/html/semantics/selectors/pseudo-classes/disabled_t01: Pass, RuntimeError # Spurious pass
-WebPlatformTest/html/semantics/selectors/pseudo-classes/link_t01: RuntimeError
-WebPlatformTest/html/semantics/selectors/pseudo-classes/valid-invalid_t01: RuntimeError
-WebPlatformTest/html/semantics/selectors/pseudo-classes/focus_t01: RuntimeError
-WebPlatformTest/html/semantics/forms/the-input-element/pattern_attribute_t01: RuntimeError
-WebPlatformTest/html/semantics/forms/the-form-element/form-nameditem_t01: RuntimeError
-WebPlatformTest/html/semantics/disabled-elements/disabledElement_t01: RuntimeError
-WebPlatformTest/html/dom/documents/dom-tree-accessors/nameditem_t03: RuntimeError
-WebPlatformTest/html/dom/documents/dom-tree-accessors/nameditem_t05: RuntimeError
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.getElementsByName-param_t01: RuntimeError
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.getElementsByName-newelements_t01: RuntimeError
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.getElementsByName-case_t01: RuntimeError
-#
-# End of Issue 747
-#
-LibTest/html/IFrameElement/appendHtml_A01_t01: Pass, RuntimeError # Issue 23462
-LibTest/html/IFrameElement/appendHtml_A01_t02: Pass, RuntimeError # Issue 23462
-
 [ $compiler == none && ($runtime == dartium || $runtime == ContentShellOnAndroid ) && $checked ]
-LayoutTests/fast/html/article-element_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/html/aside-element_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/innerHTML/innerHTML-svg-read_t01: RuntimeError, Pass # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/dom/HTMLLabelElement/form/test1_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLTableElement/insert-row_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LibTest/html/Node/ownerDocument_A01_t01: RuntimeError # co19-roll r722: Issue 18251
-WebPlatformTest/custom-elements/instantiating/createElementNS_A05_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/custom-elements/instantiating/createElement_A05_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/html/semantics/forms/textfieldselection/selection_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-body-context_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-context_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-row-context_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/ownerdocument-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
-
-# co19-roll r738
-WebPlatformTest/DOMEvents/approved/Propagation.path.target.removed_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/elements/global-attributes/dataset-enumeration_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/custom/type-extensions_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/shadowhost-keyframes_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
-
-# co19-roll r761
+Language/Errors_and_Warnings/static_warning_t01: RuntimeError # Please triage this failure.
+Language/Errors_and_Warnings/static_warning_t02: RuntimeError # Please triage this failure.
+Language/Errors_and_Warnings/static_warning_t03: RuntimeError # Please triage this failure.
+Language/Errors_and_Warnings/static_warning_t04: RuntimeError # Please triage this failure.
+Language/Errors_and_Warnings/static_warning_t05: RuntimeError # Please triage this failure.
+Language/Errors_and_Warnings/static_warning_t06: RuntimeError # Please triage this failure.
 LayoutTests/fast/canvas/webgl/framebuffer-object-attachment_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/canvas/webgl/oes-vertex-array-object_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/canvas/webgl/read-pixels-test_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/box-sizing-border-box-dynamic-padding-border-update_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/display-inline-block-scrollbar_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/fixed-width-intrinsic-width-excludes-scrollbars_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/xpath-result-eventlistener-crash_t01: RuntimeError # co19-roll r761: Please triage this failure.
-
-# co19-roll r786
 LayoutTests/fast/css-intrinsic-dimensions/css-tables_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-absolutes_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-blocks_t01: RuntimeError # co19-roll r786: Please triage this failure.
@@ -1119,6 +1097,15 @@
 LayoutTests/fast/css-intrinsic-dimensions/multicol_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/css-intrinsic-dimensions/tables_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/css-intrinsic-dimensions/width-shrinks-avoid-floats_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css/box-sizing-border-box-dynamic-padding-border-update_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/display-inline-block-scrollbar_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/fixed-width-intrinsic-width-excludes-scrollbars_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/dom/HTMLDialogElement/top-layer-position-relative_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/HTMLDialogElement/top-layer-position-static_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/HTMLLabelElement/form/test1_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLTableElement/insert-row_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/custom/type-extensions_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/shadow/shadowhost-keyframes_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
 LayoutTests/fast/filesystem/file-writer-abort_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/filesystem/file-writer-events_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/filesystem/op-copy_t01: RuntimeError # co19-roll r786: Please triage this failure.
@@ -1131,6 +1118,25 @@
 LayoutTests/fast/filesystem/op-restricted-chars_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/filesystem/op-restricted-names_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/filesystem/op-restricted-unicode_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/flexbox/flexing-overflow-scroll-item_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/flexbox/intrinsic-min-width-applies-with-fixed-width_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/select-list-box-mouse-focus_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/html/article-element_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/html/aside-element_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/inline/empty-inline-before-collapsed-space_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/innerHTML/innerHTML-svg-read_t01: RuntimeError, Pass # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/lists/list-style-position-inside_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/lists/marker-preferred-margins_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/fixed-column-percent-logical-height-orthogonal-writing-mode_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/vertical-lr/image-inside-nested-blocks-with-border_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/replaced/available-height-for-content_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/shapes/parsing/parsing-shape-image-threshold_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/shapes/parsing/parsing-shape-margin_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/shapes/parsing/parsing-shape-outside_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/table/absolute-table-percent-lengths_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/table/css-table-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/table/fixed-table-layout-width-change_t01: RuntimeError # co19-roll r786: Please triage this failure.
@@ -1138,33 +1144,26 @@
 LayoutTests/fast/table/margins-flipped-text-direction_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/table/min-max-width-preferred-size_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/table/nested-tables-with-div-offset_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/switch-table-layout-dynamic-cells_t01: RuntimeError # co19 issue 11.
 LayoutTests/fast/table/switch-table-layout-dynamic-cells_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/table/switch-table-layout-multiple-section_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/switch-table-layout_t01: RuntimeError # co19 issue 11.
 LayoutTests/fast/table/switch-table-layout_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/table/table-width-exceeding-max-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/text/line-break-after-inline-latin1_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/url/trivial-segments_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/url/trivial_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/top-layer-position-relative_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/top-layer-position-static_t01: RuntimeError # Please triage this failure.
-
-# co19 roll r801
-LayoutTests/fast/flexbox/flexing-overflow-scroll-item_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/flexbox/intrinsic-min-width-applies-with-fixed-width_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/select-list-box-mouse-focus_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/inline/empty-inline-before-collapsed-space_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/lists/list-style-position-inside_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/lists/marker-preferred-margins_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/fixed-column-percent-logical-height-orthogonal-writing-mode_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/vertical-lr/image-inside-nested-blocks-with-border_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/replaced/available-height-for-content_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/parsing/parsing-shape-image-threshold_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/parsing/parsing-shape-margin_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/parsing/parsing-shape-outside_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/xpath/xpath-result-eventlistener-crash_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LibTest/html/Node/ownerDocument_A01_t01: RuntimeError # co19-roll r722: Issue 18251
+WebPlatformTest/DOMEvents/approved/Propagation.path.target.removed_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/custom-elements/instantiating/createElementNS_A05_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/custom-elements/instantiating/createElement_A05_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-body-context_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-context_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-row-context_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/html/dom/elements/global-attributes/dataset-enumeration_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/forms/textfieldselection/selection_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/ownerdocument-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
 
 [ $compiler == none && ($runtime == dartium || $runtime == ContentShellOnAndroid) && $mode == debug ]
 WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/mode_t01: Skip # Issue 19495.
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index e4edb77..b9f872a 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -11,16 +11,15 @@
 
 LibTest/core/int/toRadixString_A01_t01: Fail # co19 issue 492
 
-Language/03_Overview/1_Scoping_A02_t28: RuntimeError # Issue 21163
-Language/13_Statements/09_Switch_A01_t02: fail # Dart issue 12908
-Language/13_Statements/12_Labels_A01_t03: fail # Dart issue 2238
-Language/14_Libraries_and_Scripts/2_Exports_A04_t02: fail # Dart issue 12916
-Language/14_Libraries_and_Scripts/2_Exports_A04_t03: fail # Dart issue 12916
+Language/Statements/Switch/syntax_t02: fail # Dart issue 12908
+Language/Statements/Labels/syntax_t03: fail # Dart issue 2238
+Language/Libraries_and_Scripts/Exports/reexport_t01: fail # Dart issue 12916
+Language/Libraries_and_Scripts/Exports/reexport_t02: fail # Dart issue 12916
 
-Language/13_Statements/15_Assert_A03_t02: skip # co19 issue 734
-Language/13_Statements/15_Assert_A03_t03: skip # co19 issue 734
-Language/13_Statements/15_Assert_A04_t02: skip # co19 issue 734
-Language/13_Statements/15_Assert_A04_t05: skip # co19 issue 734
+Language/Statements/Assert/execution_t02: skip # co19 issue 734
+Language/Statements/Assert/execution_t03: skip # co19 issue 734
+Language/Statements/Assert/type_t02: skip # co19 issue 734
+Language/Statements/Assert/type_t05: skip # co19 issue 734
 
 
 LibTest/core/DateTime/parse_A03_t01: fail # Issue 12514
@@ -41,12 +40,12 @@
 [ $compiler == none && $runtime == vm ]
 LibTest/typed_data/Float32x4/reciprocalSqrt_A01_t01: Pass, Fail # co19 issue 599
 LibTest/typed_data/Float32x4/reciprocal_A01_t01: Pass, Fail # co19 issue 599
-Language/12_Expressions/12_Instance_Creation/2_Const_A11_t01: MissingCompileTimeError # Issue 22007
-Language/12_Expressions/12_Instance_Creation/2_Const_A11_t03: MissingCompileTimeError # Issue 22007
+Language/Expressions/Instance_Creation/Const/abstract_class_t01: MissingCompileTimeError # Issue 22007
+Language/Expressions/Instance_Creation/Const/abstract_class_t03: MissingCompileTimeError # Issue 22007
 # With asynchronous loading, the load errors in these tests are no longer recognized as compile errors:
-Language/14_Libraries_and_Scripts/1_Imports_A04_t02: Fail
-Language/14_Libraries_and_Scripts/2_Exports_A05_t02: Fail
-Language/14_Libraries_and_Scripts/3_Parts_A01_t06: Fail
+Language/Libraries_and_Scripts/Imports/invalid_uri_t02: Fail
+Language/Libraries_and_Scripts/Exports/invalid_uri_t02: Fail
+Language/Libraries_and_Scripts/Parts/syntax_t06: Fail
 
 [ $runtime == vm ]
 LibTest/math/MutableRectangle/MutableRectangle.fromPoints_A01_t01: Pass, RuntimeError # co19-roll r607: Please triage this failure
@@ -83,7 +82,72 @@
 WebPlatformTest/*: SkipByDesign # dart:html not supported on VM.
 
 [ $runtime == vm && $mode == debug && $builder_tag == asan ]
-Language/15_Types/4_Interface_Types_A11_t01: Skip  # Issue 21174.
+Language/Types/Interface_Types/subtype_t27: Skip  # Issue 21174.
 
 [ $runtime == vm && $arch == arm ]
 LibTest/typed_data/Float32x4/operator_multiplication_A01_t01: Fail # Dart issue 24416
+
+[ $runtime == vm ]
+# co19 update Sep 29, 2015 (3ed795ea02e022ef19c77cf1b6095b7c8f5584d0)
+Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t01: MissingCompileTimeError # Please triage this failure
+Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t02: MissingCompileTimeError # Please triage this failure
+Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t03: MissingCompileTimeError # Please triage this failure
+Language/Classes/Constructors/Constant_Constructors/not_a_constant_in_superclass_t01: MissingCompileTimeError # Please triage this failure
+Language/Classes/Constructors/Constant_Constructors/not_a_constant_in_superclass_t02: MissingCompileTimeError # Please triage this failure
+Language/Classes/Getters/type_object_t01: RuntimeError # Please triage this failure
+Language/Classes/Getters/type_object_t02: RuntimeError # Please triage this failure
+Language/Classes/Setters/syntax_t04: RuntimeError # Please triage this failure
+Language/Classes/Setters/type_object_t01: RuntimeError # Please triage this failure
+Language/Classes/Setters/type_object_t02: RuntimeError # Please triage this failure
+Language/Classes/Static_Methods/type_object_t01: RuntimeError # Please triage this failure
+Language/Classes/Static_Methods/type_object_t02: RuntimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/class_object_member_t01: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/class_object_member_t02: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/class_object_member_t03: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/class_object_member_t04: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/class_object_member_t05: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/class_object_member_t06: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t01: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t02: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t03: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t04: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t05: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t06: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t07: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t08: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/not_class_t01: CompileTimeError # Please triage this failure
+Language/Libraries_and_Scripts/Imports/namespace_changes_t10: RuntimeError # Please triage this failure
+Language/Libraries_and_Scripts/Parts/compilation_t09: MissingCompileTimeError # Please triage this failure
+Language/Libraries_and_Scripts/URIs/syntax_t04: RuntimeError # Please triage this failure
+Language/Libraries_and_Scripts/URIs/syntax_t05: RuntimeError # Please triage this failure
+Language/Libraries_and_Scripts/URIs/syntax_t09: RuntimeError # Please triage this failure
+Language/Libraries_and_Scripts/URIs/syntax_t10: RuntimeError # Please triage this failure
+Language/Libraries_and_Scripts/URIs/syntax_t14: RuntimeError # Please triage this failure
+Language/Libraries_and_Scripts/URIs/syntax_t15: RuntimeError # Please triage this failure
+Language/Mixins/Mixin_Application/error_t01: MissingCompileTimeError # Please triage this failure
+Language/Mixins/Mixin_Application/error_t02: MissingCompileTimeError # Please triage this failure
+Language/Mixins/declaring_constructor_t01: MissingCompileTimeError # Please triage this failure
+Language/Mixins/not_object_superclass_t01: MissingCompileTimeError # Please triage this failure
+Language/Mixins/reference_to_super_t01: MissingCompileTimeError # Please triage this failure
+
+[ $runtime == vm && $mode == debug ]
+Language/Mixins/Mixin_Application/wrong_type_t02: Crash # Please triage this failure
+
+[ $runtime == vm && $checked ]
+Language/Errors_and_Warnings/static_warning_t01: RuntimeError # Please triage this failure
+Language/Errors_and_Warnings/static_warning_t02: RuntimeError # Please triage this failure
+Language/Errors_and_Warnings/static_warning_t03: RuntimeError # Please triage this failure
+Language/Errors_and_Warnings/static_warning_t04: RuntimeError # Please triage this failure
+Language/Errors_and_Warnings/static_warning_t05: RuntimeError # Please triage this failure
+Language/Errors_and_Warnings/static_warning_t06: RuntimeError # Please triage this failure
+
+[ $runtime == vm && $noopt ]
+LibTest/collection/ListBase/ListBase_class_A01_t02: Pass, Timeout
+LibTest/collection/ListMixin/ListMixin_class_A01_t02: Pass, Timeout
+LibTest/core/Map/Map_class_A01_t04: Pass, Timeout
+LibTest/core/Uri/encodeQueryComponent_A01_t02: Pass, Timeout
+Language/Mixins/Mixin_Application/error_t01: Pass
+Language/Mixins/Mixin_Application/error_t02: Pass
+Language/Mixins/declaring_constructor_t01: Pass
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/deferred_type_t01: Pass
+Language/Metadata/*: Skip # Uses dart:mirrors
diff --git a/tests/compiler/dart2js/analyze_all_test.dart b/tests/compiler/dart2js/analyze_all_test.dart
index 2d72c76..2bb4808 100644
--- a/tests/compiler/dart2js/analyze_all_test.dart
+++ b/tests/compiler/dart2js/analyze_all_test.dart
@@ -30,27 +30,29 @@
 main() {
   Uri uri = Uri.parse('test:code');
   var compiler1 = compilerFor(SOURCE, uri, analyzeAll: false);
-  asyncTest(() => compiler1.runCompiler(uri).then((_) {
-    Expect.isFalse(compiler1.compilationFailed);
-    print(compiler1.warnings);
-    Expect.isTrue(compiler1.warnings.isEmpty, 'unexpected warnings');
-    Expect.isTrue(compiler1.errors.isEmpty, 'unexpected errors');
+  asyncTest(() => compiler1.run(uri).then((compilationSucceded) {
+    DiagnosticCollector collector = compiler1.diagnosticCollector;
+    Expect.isTrue(compilationSucceded);
+    print(collector.warnings);
+    Expect.isTrue(collector.warnings.isEmpty, 'unexpected warnings');
+    Expect.isTrue(collector.errors.isEmpty, 'unexpected errors');
   }));
 
   var compiler2 = compilerFor(SOURCE, uri, analyzeAll: true);
-  asyncTest(() => compiler2.runCompiler(uri).then((_) {
-    Expect.isTrue(compiler2.compilationFailed);
-    Expect.isTrue(compiler2.warnings.isEmpty,
-                  'unexpected warnings: ${compiler2.warnings}');
-    Expect.equals(2, compiler2.errors.length,
-                  'expected exactly two errors, but got ${compiler2.errors}');
+  asyncTest(() => compiler2.run(uri).then((compilationSucceded) {
+    DiagnosticCollector collector = compiler2.diagnosticCollector;
+    Expect.isFalse(compilationSucceded);
+    Expect.isTrue(collector.warnings.isEmpty,
+                  'unexpected warnings: ${collector.warnings}');
+    Expect.equals(2, collector.errors.length,
+                  'expected exactly two errors, but got ${collector.errors}');
 
-    Expect.equals(MessageKind.CONSTRUCTOR_IS_NOT_CONST,
-                  compiler2.errors[0].message.kind);
-    Expect.equals("Foo", compiler2.errors[0].node.toString());
+    CollectedMessage first = collector.errors.first;
+    Expect.equals(MessageKind.CONSTRUCTOR_IS_NOT_CONST, first.message.kind);
+    Expect.equals("Foo", SOURCE.substring(first.begin, first.end));
 
-    Expect.equals(MessageKind.CONSTRUCTOR_IS_NOT_CONST,
-                  compiler2.errors[1].message.kind);
-    Expect.equals("Foo", compiler2.errors[1].node.toString());
+    CollectedMessage second = collector.errors.elementAt(1);
+    Expect.equals(MessageKind.CONSTRUCTOR_IS_NOT_CONST, second.message.kind);
+    Expect.equals("Foo", SOURCE.substring(second.begin, second.end));
   }));
 }
diff --git a/tests/compiler/dart2js/analyze_dart2js_helpers_test.dart b/tests/compiler/dart2js/analyze_dart2js_helpers_test.dart
index 0787dd3..e4b9326 100644
--- a/tests/compiler/dart2js/analyze_dart2js_helpers_test.dart
+++ b/tests/compiler/dart2js/analyze_dart2js_helpers_test.dart
@@ -10,7 +10,7 @@
 import 'package:compiler/compiler_new.dart' show
     Diagnostic;
 import 'package:compiler/src/apiimpl.dart' show
-    Compiler;
+    CompilerImpl;
 import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/constants/expressions.dart' show
     ConstructedConstantExpression;
@@ -44,7 +44,7 @@
     options.add(Flags.verbose);
   }
   asyncTest(() async {
-    Compiler compiler = compilerFor(
+    CompilerImpl compiler = compilerFor(
         options: options, showDiagnostics: verbose);
     FormattingDiagnosticHandler diagnostics =
         new FormattingDiagnosticHandler(compiler.provider);
diff --git a/tests/compiler/dart2js/analyze_helper.dart b/tests/compiler/dart2js/analyze_helper.dart
index 7d84392..2d6b604 100644
--- a/tests/compiler/dart2js/analyze_helper.dart
+++ b/tests/compiler/dart2js/analyze_helper.dart
@@ -131,7 +131,7 @@
   }
 }
 
-typedef bool CheckResults(Compiler compiler,
+typedef bool CheckResults(CompilerImpl compiler,
                           CollectingDiagnosticHandler handler);
 
 Future analyze(List<Uri> uriList,
@@ -161,7 +161,7 @@
       Flags.showPackageWarnings];
   if (analyzeAll) options.add(Flags.analyzeAll);
   if (analyzeMain) options.add(Flags.analyzeMain);
-  var compiler = new Compiler(
+  var compiler = new CompilerImpl(
       provider,
       null,
       handler,
diff --git a/tests/compiler/dart2js/analyze_only_test.dart b/tests/compiler/dart2js/analyze_only_test.dart
index 08100a6..2d771fb 100644
--- a/tests/compiler/dart2js/analyze_only_test.dart
+++ b/tests/compiler/dart2js/analyze_only_test.dart
@@ -49,8 +49,8 @@
               localProvider, localHandler, options, outputCollector);
   result.then((_) {
     onValue(outputCollector.getOutput('', 'js'), errors, warnings);
-  }, onError: (e) {
-    throw 'Compilation failed: ${Error.safeToString(e)}';
+  }, onError: (e, st) {
+    throw 'Compilation failed: ${e} ${st}';
   }).then(asyncSuccess).catchError((error, stack) {
     print('\n\n-----------------------------------------------');
     print('main source:\n$main');
diff --git a/tests/compiler/dart2js/async_await_js_transform_test.dart b/tests/compiler/dart2js/async_await_js_transform_test.dart
index d0f4c85..40c9eb6 100644
--- a/tests/compiler/dart2js/async_await_js_transform_test.dart
+++ b/tests/compiler/dart2js/async_await_js_transform_test.dart
@@ -64,12 +64,13 @@
       switch (__goto) {
         case 0:
           // Function start
+          closures = [new A.main_closure()];
           __goto = 2;
-        closures = [new A.main_closure()];
-        return thenHelper(closures, body, __completer);
+          return thenHelper(closures, body, __completer);
         case 2:
           // returning from await.
-          v0 = __result, v1 = 0;
+          v0 = __result;
+          v1 = 0;
           if (v1 < 0 || v1 >= v0.length)
             H.ioore(v0, v1);
           else
diff --git a/tests/compiler/dart2js/backend_dart/dart_backend_test.dart b/tests/compiler/dart2js/backend_dart/dart_backend_test.dart
index 597f056..5db4160 100644
--- a/tests/compiler/dart2js/backend_dart/dart_backend_test.dart
+++ b/tests/compiler/dart2js/backend_dart/dart_backend_test.dart
@@ -4,6 +4,7 @@
 
 import "package:expect/expect.dart";
 import 'dart:async';
+import 'dart:io' as io;
 import "package:async_helper/async_helper.dart";
 import '../mock_compiler.dart';
 import '../mock_libraries.dart';
@@ -58,7 +59,9 @@
     if (uri.toString() == libUri.toString()) {
       return new Future.value(librarySrc);
     }
-    if (uri.path.endsWith('/core.dart')) {
+    if (uri.path.endsWith('/dart2dart.platform')) {
+      return new io.File.fromUri(uri).readAsBytes();
+    } else if (uri.path.endsWith('/core.dart')) {
       return new Future.value(buildLibrarySource(DEFAULT_CORE_LIBRARY));
     } else if (uri.path.endsWith('/core_patch.dart')) {
       return new Future.value(DEFAULT_PATCH_CORE_SOURCE);
@@ -87,7 +90,6 @@
 
   final options = <String>['--output-type=dart'];
   // Some tests below are using dart:io.
-  options.add('--categories=Client,Server');
   if (minify) options.add('--minify');
   if (stripTypes) options.add('--force-strip=types');
 
@@ -95,7 +97,7 @@
     OutputCollector outputCollector = new OutputCollector();
     return compile(
         scriptUri,
-        fileUri('libraryRoot/'),
+        Uri.base.resolve('sdk/'),
         fileUri('packageRoot/'),
         provider,
         handler,
diff --git a/tests/compiler/dart2js/bad_loop_test.dart b/tests/compiler/dart2js/bad_loop_test.dart
index bd1053c..c1b2a6d 100644
--- a/tests/compiler/dart2js/bad_loop_test.dart
+++ b/tests/compiler/dart2js/bad_loop_test.dart
@@ -33,7 +33,7 @@
     }
   }
 
-  Compiler compiler = new Compiler(
+  CompilerImpl compiler = new CompilerImpl(
       new LegacyCompilerInput(provider.readStringFromUri),
       new LegacyCompilerOutput(),
       new LegacyCompilerDiagnostics(diagnosticHandler),
diff --git a/tests/compiler/dart2js/call_site_simple_type_inferer_test.dart b/tests/compiler/dart2js/call_site_simple_type_inferer_test.dart
index 41ed1ba..517a347 100644
--- a/tests/compiler/dart2js/call_site_simple_type_inferer_test.dart
+++ b/tests/compiler/dart2js/call_site_simple_type_inferer_test.dart
@@ -16,7 +16,7 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(code, uri);
   compiler.disableInlining = disableInlining;
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var cls = findElement(compiler, className);
     var member = cls.lookupLocalMember(memberName);
     return check(compiler, member);
diff --git a/tests/compiler/dart2js/categories_test.dart b/tests/compiler/dart2js/categories_test.dart
index 3b22453..677d1a8 100644
--- a/tests/compiler/dart2js/categories_test.dart
+++ b/tests/compiler/dart2js/categories_test.dart
@@ -19,17 +19,13 @@
 
 void main() {
   asyncTest(() async {
-    await runTest("import 'dart:async'; main() {}", "Embedded", 1);
     await runTest("import 'dart:async'; main() {}", "Client", 0);
     await runTest("import 'dart:async'; main() {}", "Server", 0);
-    await runTest("import 'dart:html'; main() {}", "Embedded", 1);
     await runTest("import 'dart:html'; main() {}", "Client", 0);
     await runTest("import 'dart:html'; main() {}", "Server", 1);
-    await runTest("import 'dart:io'; main() {}", "Embedded", 1);
     await runTest("import 'dart:io'; main() {}", "Client", 1);
     await runTest("import 'dart:io'; main() {}", "Server", 0);
-    await runTest("import 'dart:_internal'; main() {}", "Embedded", 2);
-    await runTest("import 'dart:_internal'; main() {}", "Client", 2);
-    await runTest("import 'dart:_internal'; main() {}", "Server", 2);
+    await runTest("import 'dart:_internal'; main() {}", "Client", 1);
+    await runTest("import 'dart:_internal'; main() {}", "Server", 1);
   });
 }
diff --git a/tests/compiler/dart2js/check_elements_invariants_test.dart b/tests/compiler/dart2js/check_elements_invariants_test.dart
index bc1314f..7216a05 100644
--- a/tests/compiler/dart2js/check_elements_invariants_test.dart
+++ b/tests/compiler/dart2js/check_elements_invariants_test.dart
@@ -20,7 +20,7 @@
       '--disable-type-inference'
     ];
 
-Iterable<ClassElement> computeLiveClasses(Compiler compiler) {
+Iterable<ClassElement> computeLiveClasses(CompilerImpl compiler) {
   return new Set<ClassElement>()
       ..addAll(compiler.resolverWorld.directlyInstantiatedClasses)
       ..addAll(compiler.codegenWorld.directlyInstantiatedClasses);
diff --git a/tests/compiler/dart2js/check_members_test.dart b/tests/compiler/dart2js/check_members_test.dart
index fff8a93..a8271be 100644
--- a/tests/compiler/dart2js/check_members_test.dart
+++ b/tests/compiler/dart2js/check_members_test.dart
@@ -14,38 +14,61 @@
 /// the warnings of each category.
 const Map<String, dynamic> TESTS = const {
   // Instance methods.
-    'co19/src/Language/07_Classes/1_Instance_Methods_A01_t01.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A01_t02.dart': null,
-
     'language/check_method_override_test.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A06_t01.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A06_t02.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_more_parameters_t01.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_more_parameters_t02.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_fewer_parameters_t01.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_fewer_parameters_t02.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_named_parameters_t01.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_named_parameters_t02.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_named_parameters_t03.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_named_parameters_t04.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_named_parameters_t05.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_named_parameters_t06.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_subtype_t01.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_subtype_t02.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_subtype_t03.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_subtype_t04.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_subtype_t05.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_subtype_t06.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'same_name_static_member_in_superclass_t01.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'same_name_static_member_in_superclass_t02.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'same_name_static_member_in_superclass_t04.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'same_name_static_member_in_superclass_t05.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'same_name_static_member_in_superclass_t06.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'same_name_static_member_in_superclass_t07.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'same_name_static_member_in_superclass_t08.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'same_name_static_member_in_superclass_t09.dart': null,
 
-    'co19/src/Language/07_Classes/1_Instance_Methods_A02_t01.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A02_t02.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A02_t03.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A02_t04.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A02_t05.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A02_t06.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A03_t01.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A03_t02.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A03_t03.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A03_t04.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A03_t05.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A03_t06.dart': null,
-
-    'co19/src/Language/07_Classes/1_Instance_Methods_A05_t01.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A05_t02.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A05_t04.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A05_t05.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A05_t06.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A05_t07.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A05_t08.dart': null,
   // Getters.
-    'co19/src/Language/07_Classes/2_Getters_A05_t01.dart': null,
-    'co19/src/Language/07_Classes/2_Getters_A05_t02.dart': null,
-    'co19/src/Language/07_Classes/2_Getters_A05_t03.dart': null,
-    'co19/src/Language/07_Classes/2_Getters_A05_t04.dart': null,
+    'co19/src/Language/Classes/Getters/override_t01.dart': null,
+    'co19/src/Language/Classes/Getters/override_t02.dart': null,
+    'co19/src/Language/Classes/Getters/override_t03.dart': null,
+    'co19/src/Language/Classes/Getters/override_t04.dart': null,
 };
 
 void main() {
diff --git a/tests/compiler/dart2js/closure_tracer_test.dart b/tests/compiler/dart2js/closure_tracer_test.dart
index 8053c01..86d1e2f 100644
--- a/tests/compiler/dart2js/closure_tracer_test.dart
+++ b/tests/compiler/dart2js/closure_tracer_test.dart
@@ -153,7 +153,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesTask = compiler.typesTask;
     var typesInferrer = typesTask.typesInferrer;
 
diff --git a/tests/compiler/dart2js/codegen_helper.dart b/tests/compiler/dart2js/codegen_helper.dart
index 36fadff..c99fc49 100644
--- a/tests/compiler/dart2js/codegen_helper.dart
+++ b/tests/compiler/dart2js/codegen_helper.dart
@@ -16,7 +16,7 @@
   var provider = new MemorySourceFileProvider({ 'main.dart': code });
   var handler = new FormattingDiagnosticHandler(provider);
 
-  Compiler compiler = new Compiler(provider,
+  CompilerImpl compiler = new CompilerImpl(provider,
                                    const NullCompilerOutput(),
                                    handler,
                                    libraryRoot,
diff --git a/tests/compiler/dart2js/compile_with_empty_libraries_test.dart b/tests/compiler/dart2js/compile_with_empty_libraries_test.dart
index b133d85..6f6a94a 100644
--- a/tests/compiler/dart2js/compile_with_empty_libraries_test.dart
+++ b/tests/compiler/dart2js/compile_with_empty_libraries_test.dart
@@ -14,5 +14,5 @@
   Uri uri = new Uri(scheme: 'source');
   MockCompiler compiler =
     new MockCompiler.internal(librariesOverride: (_) => '');
-  asyncTest(() => compiler.runCompiler(uri));
+  asyncTest(() => compiler.run(uri));
 }
diff --git a/tests/compiler/dart2js/compiler_helper.dart b/tests/compiler/dart2js/compiler_helper.dart
index d3ac2ac..e0a69f1 100644
--- a/tests/compiler/dart2js/compiler_helper.dart
+++ b/tests/compiler/dart2js/compiler_helper.dart
@@ -146,9 +146,10 @@
       expectedWarnings: expectedWarnings,
       outputProvider: outputCollector);
   compiler.diagnosticHandler = createHandler(compiler, code);
-  return compiler.runCompiler(uri).then((_) {
-    Expect.isFalse(compiler.compilationFailed,
-                   'Unexpected compilation error(s): ${compiler.errors}');
+  return compiler.run(uri).then((compilationSucceded) {
+    Expect.isTrue(compilationSucceded,
+                  'Unexpected compilation error(s): '
+                  '${compiler.diagnosticCollector.errors}');
     return outputCollector.getOutput('', 'js');
   });
 }
@@ -161,7 +162,7 @@
   MockCompiler compiler = compilerFor(code, uri,
       expectedErrors: expectedErrors,
       expectedWarnings: expectedWarnings);
-  return compiler.runCompiler(uri).then((_) {
+  return compiler.run(uri).then((_) {
     lego.Element element = findElement(compiler, name);
     return check(compiler, element);
   });
@@ -179,7 +180,7 @@
     compiler.registerSource(base.resolve(path), code);
   });
 
-  return compiler.runCompiler(mainUri).then((_) {
+  return compiler.run(mainUri).then((_) {
     return check(compiler);
   });
 }
@@ -200,7 +201,7 @@
   var sourceName = name;
   var element = compiler.mainApp.find(sourceName);
   if (element == null) {
-    element = compiler.backend.interceptorsLibrary.find(sourceName);
+    element = compiler.backend.helpers.interceptorsLibrary.find(sourceName);
   }
   if (element == null) {
     element = compiler.coreLibrary.find(sourceName);
diff --git a/tests/compiler/dart2js/compiler_test.dart b/tests/compiler/dart2js/compiler_test.dart
index 74f9b17..691b86b 100644
--- a/tests/compiler/dart2js/compiler_test.dart
+++ b/tests/compiler/dart2js/compiler_test.dart
@@ -62,7 +62,7 @@
     compiler.reporter.setOnWarning(
         (c, n, m) => Expect.equals(foo, compiler.currentElement));
     foo.computeType(compiler.resolution);
-    Expect.equals(1, compiler.warnings.length);
+    Expect.equals(1, compiler.diagnosticCollector.warnings.length);
   });
 }
 
diff --git a/tests/compiler/dart2js/concrete_type_inference_test.dart b/tests/compiler/dart2js/concrete_type_inference_test.dart
index 8a53a44..c245deb 100644
--- a/tests/compiler/dart2js/concrete_type_inference_test.dart
+++ b/tests/compiler/dart2js/concrete_type_inference_test.dart
@@ -11,7 +11,7 @@
                     check(compiler, element)) {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(code, uri);
-  return compiler.runCompiler(uri).then((_) {
+  return compiler.run(uri).then((_) {
     var element = findElement(compiler, name);
     check(compiler, element);
   });
diff --git a/tests/compiler/dart2js/dart2js.status b/tests/compiler/dart2js/dart2js.status
index 3b0aae1..ed4cdeb 100644
--- a/tests/compiler/dart2js/dart2js.status
+++ b/tests/compiler/dart2js/dart2js.status
@@ -6,8 +6,6 @@
 
 boolified_operator_test: Fail # Issue 8001
 
-async_await_js_transform_test/01: RuntimeError # Issue 23997
-
 # Don't mark these tests as failing. Instead, fix the errors/warnings that they
 # report or update the whitelist in the test-files to temporarily allow
 # digression.
@@ -37,6 +35,7 @@
 patch_test/bug: RuntimeError # Issue 21132
 
 http_test: Pass, Slow
+inference_stats_test: Pass, Slow
 
 # These tests are for the now-deleted dart2dart variant of the CPS IR.
 # We want to adapt them to test the JS variant of the CPS IR instead,
@@ -57,6 +56,8 @@
 exit_code_test: Skip # This tests requires checked mode.
 
 [ $checked ]
+analyze_dart2js_test: Pass, Slow
+analyze_unused_dart2js_test: Pass, Slow
 uri_retention_test: Pass, Slow
 deferred_mirrors_test: Pass, Slow
 mirror_final_field_inferrer2_test: Pass, Slow
diff --git a/tests/compiler/dart2js/deferred_load_mapping_test.dart b/tests/compiler/dart2js/deferred_load_mapping_test.dart
index 4cb51d13..34ba2e8 100644
--- a/tests/compiler/dart2js/deferred_load_mapping_test.dart
+++ b/tests/compiler/dart2js/deferred_load_mapping_test.dart
@@ -14,7 +14,7 @@
         memorySourceFiles: MEMORY_SOURCE_FILES,
         options: ['--deferred-map=deferred_map.json'],
         outputProvider: collector);
-    Compiler compiler = result.compiler;
+    CompilerImpl compiler = result.compiler;
     // Ensure a mapping file is output.
     Expect.isNotNull(
         collector.getOutput("deferred_map.json", "deferred_map"));
diff --git a/tests/compiler/dart2js/diagnose_ambiguous_test.dart b/tests/compiler/dart2js/diagnose_ambiguous_test.dart
index 09e8706..12e574c 100644
--- a/tests/compiler/dart2js/diagnose_ambiguous_test.dart
+++ b/tests/compiler/dart2js/diagnose_ambiguous_test.dart
@@ -17,17 +17,22 @@
       options: ['--analyze-all']);
 
     List<String> diagnostics = <String>[];
-    collector.messages.forEach((DiagnosticMessage message) {
+    collector.messages.forEach((CollectedMessage message) {
       if (message.kind == Diagnostic.VERBOSE_INFO) return;
       diagnostics.add(message.toString());
     });
     diagnostics.sort();
     var expected = [
-        "memory:exporter.dart:43:47:'hest' is defined here.:info",
-        "memory:library.dart:41:45:'hest' is defined here.:info",
-        "memory:main.dart:0:22:'hest' is imported here.:info",
-        "memory:main.dart:23:46:'hest' is imported here.:info",
-        "memory:main.dart:86:92:Duplicate import of 'hest'.:warning",
+        "MessageKind.AMBIGUOUS_LOCATION:"
+            "memory:exporter.dart:43:47:'hest' is defined here.:info",
+        "MessageKind.AMBIGUOUS_LOCATION:"
+            "memory:library.dart:41:45:'hest' is defined here.:info",
+        "MessageKind.DUPLICATE_IMPORT:"
+            "memory:main.dart:86:92:Duplicate import of 'hest'.:warning",
+        "MessageKind.IMPORTED_HERE:"
+            "memory:main.dart:0:22:'hest' is imported here.:info",
+        "MessageKind.IMPORTED_HERE:"
+            "memory:main.dart:23:46:'hest' is imported here.:info",
     ];
     Expect.listEquals(expected, diagnostics);
     Expect.isTrue(result.isSuccess);
diff --git a/tests/compiler/dart2js/diagnostic_helper.dart b/tests/compiler/dart2js/diagnostic_helper.dart
new file mode 100644
index 0000000..2fbdfcd5
--- /dev/null
+++ b/tests/compiler/dart2js/diagnostic_helper.dart
@@ -0,0 +1,149 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.test.diagnostic_helper;
+
+import 'dart:collection';
+
+import 'package:compiler/compiler_new.dart' show
+    CompilerDiagnostics,
+    Diagnostic;
+import 'package:compiler/src/diagnostics/messages.dart' show
+    Message,
+    MessageKind;
+import 'package:expect/expect.dart';
+
+class CollectedMessage {
+  final Message message;
+  final Uri uri;
+  final int begin;
+  final int end;
+  final String text;
+  final Diagnostic kind;
+
+  CollectedMessage(
+      this.message, this.uri, this.begin, this.end, this.text, this.kind);
+
+  MessageKind get messageKind => message.kind;
+
+  String toString() => '${message.kind}:$uri:$begin:$end:$text:$kind';
+}
+
+class DiagnosticCollector implements CompilerDiagnostics {
+  List<CollectedMessage> messages = <CollectedMessage>[];
+
+  void call(Uri uri, int begin, int end, String message, Diagnostic kind) {
+    throw '';
+    report(null, uri, begin, end, message, kind);
+  }
+
+  @override
+  void report(Message message,
+              Uri uri, int begin, int end, String text, Diagnostic kind) {
+    messages.add(new CollectedMessage(message, uri, begin, end, text, kind));
+  }
+
+  Iterable<CollectedMessage> filterMessagesByKinds(List<Diagnostic> kinds) {
+    return messages.where(
+      (CollectedMessage message) => kinds.contains(message.kind));
+  }
+
+  Iterable<CollectedMessage> get errors {
+    return filterMessagesByKinds([Diagnostic.ERROR]);
+  }
+
+  Iterable<CollectedMessage> get warnings {
+    return filterMessagesByKinds([Diagnostic.WARNING]);
+  }
+
+  Iterable<CollectedMessage> get hints {
+    return filterMessagesByKinds([Diagnostic.HINT]);
+  }
+
+  Iterable<CollectedMessage> get infos {
+    return filterMessagesByKinds([Diagnostic.INFO]);
+  }
+
+  Iterable<CollectedMessage> get crashes {
+    return filterMessagesByKinds([Diagnostic.CRASH]);
+  }
+
+  /// `true` if non-verbose messages has been collected.
+  bool get hasRegularMessages {
+    return messages.any((m) => m.kind != Diagnostic.VERBOSE_INFO);
+  }
+
+  void clear() {
+    messages.clear();
+  }
+}
+
+
+void compareWarningKinds(String text,
+                         List expectedWarnings,
+                         Iterable<CollectedMessage> foundWarnings) {
+  compareMessageKinds(text, expectedWarnings, foundWarnings, 'warning');
+}
+
+/// [expectedMessages] must be a list of either [MessageKind] or [CheckMessage].
+void compareMessageKinds(String text,
+                         List expectedMessages,
+                         Iterable<CollectedMessage> foundMessages,
+                         String kind) {
+  var fail = (message) => Expect.fail('$text: $message');
+  HasNextIterator expectedIterator =
+      new HasNextIterator(expectedMessages.iterator);
+  HasNextIterator<CollectedMessage> foundIterator =
+      new HasNextIterator(foundMessages.iterator);
+  while (expectedIterator.hasNext && foundIterator.hasNext) {
+    var expected = expectedIterator.next();
+    var found = foundIterator.next();
+    if (expected is MessageKind) {
+      Expect.equals(expected, found.message.kind);
+    } else if (expected is CheckMessage) {
+      String error = expected(found.message);
+      Expect.isNull(error, error);
+    } else {
+      Expect.fail("Unexpected $kind value: $expected.");
+    }
+  }
+  if (expectedIterator.hasNext) {
+    do {
+      var expected = expectedIterator.next();
+      if (expected is CheckMessage) expected = expected(null);
+      print('Expected $kind "${expected}" did not occur');
+    } while (expectedIterator.hasNext);
+    fail('Too few ${kind}s');
+  }
+  if (foundIterator.hasNext) {
+    do {
+      CollectedMessage message = foundIterator.next();
+      print('Additional $kind "${message}: ${message.message}"');
+    } while (foundIterator.hasNext);
+    fail('Too many ${kind}s');
+  }
+}
+
+/// A function the checks [message]. If the check fails or if [message] is
+/// `null`, an error string is returned. Otherwise `null` is returned.
+typedef String CheckMessage(Message message);
+
+CheckMessage checkMessage(MessageKind kind, Map arguments) {
+  return (Message message) {
+    if (message == null) return '$kind';
+    if (message.kind != kind) return 'Expected message $kind, found $message.';
+    for (var key in arguments.keys) {
+      if (!message.arguments.containsKey(key)) {
+        return 'Expected argument $key not found in $message.kind.';
+      }
+      String expectedValue = '${arguments[key]}';
+      String foundValue = '${message.arguments[key]}';
+      if (expectedValue != foundValue) {
+        return 'Expected argument $key with value $expectedValue, '
+               'found $foundValue.';
+      }
+    }
+    return null;
+  };
+}
diff --git a/tests/compiler/dart2js/duplicate_library_test.dart b/tests/compiler/dart2js/duplicate_library_test.dart
index 80aa6fe..5a2a708 100644
--- a/tests/compiler/dart2js/duplicate_library_test.dart
+++ b/tests/compiler/dart2js/duplicate_library_test.dart
@@ -13,13 +13,13 @@
 import 'memory_compiler.dart';
 
 void check(String kind,
-           Iterable<DiagnosticMessage> messages,
+           Iterable<CollectedMessage> messages,
            List<MessageKind> expectedMessageKinds) {
   Expect.equals(messages.length, expectedMessageKinds.length,
       "Unexpected $kind count: $messages");
   int i = 0;
-  messages.forEach((DiagnosticMessage message) {
-    Expect.equals(expectedMessageKinds[i++], message.message.kind);
+  messages.forEach((CollectedMessage message) {
+    Expect.equals(expectedMessageKinds[i++], message.messageKind);
   });
 }
 
diff --git a/tests/compiler/dart2js/exit_code_test.dart b/tests/compiler/dart2js/exit_code_test.dart
index ff03975..e5263e4 100644
--- a/tests/compiler/dart2js/exit_code_test.dart
+++ b/tests/compiler/dart2js/exit_code_test.dart
@@ -29,9 +29,10 @@
 import 'package:compiler/src/old_to_new_api.dart';
 import 'package:compiler/src/resolution/resolution.dart';
 import 'package:compiler/src/scanner/scanner_task.dart';
+import 'package:compiler/src/universe/world_impact.dart';
 import 'diagnostic_reporter_helper.dart';
 
-class TestCompiler extends apiimpl.Compiler {
+class TestCompiler extends apiimpl.CompilerImpl {
   final String testMarker;
   final String testType;
   final Function onTest;
diff --git a/tests/compiler/dart2js/expect_annotations_test.dart b/tests/compiler/dart2js/expect_annotations_test.dart
index 62e29ae..7c4605a 100644
--- a/tests/compiler/dart2js/expect_annotations_test.dart
+++ b/tests/compiler/dart2js/expect_annotations_test.dart
@@ -105,8 +105,8 @@
 
     TypeMask jsStringType = compiler.typesTask.stringType;
     TypeMask jsIntType = compiler.typesTask.intType;
-    TypeMask coreStringType = new TypeMask.subtype(compiler.stringClass,
-        compiler.world);
+    TypeMask coreStringType = new TypeMask.subtype(
+        compiler.coreClasses.stringClass, compiler.world);
 
     test('method');
     test('methodAssumeDynamic', expectAssumeDynamic: true);
diff --git a/tests/compiler/dart2js/field_type_simple_inferer_test.dart b/tests/compiler/dart2js/field_type_simple_inferer_test.dart
index 2a33d95..7eeb5f9 100644
--- a/tests/compiler/dart2js/field_type_simple_inferer_test.dart
+++ b/tests/compiler/dart2js/field_type_simple_inferer_test.dart
@@ -17,7 +17,7 @@
                     check(compiler, element)) {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(code, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     compiler.disableInlining = disableInlining;
     var cls = findElement(compiler, className);
     var member = cls.lookupMember(memberName);
@@ -531,7 +531,7 @@
   runTest(TEST_14, {'f': (types) => types.uint31Type});
   runTest(TEST_15, {'f': (types) {
                             ClassElement cls =
-                                types.compiler.backend.jsIndexableClass;
+                                types.compiler.backend.helpers.jsIndexableClass;
                             return new TypeMask.nonNullSubtype(cls,
                                 types.compiler.world);
                          }});
diff --git a/tests/compiler/dart2js/gvn_dynamic_field_get_test.dart b/tests/compiler/dart2js/gvn_dynamic_field_get_test.dart
index 350dcc4..7ceb6a1 100644
--- a/tests/compiler/dart2js/gvn_dynamic_field_get_test.dart
+++ b/tests/compiler/dart2js/gvn_dynamic_field_get_test.dart
@@ -25,7 +25,7 @@
 main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     String generated = compiler.assembledCode;
     RegExp regexp = new RegExp(r"get\$foo");
     Iterator matches = regexp.allMatches(generated).iterator;
diff --git a/tests/compiler/dart2js/incremental/compile_all.dart b/tests/compiler/dart2js/incremental/compile_all.dart
index a89ec32..9d62061 100644
--- a/tests/compiler/dart2js/incremental/compile_all.dart
+++ b/tests/compiler/dart2js/incremental/compile_all.dart
@@ -18,7 +18,7 @@
     FormattingDiagnosticHandler;
 
 import '../memory_source_file_helper.dart' show
-    Compiler;
+    CompilerImpl;
 
 import '../memory_compiler.dart' show
     compilerFor;
@@ -43,7 +43,7 @@
   int testCount = 0;
   int skipCount = 0;
   Set<String> crashes = new Set<String>();
-  Compiler memoryCompiler = compilerFor(memorySourceFiles: sources);
+  CompilerImpl memoryCompiler = compilerFor(memorySourceFiles: sources);
   FormattingDiagnosticHandler handler = memoryCompiler.handler;
   handler.verbose = verbose;
   var options = ['--analyze-main'];
diff --git a/tests/compiler/dart2js/issue13354_test.dart b/tests/compiler/dart2js/issue13354_test.dart
index 3402206..c275bfe 100644
--- a/tests/compiler/dart2js/issue13354_test.dart
+++ b/tests/compiler/dart2js/issue13354_test.dart
@@ -28,7 +28,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesTask = compiler.typesTask;
     var typesInferrer = typesTask.typesInferrer;
 
diff --git a/tests/compiler/dart2js/js_backend_cps_ir.dart b/tests/compiler/dart2js/js_backend_cps_ir.dart
index 95852f1..b5f395a 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir.dart
@@ -8,7 +8,7 @@
 import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
 import 'package:compiler/src/apiimpl.dart' show
-    Compiler;
+    CompilerImpl;
 import 'memory_compiler.dart';
 import 'package:compiler/src/js/js.dart' as js;
 import 'package:compiler/src/elements/elements.dart' show
@@ -33,13 +33,13 @@
   return test[TEST_MAIN_FILE];
 }
 
-String getCodeForMain(Compiler compiler) {
+String getCodeForMain(CompilerImpl compiler) {
   Element mainFunction = compiler.mainFunction;
   js.Node ast = compiler.enqueuer.codegen.generatedCode[mainFunction];
   return js.prettyPrint(ast, compiler).getText();
 }
 
-String getCodeForMethod(Compiler compiler,
+String getCodeForMethod(CompilerImpl compiler,
                         String name) {
   Element foundElement;
   for (Element element in compiler.enqueuer.codegen.generatedCode.keys) {
@@ -70,7 +70,7 @@
             memorySourceFiles: files,
             options: <String>['--use-cps-ir']);
         Expect.isTrue(result.isSuccess);
-        Compiler compiler = result.compiler;
+        CompilerImpl compiler = result.compiler;
         String expectation = test.expectation;
         if (expectation != null) {
           String expected = test.expectation;
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_closures_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_closures_test.dart
index 820be3e..be1bd40 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_closures_test.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_closures_test.dart
@@ -36,8 +36,8 @@
 r"""
 function(x) {
   var _box_0 = {}, a = new V.main_a(_box_0);
-  _box_0._captured_x_0 = x;
-  _box_0._captured_x_0 = J.getInterceptor$ns(x = _box_0._captured_x_0).$add(x, "1");
+  _box_0.x = x;
+  _box_0.x = J.getInterceptor$ns(x = _box_0.x).$add(x, "1");
   P.print(a.call$0());
   return a;
 }"""),
@@ -96,8 +96,8 @@
 r"""
 function() {
   var _box_0 = {}, a = new V.main_closure(_box_0);
-  _box_0._captured_x_0 = 122;
-  _box_0._captured_x_0 = _box_0._captured_x_0 + 1;
+  _box_0.x = 122;
+  _box_0.x = _box_0.x + 1;
   P.print(a.call$0());
   return a;
 }"""),
@@ -133,8 +133,8 @@
 r"""
 function() {
   var _box_0 = {}, a = new V.main_closure(_box_0);
-  _box_0._captured_x_0 = 122;
-  _box_0._captured_x_0 = _box_0._captured_x_0 + 1;
+  _box_0.x = 122;
+  _box_0.x = _box_0.x + 1;
   P.print(a.call$0().call$0());
   return a;
 }"""),
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_constructor_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_constructor_test.dart
index b724218..ec45a16 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_constructor_test.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_constructor_test.dart
@@ -96,7 +96,7 @@
 r"""
 function(x, y) {
   var _box_0 = {}, v0 = new V.Sub(y, new V.Base_closure(_box_0));
-  _box_0._captured_x1_0 = x;
+  _box_0.x1 = x;
   v0.Base0$0();
   v0.Base$1(_box_0);
   v0.Sub$2(x, y);
@@ -216,7 +216,7 @@
 }"""),
 
 
-const TestEntry.forMethod('function(Foo#make)', r"""
+const TestEntry.forMethod('factory_constructor(Foo#make)', r"""
 class Foo {
   factory Foo.make(x) {
     print('Foo');
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_control_flow_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_control_flow_test.dart
index 2365d4f..2d9e07e 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_control_flow_test.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_control_flow_test.dart
@@ -138,12 +138,9 @@
   }
 }""",r"""
 function() {
-  var list = [1, 2, 3, 4, 5, 6], $length = list.length, i = 0;
-  for (; i < list.length; i = i + 1) {
+  var list = [1, 2, 3, 4, 5, 6], i = 0;
+  for (; i < 6; i = i + 1)
     P.print(list[i]);
-    if ($length !== list.length)
-      H.throwConcurrentModificationError(list);
-  }
 }"""),
   const TestEntry("""
 main() {
@@ -155,18 +152,14 @@
   }
 }""",r"""
 function() {
-  var xs = ["x", "y", "z"], ys = ["A", "B", "C"], $length = xs.length, length1 = ys.length, i = 0, i1 = 0, current, current1;
-  for (; i < xs.length; i = i + 1, i1 = i1 + 1) {
+  var xs = ["x", "y", "z"], ys = ["A", "B", "C"], i = 0, i1 = 0, current, current1;
+  for (; i < 3; i = i + 1, i1 = i1 + 1) {
     current = xs[i];
-    if (length1 !== ys.length)
-      H.throwConcurrentModificationError(ys);
-    if (!(i1 < ys.length))
+    if (!(i1 < 3))
       break;
     current1 = ys[i1];
     P.print(current);
     P.print(current1);
-    if ($length !== xs.length)
-      H.throwConcurrentModificationError(xs);
   }
 }"""),
 ];
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_interceptors_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_interceptors_test.dart
index 947d919..4de37b1 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_interceptors_test.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_interceptors_test.dart
@@ -33,14 +33,11 @@
 }""",
 r"""
 function() {
-  var l = ["hest", ["h", "e", "s", "t"]], i = 0, x_, x, j;
-  for (P.print(l.length); i < l.length; i = i + 1) {
-    x_ = J.getInterceptor$as(x = l[i]);
-    for (j = 0; j < x_.get$length(x); j = j + 1) {
-      if (j >= x.length)
-        H.ioore(x, j);
+  var l = ["hest", ["h", "e", "s", "t"]], i = 0, x, j;
+  for (P.print(2); i < 2; i = i + 1) {
+    x = l[i];
+    for (j = 0; j < x.length; j = j + 1)
       P.print(x[j]);
-    }
   }
 }"""),
 ];
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_operators2_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_operators2_test.dart
new file mode 100644
index 0000000..1ced961
--- /dev/null
+++ b/tests/compiler/dart2js/js_backend_cps_ir_operators2_test.dart
@@ -0,0 +1,105 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests of operators.
+
+library operators_tests;
+
+import 'js_backend_cps_ir.dart';
+
+const List<TestEntry> tests = const [
+
+  const TestEntry.forMethod('function(foo)',
+      r"""
+foo(a, b) => ((a & 0xff0000) >> 1) & b;
+main() {
+  print(foo(123, 234));
+  print(foo(0, 2));
+}""", r"""
+function(a, b) {
+  return (a & 16711680) >>> 1 & b;
+}"""),
+
+  const TestEntry.forMethod('function(foo)',
+      r"""
+foo(a) => ~a;
+main() {
+  print(foo(1));
+  print(foo(10));
+}""", r"""
+function(a) {
+  return ~a >>> 0;
+}"""),
+
+  const TestEntry.forMethod('function(foo)',
+      r"""
+foo(a) => a % 13;
+main() {
+  print(foo(5));
+  print(foo(-100));
+}""", r"""
+function(a) {
+  return C.JSInt_methods.$mod(a, 13);
+}"""),
+
+  const TestEntry.forMethod('function(foo)',
+      r"""
+foo(a) => a % 13;
+main() {
+  print(foo(5));
+  print(foo(100));
+}""", r"""
+function(a) {
+  return a % 13;
+}"""),
+
+  const TestEntry.forMethod('function(foo)',
+      r"""
+foo(a) => a.remainder(13);
+main() {
+  print(foo(5));
+  print(foo(-100));
+}""", r"""
+function(a) {
+  return a % 13;
+}"""),
+
+  const TestEntry.forMethod('function(foo)',
+      r"""
+foo(a) => a ~/ 13;
+main() {
+  print(foo(5));
+  print(foo(-100));
+}""", r"""
+function(a) {
+  return C.JSInt_methods.$tdiv(a, 13);
+}"""),
+
+  const TestEntry.forMethod('function(foo)',
+      r"""
+foo(a) => a ~/ 13;
+main() {
+  print(foo(5));
+  print(foo(100));
+}""", r"""
+function(a) {
+  return a / 13 | 0;
+}"""),
+
+  const TestEntry.forMethod('function(foo)',
+      r"""
+foo(a) => a ~/ 13;
+main() {
+  print(foo(5));
+  print(foo(8000000000));
+}""", r"""
+function(a) {
+  return C.JSInt_methods.$tdiv(a, 13);
+}"""),
+
+];
+
+void main() {
+  runTests(tests);
+}
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_source_information_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_source_information_test.dart
index bbfbdd6..db46dcbf 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_source_information_test.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_source_information_test.dart
@@ -9,7 +9,7 @@
 import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
 import 'package:compiler/src/apiimpl.dart'
-       show Compiler;
+       show CompilerImpl;
 import 'memory_compiler.dart';
 import 'package:compiler/src/cps_ir/cps_ir_nodes.dart' as ir;
 import 'package:compiler/src/cps_ir/cps_ir_nodes_sexpr.dart' as ir;
@@ -34,16 +34,16 @@
   return test[TEST_MAIN_FILE];
 }
 
-js.Node getCodeForMain(Compiler compiler) {
+js.Node getCodeForMain(CompilerImpl compiler) {
   Element mainFunction = compiler.mainFunction;
   return compiler.enqueuer.codegen.generatedCode[mainFunction];
 }
 
-js.Node getJsNodeForElement(Compiler compiler, Element element) {
+js.Node getJsNodeForElement(CompilerImpl compiler, Element element) {
   return compiler.enqueuer.codegen.generatedCode[element];
 }
 
-String getCodeForMethod(Compiler compiler, String name) {
+String getCodeForMethod(CompilerImpl compiler, String name) {
   Element foundElement;
   for (Element element in compiler.enqueuer.codegen.generatedCode.keys) {
     if (element.toString() == name) {
@@ -66,7 +66,7 @@
   for (TestEntry test in tests) {
     Map files = {TEST_MAIN_FILE: test.source};
     asyncTest(() {
-      Compiler compiler = compilerFor(
+      CompilerImpl compiler = compilerFor(
           memorySourceFiles: files, options: <String>['--use-cps-ir']);
       ir.FunctionDefinition irNodeForMain;
 
diff --git a/tests/compiler/dart2js/js_constant_test.dart b/tests/compiler/dart2js/js_constant_test.dart
new file mode 100644
index 0000000..6165cfa
--- /dev/null
+++ b/tests/compiler/dart2js/js_constant_test.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+import 'compiler_helper.dart';
+
+const String TEST_1 = r"""
+  import 'dart:_foreign_helper';
+  main() {
+    JS('', '#.toString()', -5);
+    // absent: "5.toString"
+    // present: "(-5).toString"
+  }
+""";
+
+
+main() {
+  RegExp directivePattern = new RegExp(
+      //      \1                    \2        \3
+      r'''// *(present|absent): (?:"([^"]*)"|'([^'']*)')''',
+      multiLine: true);
+
+  Future check(String test) {
+    Uri uri = new Uri(scheme: 'dart', path: 'test');
+    var compiler = compilerFor(test, uri, expectedErrors: 0);
+    return compiler.run(uri).then((_) {
+      var element = findElement(compiler, 'main');
+      var backend = compiler.backend;
+      String generated = backend.getGeneratedCode(element);
+
+      for (Match match in directivePattern.allMatches(test)) {
+        String directive = match.group(1);
+        String pattern = match.groups([2, 3]).where((s) => s != null).single;
+        if (directive == 'present') {
+          Expect.isTrue(generated.contains(pattern),
+              "Cannot find '$pattern' in:\n$generated");
+        } else {
+          assert(directive == 'absent');
+          Expect.isFalse(generated.contains(pattern),
+              "Must not find '$pattern' in:\n$generated");
+        }
+      }
+    });
+  }
+
+  asyncTest(() => Future.wait([
+    check(TEST_1),
+  ]));
+}
diff --git a/tests/compiler/dart2js/js_spec_optimization_test.dart b/tests/compiler/dart2js/js_spec_optimization_test.dart
index 8c83b3b..3c03c09 100644
--- a/tests/compiler/dart2js/js_spec_optimization_test.dart
+++ b/tests/compiler/dart2js/js_spec_optimization_test.dart
@@ -67,7 +67,7 @@
   Future check(String test) {
     Uri uri = new Uri(scheme: 'dart', path: 'test');
     var compiler = compilerFor(test, uri, expectedErrors: 0);
-    return compiler.runCompiler(uri).then((_) {
+    return compiler.run(uri).then((_) {
       var element = findElement(compiler, 'main');
       var backend = compiler.backend;
       String generated = backend.getGeneratedCode(element);
diff --git a/tests/compiler/dart2js/library_resolution_test.dart b/tests/compiler/dart2js/library_resolution_test.dart
index 3d6c035..28ad567 100644
--- a/tests/compiler/dart2js/library_resolution_test.dart
+++ b/tests/compiler/dart2js/library_resolution_test.dart
@@ -14,92 +14,58 @@
 
 import "package:async_helper/async_helper.dart";
 
-import 'package:expect/expect.dart' show
-    Expect;
+import 'package:expect/expect.dart' show Expect;
 
-import 'package:compiler/src/diagnostics/messages.dart' show
-    MessageKind,
-    MessageTemplate;
+import 'package:compiler/src/diagnostics/messages.dart'
+    show MessageKind, MessageTemplate;
 
-import 'package:compiler/src/elements/elements.dart' show
-    LibraryElement;
+import 'package:compiler/src/elements/elements.dart' show LibraryElement;
 
-import 'package:compiler/src/null_compiler_output.dart' show
-    NullCompilerOutput;
+import 'package:compiler/src/null_compiler_output.dart' show NullCompilerOutput;
 
-import 'package:compiler/src/old_to_new_api.dart' show
-    LegacyCompilerDiagnostics,
-    LegacyCompilerInput;
+import 'package:compiler/src/old_to_new_api.dart'
+    show LegacyCompilerDiagnostics, LegacyCompilerInput;
 
-import 'package:sdk_library_metadata/libraries.dart' show
-    DART2JS_PLATFORM,
-    LibraryInfo;
+Uri sdkRoot = Uri.base.resolve("sdk/");
+Uri mock1LibraryUri = sdkRoot.resolve("lib/mock1.dart");
+Uri mock2LibraryUri = sdkRoot.resolve("lib/mock2.dart");
 
-const LibraryInfo mock1LibraryInfo = const LibraryInfo(
-    "mock1.dart",
-    categories: "Client,Embedded",
-    documented: false,
-    platforms: DART2JS_PLATFORM);
+class CustomCompiler extends CompilerImpl {
+  CustomCompiler(provider, handler, libraryRoot,
+      packageRoot, options, environment)
+      : super(provider, const NullCompilerOutput(), handler, libraryRoot,
+            packageRoot, options, environment);
 
-const LibraryInfo mock2LibraryInfo = const LibraryInfo(
-    "mock2.dart",
-    categories: "Client,Embedded",
-    documented: false,
-    platforms: DART2JS_PLATFORM);
-
-
-class CustomCompiler extends Compiler {
-  final Map<String, LibraryInfo> customLibraryInfo;
-
-  CustomCompiler(
-      this.customLibraryInfo,
-      provider,
-      handler,
-      libraryRoot,
-      packageRoot,
-      options,
-      environment)
-      : super(
-          provider,
-          const NullCompilerOutput(),
-          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);
+  Uri lookupLibraryUri(String libraryName) {
+    if (libraryName == "m_o_c_k_1") return mock1LibraryUri;
+    if (libraryName == "m_o_c_k_2") return mock2LibraryUri;
+    return super.lookupLibraryUri(libraryName);
   }
 }
 
-main() {
-  Uri sdkRoot = Uri.base.resolve("sdk/");
+main() async {
   Uri packageRoot = Uri.base.resolve(Platform.packageRoot);
 
   var provider = new MemorySourceFileProvider(MEMORY_SOURCE_FILES);
   var handler = new FormattingDiagnosticHandler(provider);
 
   Future wrappedProvider(Uri uri) {
-    if (uri == sdkRoot.resolve('lib/mock1.dart')) {
+    if (uri == mock1LibraryUri) {
       return provider.readStringFromUri(Uri.parse('memory:mock1.dart'));
     }
-    if (uri == sdkRoot.resolve('lib/mock2.dart')) {
+    if (uri == mock2LibraryUri) {
       return provider.readStringFromUri(Uri.parse('memory:mock2.dart'));
     }
     return provider.readStringFromUri(uri);
   }
 
-  String expectedMessage =
-      MessageTemplate.TEMPLATES[MessageKind.LIBRARY_NOT_FOUND].message(
-          {'resolvedUri': 'dart:mock2.dart'}).computeMessage();
+  String expectedMessage = MessageTemplate.TEMPLATES[
+          MessageKind.LIBRARY_NOT_FOUND]
+      .message({'resolvedUri': 'dart:mock2.dart'}).computeMessage();
 
   int actualMessageCount = 0;
 
-  wrappedHandler(
-      Uri uri, int begin, int end, String message, kind) {
+  wrappedHandler(Uri uri, int begin, int end, String message, kind) {
     if (message == expectedMessage) {
       actualMessageCount++;
     } else {
@@ -111,8 +77,7 @@
     Expect.equals(1, actualMessageCount);
   }
 
-  Compiler compiler = new CustomCompiler(
-      {},
+  CompilerImpl compiler = new CustomCompiler(
       new LegacyCompilerInput(wrappedProvider),
       new LegacyCompilerDiagnostics(wrappedHandler),
       sdkRoot,
@@ -121,9 +86,11 @@
       {});
 
   asyncStart();
-  compiler.libraryLoader.loadLibrary(Uri.parse("dart:m_o_c_k_1"))
-      .then(checkLibrary)
-      .then(asyncSuccess);
+  await compiler.setupSdk();
+  var library =
+      await compiler.libraryLoader.loadLibrary(Uri.parse("dart:m_o_c_k_1"));
+  await checkLibrary(library);
+  asyncSuccess(null);
 }
 
 const Map MEMORY_SOURCE_FILES = const {
diff --git a/tests/compiler/dart2js/list_tracer2_test.dart b/tests/compiler/dart2js/list_tracer2_test.dart
index 5c60954..76ee4b5a 100644
--- a/tests/compiler/dart2js/list_tracer2_test.dart
+++ b/tests/compiler/dart2js/list_tracer2_test.dart
@@ -24,7 +24,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkType(String name, type) {
diff --git a/tests/compiler/dart2js/list_tracer3_test.dart b/tests/compiler/dart2js/list_tracer3_test.dart
index e9decd9..3ef45d2 100644
--- a/tests/compiler/dart2js/list_tracer3_test.dart
+++ b/tests/compiler/dart2js/list_tracer3_test.dart
@@ -27,7 +27,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkType(String name, type) {
diff --git a/tests/compiler/dart2js/list_tracer_test.dart b/tests/compiler/dart2js/list_tracer_test.dart
index d6edb88..24d7ae0 100644
--- a/tests/compiler/dart2js/list_tracer_test.dart
+++ b/tests/compiler/dart2js/list_tracer_test.dart
@@ -198,7 +198,7 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(generateTest(allocation), uri,
       expectedErrors: 0, expectedWarnings: 1);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesTask = compiler.typesTask;
     var typesInferrer = typesTask.typesInferrer;
 
diff --git a/tests/compiler/dart2js/map_tracer_const_test.dart b/tests/compiler/dart2js/map_tracer_const_test.dart
index 8389de6..1365349 100644
--- a/tests/compiler/dart2js/map_tracer_const_test.dart
+++ b/tests/compiler/dart2js/map_tracer_const_test.dart
@@ -33,7 +33,7 @@
   var compiler = compilerFor(TEST, uri,
       expectedErrors: 0, expectedWarnings: 0);
   compiler.stopAfterTypeInference = true;
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesTask = compiler.typesTask;
     var typesInferrer = typesTask.typesInferrer;
     var element = findElement(compiler, 'closure');
diff --git a/tests/compiler/dart2js/map_tracer_keys_test.dart b/tests/compiler/dart2js/map_tracer_keys_test.dart
index 0c2edb7..da6f9fa 100644
--- a/tests/compiler/dart2js/map_tracer_keys_test.dart
+++ b/tests/compiler/dart2js/map_tracer_keys_test.dart
@@ -54,7 +54,7 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(generateTest(key, value, initial), uri,
       expectedErrors: 0, expectedWarnings: 0);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesTask = compiler.typesTask;
     var typesInferrer = typesTask.typesInferrer;
     var aDoubleType =
diff --git a/tests/compiler/dart2js/map_tracer_test.dart b/tests/compiler/dart2js/map_tracer_test.dart
index c45370a..d7aa366 100644
--- a/tests/compiler/dart2js/map_tracer_test.dart
+++ b/tests/compiler/dart2js/map_tracer_test.dart
@@ -215,7 +215,7 @@
   var compiler = compilerFor(generateTest(allocation), uri,
       expectedErrors: 0, expectedWarnings: 1);
   var classWorld = compiler.world;
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var keyType, valueType;
     var typesTask = compiler.typesTask;
     var typesInferrer = typesTask.typesInferrer;
diff --git a/tests/compiler/dart2js/members_test.dart b/tests/compiler/dart2js/members_test.dart
index d4be7ab..59dbf97 100644
--- a/tests/compiler/dart2js/members_test.dart
+++ b/tests/compiler/dart2js/members_test.dart
@@ -12,7 +12,7 @@
        show Element, ClassElement, MemberSignature, Name, PublicName,
             DeclaredMember, Member;
 import "package:compiler/src/resolution/class_members.dart"
-  show DeclaredMember, ErroneousMember, SyntheticMember;
+  show MembersCreator, DeclaredMember, ErroneousMember, SyntheticMember;
 
 void main() {
   testClassMembers();
@@ -212,6 +212,8 @@
                 functionType: env.functionType(String_, []));
 
     InterfaceType A = env['A'];
+    MembersCreator.computeAllClassMembers(env.compiler, A.element);
+
     checkMemberCount(A, 5 /*inherited*/ + 9 /*non-static declared*/,
                      interfaceMembers: true);
     checkMemberCount(A, 5 /*inherited*/ + 9 /*non-abstract declared*/ +
@@ -255,6 +257,7 @@
                 isStatic: true, functionType: env.functionType(dynamic_, []));
 
     ClassElement B = env.getElement('B');
+    MembersCreator.computeAllClassMembers(env.compiler, B);
     InterfaceType B_this = B.thisType;
     TypeVariableType B_T = B_this.typeArguments.first;
     checkMemberCount(B_this, 4 /*inherited*/ + 4 /*non-static declared*/,
@@ -280,6 +283,7 @@
                                                optionalParameters: [B_T]));
 
     ClassElement C = env.getElement('C');
+    MembersCreator.computeAllClassMembers(env.compiler, C);
     InterfaceType C_this = C.thisType;
     TypeVariableType C_S = C_this.typeArguments.first;
     checkMemberCount(C_this, 8 /*inherited*/, interfaceMembers: true);
@@ -306,6 +310,7 @@
                                                optionalParameters: [C_S]));
 
     InterfaceType D = env['D'];
+    MembersCreator.computeAllClassMembers(env.compiler, D.element);
     checkMemberCount(D, 8 /*inherited*/, interfaceMembers: true);
     checkMemberCount(D, 8 /*inherited*/, interfaceMembers: false);
     InterfaceType B_int = instantiate(B, [int_]);
@@ -330,6 +335,7 @@
                                                optionalParameters: [int_]));
 
     InterfaceType E = env['E'];
+    MembersCreator.computeAllClassMembers(env.compiler, E.element);
     checkMemberCount(E, 8 /*inherited*/, interfaceMembers: true);
     checkMemberCount(E, 8 /*inherited*/, interfaceMembers: false);
 
@@ -411,6 +417,9 @@
     InterfaceType C = env['C'];
     InterfaceType D = env['D'];
 
+    // Ensure that members have been computed on all classes.
+    MembersCreator.computeAllClassMembers(env.compiler, D.element);
+
     // A: num method1()
     // B: int method1()
     // D: dynamic method1() -- synthesized from A and B.
@@ -576,6 +585,9 @@
     InterfaceType B = env['B'];
     InterfaceType C = env['C'];
 
+    // Ensure that members have been computed on all classes.
+    MembersCreator.computeAllClassMembers(env.compiler, C.element);
+
     // A: method1()
     // B: method1()
     // C class: method1() -- inherited from A.
@@ -634,6 +646,9 @@
     InterfaceType A_U = instantiate(A, [C_U]);
     InterfaceType B_V = instantiate(B, [C_V]);
 
+    // Ensure that members have been computed on all classes.
+    MembersCreator.computeAllClassMembers(env.compiler, C);
+
     // A: method1()
     // B: method1()
     // C class: method1() -- inherited from A.
@@ -702,6 +717,9 @@
     InterfaceType B = env['B'];
     InterfaceType C = env['C'];
 
+    // Ensure that members have been computed on all classes.
+    MembersCreator.computeAllClassMembers(env.compiler, C.element);
+
     checkMember(C, 'm', checkType: NO_CLASS_MEMBER,
                 inheritedFrom: A,
                 functionType: env.functionType(dynamic_ , []));
diff --git a/tests/compiler/dart2js/memory_compiler.dart b/tests/compiler/dart2js/memory_compiler.dart
index be6780f..8d788f6 100644
--- a/tests/compiler/dart2js/memory_compiler.dart
+++ b/tests/compiler/dart2js/memory_compiler.dart
@@ -28,64 +28,7 @@
 export 'output_collector.dart';
 export 'package:compiler/compiler_new.dart' show
     CompilationResult;
-
-class DiagnosticMessage {
-  final Message message;
-  final Uri uri;
-  final int begin;
-  final int end;
-  final String text;
-  final Diagnostic kind;
-
-  DiagnosticMessage(
-      this.message, this.uri, this.begin, this.end, this.text, this.kind);
-
-  String toString() => '$uri:$begin:$end:$text:$kind';
-}
-
-class DiagnosticCollector implements CompilerDiagnostics {
-  List<DiagnosticMessage> messages = <DiagnosticMessage>[];
-
-  void call(Uri uri, int begin, int end, String message, Diagnostic kind) {
-    report(null, uri, begin, end, message, kind);
-  }
-
-  @override
-  void report(Message message,
-              Uri uri, int begin, int end, String text, Diagnostic kind) {
-    messages.add(new DiagnosticMessage(message, uri, begin, end, text, kind));
-  }
-
-  Iterable<DiagnosticMessage> filterMessagesByKinds(List<Diagnostic> kinds) {
-    return messages.where(
-      (DiagnosticMessage message) => kinds.contains(message.kind));
-  }
-
-  Iterable<DiagnosticMessage> get errors {
-    return filterMessagesByKinds([Diagnostic.ERROR]);
-  }
-
-  Iterable<DiagnosticMessage> get warnings {
-    return filterMessagesByKinds([Diagnostic.WARNING]);
-  }
-
-  Iterable<DiagnosticMessage> get hints {
-    return filterMessagesByKinds([Diagnostic.HINT]);
-  }
-
-  Iterable<DiagnosticMessage> get infos {
-    return filterMessagesByKinds([Diagnostic.INFO]);
-  }
-
-  /// `true` if non-verbose messages has been collected.
-  bool get hasRegularMessages {
-    return messages.any((m) => m.kind != Diagnostic.VERBOSE_INFO);
-  }
-
-  void clear() {
-    messages.clear();
-  }
-}
+export 'diagnostic_helper.dart';
 
 class MultiDiagnostics implements CompilerDiagnostics {
   final List<CompilerDiagnostics> diagnosticsList;
@@ -131,16 +74,16 @@
      CompilerDiagnostics diagnosticHandler,
      CompilerOutput outputProvider,
      List<String> options: const <String>[],
-     Compiler cachedCompiler,
+     CompilerImpl cachedCompiler,
      bool showDiagnostics: true,
      Uri packageRoot,
      Uri packageConfig,
      PackagesDiscoveryProvider packagesDiscoveryProvider,
-     void beforeRun(Compiler compiler)}) async {
+     void beforeRun(CompilerImpl compiler)}) async {
   if (entryPoint == null) {
     entryPoint = Uri.parse('memory:main.dart');
   }
-  Compiler compiler = compilerFor(
+  CompilerImpl compiler = compilerFor(
       memorySourceFiles: memorySourceFiles,
       diagnosticHandler: diagnosticHandler,
       outputProvider: outputProvider,
@@ -158,12 +101,12 @@
   return new CompilationResult(compiler, isSuccess: isSuccess);
 }
 
-Compiler compilerFor(
+CompilerImpl compilerFor(
     {Map<String, String> memorySourceFiles: const <String, String>{},
      CompilerDiagnostics diagnosticHandler,
      CompilerOutput outputProvider,
      List<String> options: const <String>[],
-     Compiler cachedCompiler,
+     CompilerImpl cachedCompiler,
      bool showDiagnostics: true,
      Uri packageRoot,
      Uri packageConfig,
@@ -196,7 +139,7 @@
     outputProvider = const NullCompilerOutput();
   }
 
-  Compiler compiler = new Compiler(
+  CompilerImpl compiler = new CompilerImpl(
       provider,
       outputProvider,
       diagnosticHandler,
diff --git a/tests/compiler/dart2js/memory_source_file_helper.dart b/tests/compiler/dart2js/memory_source_file_helper.dart
index 3ff2ba5..2efa806 100644
--- a/tests/compiler/dart2js/memory_source_file_helper.dart
+++ b/tests/compiler/dart2js/memory_source_file_helper.dart
@@ -8,7 +8,7 @@
 export 'dart:io' show Platform;
 
 export 'package:compiler/src/apiimpl.dart'
-       show Compiler;
+       show CompilerImpl;
 
 export 'package:compiler/src/filenames.dart'
        show currentDirectory;
diff --git a/tests/compiler/dart2js/message_kind_helper.dart b/tests/compiler/dart2js/message_kind_helper.dart
index 9d60632..28d7948 100644
--- a/tests/compiler/dart2js/message_kind_helper.dart
+++ b/tests/compiler/dart2js/message_kind_helper.dart
@@ -15,8 +15,8 @@
 import 'package:compiler/src/diagnostics/messages.dart' show
     MessageKind,
     MessageTemplate;
-import 'package:compiler/src/old_to_new_api.dart' show
-    LegacyCompilerDiagnostics;
+import 'package:compiler/compiler_new.dart' show
+    Diagnostic;
 
 import 'memory_compiler.dart';
 
@@ -33,6 +33,7 @@
     MessageKind.CANNOT_IMPLEMENT_MALFORMED,
     MessageKind.CANNOT_MIXIN,
     MessageKind.CANNOT_MIXIN_MALFORMED,
+    MessageKind.CANNOT_INSTANTIATE_ENUM,
     MessageKind.CYCLIC_TYPEDEF_ONE,
     MessageKind.EQUAL_MAP_ENTRY_KEY,
     MessageKind.FINAL_FUNCTION_TYPE_PARAMETER,
@@ -68,13 +69,7 @@
       Expect.isTrue(example.containsKey('main.dart'),
                     "Example map must contain a 'main.dart' entry.");
     }
-    List<String> messages = <String>[];
-    void collect(Uri uri, int begin, int end, String message, kind) {
-      if (kind.name == 'verbose info' || kind.name == 'info') {
-        return;
-      }
-      messages.add(message);
-    }
+    DiagnosticCollector collector = new DiagnosticCollector();
 
     bool oldBackendIsDart;
     if (cachedCompiler != null) {
@@ -84,7 +79,7 @@
 
     Compiler compiler = compilerFor(
         memorySourceFiles: example,
-        diagnosticHandler: new LegacyCompilerDiagnostics(collect),
+        diagnosticHandler: collector,
         options: [Flags.analyzeOnly,
                   Flags.enableExperimentalMirrors]..addAll(template.options),
         cachedCompiler:
@@ -93,6 +88,11 @@
              oldBackendIsDart == newBackendIsDart ? cachedCompiler : null);
 
     return compiler.run(Uri.parse('memory:main.dart')).then((_) {
+      Iterable<CollectedMessage> messages = collector.filterMessagesByKinds(
+          [Diagnostic.ERROR,
+           Diagnostic.WARNING,
+           Diagnostic.HINT,
+           Diagnostic.CRASH]);
 
       Expect.isFalse(messages.isEmpty, 'No messages in """$example"""');
 
@@ -102,21 +102,31 @@
           new RegExp(ESCAPE_REGEXP), (m) => '\\${m[0]}');
       pattern = pattern.replaceAll(new RegExp(r'#\\\{[^}]*\\\}'), '.*');
 
+      bool checkMessage(CollectedMessage message) {
+        if (message.message.kind != MessageKind.GENERIC) {
+          return message.message.kind == template.kind;
+        } else {
+          return new RegExp('^$pattern\$').hasMatch(message.text);
+        }
+      }
+
       // TODO(johnniwinther): Extend MessageKind to contain information on
       // where info messages are expected.
       bool messageFound = false;
       List unexpectedMessages = [];
-      for (String message in messages) {
-        if (!messageFound && new RegExp('^$pattern\$').hasMatch(message)) {
+      for (CollectedMessage message in messages) {
+        if (!messageFound && checkMessage(message)) {
           messageFound = true;
         } else {
           unexpectedMessages.add(message);
         }
       }
-      Expect.isTrue(messageFound, '"$pattern" does not match any in $messages');
+      Expect.isTrue(messageFound,
+          '${template.kind}} does not match any in\n '
+          '${messages.join('\n ')}');
       Expect.isFalse(compiler.reporter.hasCrashed);
       if (!unexpectedMessages.isEmpty) {
-        for (String message in unexpectedMessages) {
+        for (CollectedMessage message in unexpectedMessages) {
           print("Unexpected message: $message");
         }
         if (!kindsWithExtraMessages.contains(template.kind)) {
diff --git a/tests/compiler/dart2js/metadata_test.dart b/tests/compiler/dart2js/metadata_test.dart
index 0f1e9fd..9255a75 100644
--- a/tests/compiler/dart2js/metadata_test.dart
+++ b/tests/compiler/dart2js/metadata_test.dart
@@ -176,7 +176,7 @@
         ..registerSource(partUri, partSource)
         ..registerSource(libUri, libSource);
 
-    asyncTest(() => compiler.runCompiler(uri).then((_) {
+    asyncTest(() => compiler.run(uri).then((_) {
       compiler.enqueuer.resolution.queueIsClosed = false;
       LibraryElement element = compiler.libraryLoader.lookupLibrary(uri);
       Expect.isNotNull(element, 'Cannot find $uri');
diff --git a/tests/compiler/dart2js/minimal_resolution_test.dart b/tests/compiler/dart2js/minimal_resolution_test.dart
index b46b340..7de35a3 100644
--- a/tests/compiler/dart2js/minimal_resolution_test.dart
+++ b/tests/compiler/dart2js/minimal_resolution_test.dart
@@ -8,7 +8,7 @@
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/elements/elements.dart';
 import 'package:compiler/src/enqueue.dart';
-import 'package:compiler/src/js_backend/js_backend.dart';
+import 'package:compiler/src/js_backend/backend_helpers.dart';
 import 'package:expect/expect.dart';
 import 'memory_compiler.dart';
 
@@ -50,7 +50,7 @@
       compiler, compiler.coreLibrary.find('Deprecated'), deprecatedClass);
 
   LibraryElement jsHelperLibrary =
-      compiler.libraryLoader.lookupLibrary(JavaScriptBackend.DART_JS_HELPER);
+      compiler.libraryLoader.lookupLibrary(BackendHelpers.DART_JS_HELPER);
   jsHelperLibrary.forEachLocalMember((Element element) {
     Uri uri = element.compilationUnit.script.resourceUri;
     if (element.isClass && uri.path.endsWith('annotations.dart')) {
diff --git a/tests/compiler/dart2js/mirror_helper_rename_test.dart b/tests/compiler/dart2js/mirror_helper_rename_test.dart
index 76d3adb..80edc15 100644
--- a/tests/compiler/dart2js/mirror_helper_rename_test.dart
+++ b/tests/compiler/dart2js/mirror_helper_rename_test.dart
@@ -7,7 +7,7 @@
 import "package:async_helper/async_helper.dart";
 import 'memory_compiler.dart' show runCompiler, OutputCollector;
 import 'package:compiler/src/apiimpl.dart' show
-    Compiler;
+    CompilerImpl;
 import 'package:compiler/src/tree/tree.dart' show
     Node;
 import 'package:compiler/src/dart_backend/dart_backend.dart';
@@ -22,7 +22,7 @@
   });
 }
 
-Future<Compiler> run({OutputCollector outputCollector,
+Future<CompilerImpl> run({OutputCollector outputCollector,
                       bool useMirrorHelperLibrary: false,
                       bool minify: false}) async {
   List<String> options = ['--output-type=dart'];
@@ -33,7 +33,7 @@
       memorySourceFiles: MEMORY_SOURCE_FILES,
       outputProvider: outputCollector,
       options: options,
-      beforeRun: (Compiler compiler) {
+      beforeRun: (CompilerImpl compiler) {
         DartBackend backend = compiler.backend;
         backend.useMirrorHelperLibrary = useMirrorHelperLibrary;
       });
@@ -42,7 +42,7 @@
 
 Future testWithMirrorHelperLibrary({bool minify}) async {
   OutputCollector outputCollector = new OutputCollector();
-  Compiler compiler = await run(
+  CompilerImpl compiler = await run(
       outputCollector: outputCollector,
       useMirrorHelperLibrary: true,
       minify: minify);
@@ -83,7 +83,8 @@
 }
 
 Future testWithoutMirrorHelperLibrary({bool minify}) async {
-  Compiler compiler = await run(useMirrorHelperLibrary: false, minify: minify);
+  CompilerImpl compiler =
+      await run(useMirrorHelperLibrary: false, minify: minify);
   DartBackend backend = compiler.backend;
   MirrorRenamer mirrorRenamer = backend.mirrorRenamer;
 
diff --git a/tests/compiler/dart2js/mirror_helper_test.dart b/tests/compiler/dart2js/mirror_helper_test.dart
index e823b8b..ce257c7 100644
--- a/tests/compiler/dart2js/mirror_helper_test.dart
+++ b/tests/compiler/dart2js/mirror_helper_test.dart
@@ -7,7 +7,7 @@
 import "package:async_helper/async_helper.dart";
 import 'memory_compiler.dart' show runCompiler;
 import 'package:compiler/src/apiimpl.dart' show
-    Compiler;
+    CompilerImpl;
 import 'package:compiler/src/elements/elements.dart' show
     Element, LibraryElement, ClassElement;
 import 'package:compiler/src/tree/tree.dart' show
@@ -26,7 +26,7 @@
   });
 }
 
-Future<Compiler> run({useMirrorHelperLibrary: false, minify: false}) async {
+Future<CompilerImpl> run({useMirrorHelperLibrary: false, minify: false}) async {
   List<String> options = ['--output-type=dart'];
   if (minify) {
     options.add('--minify');
@@ -34,7 +34,7 @@
   var result = await runCompiler(
       memorySourceFiles: MEMORY_SOURCE_FILES,
       options: options,
-      beforeRun: (Compiler compiler) {
+      beforeRun: (CompilerImpl compiler) {
         DartBackend backend = compiler.backend;
         backend.useMirrorHelperLibrary = useMirrorHelperLibrary;
       });
@@ -42,7 +42,8 @@
 }
 
 Future testWithMirrorRenaming({bool minify}) async {
-  Compiler compiler = await run(useMirrorHelperLibrary: true, minify: minify);
+  CompilerImpl compiler =
+      await run(useMirrorHelperLibrary: true, minify: minify);
   DartBackend backend = compiler.backend;
   MirrorRenamerImpl mirrorRenamer = backend.mirrorRenamer;
   Map<Node, String> renames = backend.placeholderRenamer.renames;
@@ -62,7 +63,8 @@
 }
 
 Future testWithoutMirrorRenaming({bool minify}) async {
-  Compiler compiler = await run(useMirrorHelperLibrary: false, minify: minify);
+  CompilerImpl compiler =
+      await run(useMirrorHelperLibrary: false, minify: minify);
   DartBackend backend = compiler.backend;
   Map<Node, String> renames = backend.placeholderRenamer.renames;
   Iterable<LibraryElement> imports =
diff --git a/tests/compiler/dart2js/mirror_helper_unique_minification_test.dart b/tests/compiler/dart2js/mirror_helper_unique_minification_test.dart
index 47c8145..bec8f9f 100644
--- a/tests/compiler/dart2js/mirror_helper_unique_minification_test.dart
+++ b/tests/compiler/dart2js/mirror_helper_unique_minification_test.dart
@@ -7,7 +7,7 @@
 import "package:async_helper/async_helper.dart";
 import 'memory_compiler.dart' show runCompiler;
 import 'package:compiler/src/apiimpl.dart' show
-    Compiler;
+    CompilerImpl;
 import 'package:compiler/src/dart_backend/dart_backend.dart' show
     DartBackend;
 import 'package:compiler/src/tree/tree.dart' show
@@ -22,7 +22,7 @@
   });
 }
 
-Future<Compiler> run({useMirrorHelperLibrary: false, minify: false}) async {
+Future<CompilerImpl> run({useMirrorHelperLibrary: false, minify: false}) async {
   List<String> options = ['--output-type=dart'];
   if (minify) {
     options.add('--minify');
@@ -30,7 +30,7 @@
   var result = await runCompiler(
       memorySourceFiles: MEMORY_SOURCE_FILES,
       options: options,
-      beforeRun: (Compiler compiler) {
+      beforeRun: (CompilerImpl compiler) {
         DartBackend backend = compiler.backend;
         backend.useMirrorHelperLibrary = useMirrorHelperLibrary;
       });
@@ -38,7 +38,7 @@
 }
 
 Future testUniqueMinification() async {
-  Compiler compiler = await run(useMirrorHelperLibrary: true, minify: true);
+  CompilerImpl compiler = await run(useMirrorHelperLibrary: true, minify: true);
   DartBackend backend = compiler.backend;
   MirrorRenamerImpl mirrorRenamer = backend.mirrorRenamer;
   Map<Node, String> renames = backend.placeholderRenamer.renames;
@@ -63,7 +63,8 @@
 }
 
 Future testNoUniqueMinification() async {
-  Compiler compiler = await run(useMirrorHelperLibrary: false, minify: true);
+  CompilerImpl compiler =
+      await run(useMirrorHelperLibrary: false, minify: true);
   DartBackend backend = compiler.backend;
   Map<Node, String> renames = backend.placeholderRenamer.renames;
 
diff --git a/tests/compiler/dart2js/mirror_system_helper.dart b/tests/compiler/dart2js/mirror_system_helper.dart
index 7c97ebd..323ff8e 100644
--- a/tests/compiler/dart2js/mirror_system_helper.dart
+++ b/tests/compiler/dart2js/mirror_system_helper.dart
@@ -23,7 +23,7 @@
       preserveComments: true);
     compiler.registerSource(SOURCE_URI, source);
     compiler.librariesToAnalyzeWhenRun = <Uri>[SOURCE_URI];
-  return compiler.runCompiler(null).then((_) {
+  return compiler.run(null).then((_) {
     return new Dart2JsMirrorSystem(compiler);
   });
 }
diff --git a/tests/compiler/dart2js/mirrors_used_test.dart b/tests/compiler/dart2js/mirrors_used_test.dart
index c68281f..0844273 100644
--- a/tests/compiler/dart2js/mirrors_used_test.dart
+++ b/tests/compiler/dart2js/mirrors_used_test.dart
@@ -13,7 +13,7 @@
     runCompiler;
 
 import 'package:compiler/src/apiimpl.dart' show
-    Compiler;
+    CompilerImpl;
 
 import 'package:compiler/src/constants/values.dart' show
     ConstantValue,
@@ -55,7 +55,7 @@
       memorySourceFiles: MEMORY_SOURCE_FILES,
       diagnosticHandler: new LegacyCompilerDiagnostics(expectOnlyVerboseInfo),
       options: ['--enable-experimental-mirrors']);
-    Compiler compiler = result.compiler;
+    CompilerImpl compiler = result.compiler;
     print('');
     List generatedCode =
         Elements.sortedByPosition(compiler.enqueuer.codegen.generatedCode.keys);
@@ -88,9 +88,13 @@
 
     // We always include the names of some native classes.
     List<Element> nativeClasses = [
-          compiler.intClass, compiler.doubleClass, compiler.numClass,
-          compiler.stringClass, compiler.boolClass, compiler.nullClass,
-          compiler.listClass
+          compiler.coreClasses.intClass,
+          compiler.coreClasses.doubleClass,
+          compiler.coreClasses.numClass,
+          compiler.coreClasses.stringClass,
+          compiler.coreClasses.boolClass,
+          compiler.coreClasses.nullClass,
+          compiler.coreClasses.listClass
         ];
     JavaScriptBackend backend = compiler.backend;
     Iterable<String> nativeNames = nativeClasses.map(backend.namer.className);
diff --git a/tests/compiler/dart2js/mock_compiler.dart b/tests/compiler/dart2js/mock_compiler.dart
index 7456c29..9dde5bf 100644
--- a/tests/compiler/dart2js/mock_compiler.dart
+++ b/tests/compiler/dart2js/mock_compiler.dart
@@ -13,12 +13,13 @@
     Uris;
 import 'package:compiler/src/constants/expressions.dart';
 import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
-import 'package:compiler/src/diagnostics/messages.dart';
 import 'package:compiler/src/diagnostics/source_span.dart';
 import 'package:compiler/src/diagnostics/spannable.dart';
 import 'package:compiler/src/elements/elements.dart';
-import 'package:compiler/src/js_backend/js_backend.dart'
-    show JavaScriptBackend;
+import 'package:compiler/src/js_backend/backend_helpers.dart'
+    show BackendHelpers;
+import 'package:compiler/src/js_backend/lookup_map_analysis.dart'
+    show LookupMapAnalysis;
 import 'package:compiler/src/io/source_file.dart';
 import 'package:compiler/src/resolution/members.dart';
 import 'package:compiler/src/resolution/registry.dart';
@@ -42,14 +43,9 @@
          OutputUnit;
 
 import 'mock_libraries.dart';
+import 'diagnostic_helper.dart';
 
-class WarningMessage {
-  Spannable node;
-  Message message;
-  WarningMessage(this.node, this.message);
-
-  toString() => message.kind.toString();
-}
+export 'diagnostic_helper.dart';
 
 final Uri PATCH_CORE = new Uri(scheme: 'patch', path: 'core');
 
@@ -57,11 +53,6 @@
 
 class MockCompiler extends Compiler {
   api.DiagnosticHandler diagnosticHandler;
-  List<WarningMessage> warnings;
-  List<WarningMessage> errors;
-  List<WarningMessage> hints;
-  List<WarningMessage> infos;
-  List<WarningMessage> crashes;
   /// Expected number of warnings. If `null`, the number of warnings is
   /// not checked.
   final int expectedWarnings;
@@ -71,6 +62,7 @@
   Node parsedTree;
   final String testedPatchVersion;
   final LibrarySourceProvider librariesOverride;
+  final DiagnosticCollector diagnosticCollector = new DiagnosticCollector();
 
   MockCompiler.internal(
       {Map<String, String> coreSource,
@@ -113,22 +105,20 @@
 
     deferredLoadTask = new MockDeferredLoadTask(this);
 
-    clearMessages();
-
     registerSource(Uris.dart_core,
                    buildLibrarySource(DEFAULT_CORE_LIBRARY, coreSource));
     registerSource(PATCH_CORE, DEFAULT_PATCH_CORE_SOURCE);
 
-    registerSource(JavaScriptBackend.DART_JS_HELPER,
+    registerSource(BackendHelpers.DART_JS_HELPER,
                    buildLibrarySource(DEFAULT_JS_HELPER_LIBRARY));
-    registerSource(JavaScriptBackend.DART_FOREIGN_HELPER,
+    registerSource(BackendHelpers.DART_FOREIGN_HELPER,
                    buildLibrarySource(DEFAULT_FOREIGN_HELPER_LIBRARY));
-    registerSource(JavaScriptBackend.DART_INTERCEPTORS,
+    registerSource(BackendHelpers.DART_INTERCEPTORS,
                    buildLibrarySource(DEFAULT_INTERCEPTORS_LIBRARY));
-    registerSource(JavaScriptBackend.DART_ISOLATE_HELPER,
+    registerSource(BackendHelpers.DART_ISOLATE_HELPER,
                    buildLibrarySource(DEFAULT_ISOLATE_HELPER_LIBRARY));
     registerSource(Uris.dart_mirrors, DEFAULT_MIRRORS_SOURCE);
-    registerSource(JavaScriptBackend.DART_JS_MIRRORS,
+    registerSource(BackendHelpers.DART_JS_MIRRORS,
         DEFAULT_JS_MIRRORS_SOURCE);
 
     Map<String, String> asyncLibrarySource = <String, String>{};
@@ -138,7 +128,7 @@
     }
     registerSource(Uris.dart_async,
                    buildLibrarySource(asyncLibrarySource));
-    registerSource(JavaScriptBackend.PACKAGE_LOOKUP_MAP,
+    registerSource(LookupMapAnalysis.PACKAGE_LOOKUP_MAP,
                    buildLibrarySource(DEFAULT_LOOKUP_MAP_LIBRARY));
   }
 
@@ -157,20 +147,22 @@
       // dynamic invocation the ArgumentTypesRegistry eventually iterates over
       // the interfaces of the Object class which would be 'null' if the class
       // wasn't resolved.
-      objectClass.ensureResolved(resolution);
+      coreClasses.objectClass.ensureResolved(resolution);
     }).then((_) => uri);
   }
 
-  Future runCompiler(Uri uri, [String mainSource = ""]) {
+  Future run(Uri uri, [String mainSource = ""]) {
     return init(mainSource).then((Uri mainUri) {
-      return super.runCompiler(uri == null ? mainUri : uri);
+      return super.run(uri == null ? mainUri : uri);
     }).then((result) {
       if (expectedErrors != null &&
-          expectedErrors != errors.length) {
-        throw "unexpected error during compilation ${errors}";
+          expectedErrors != diagnosticCollector.errors.length) {
+        throw "unexpected error during compilation "
+              "${diagnosticCollector.errors}";
       } else if (expectedWarnings != null &&
-                 expectedWarnings != warnings.length) {
-        throw "unexpected warnings during compilation ${warnings}";
+                 expectedWarnings != diagnosticCollector.warnings.length) {
+        throw "unexpected warnings during compilation "
+              "${diagnosticCollector.warnings}";
       } else {
         return result;
       }
@@ -192,39 +184,24 @@
     sourceFiles[uri.toString()] = new MockFile(source);
   }
 
-  // TODO(johnniwinther): Remove this when we don't filter certain type checker
-  // warnings.
-  void reportWarning(
-      DiagnosticMessage message,
-      [List<DiagnosticMessage> infos = const <DiagnosticMessage>[]]) {
-    reportDiagnostic(message, infos, api.Diagnostic.WARNING);
-  }
-
   void reportDiagnostic(DiagnosticMessage message,
                         List<DiagnosticMessage> infoMessages,
                         api.Diagnostic kind) {
 
     void processMessage(DiagnosticMessage message, api.Diagnostic kind) {
-      var diagnostic = new WarningMessage(message.spannable, message.message);
-      if (kind == api.Diagnostic.CRASH) {
-        crashes.add(diagnostic);
-      } else if (kind == api.Diagnostic.ERROR) {
-        errors.add(diagnostic);
-      } else if (kind == api.Diagnostic.WARNING) {
-        warnings.add(diagnostic);
-      } else if (kind == api.Diagnostic.INFO) {
-        infos.add(diagnostic);
-      } else if (kind == api.Diagnostic.HINT) {
-        hints.add(diagnostic);
+      SourceSpan span = message.sourceSpan;
+      Uri uri;
+      int begin;
+      int end;
+      String text = '${message.message}';
+      if (span != null) {
+        uri = span.uri;
+        begin = span.begin;
+        end = span.end;
       }
+      diagnosticCollector.report(message.message, uri, begin, end, text, kind);
       if (diagnosticHandler != null) {
-        SourceSpan span = message.sourceSpan;
-        if (span != null) {
-          diagnosticHandler(
-              span.uri, span.begin, span.end, '${message.message}', kind);
-        } else {
-          diagnosticHandler(null, null, null, '${message.message}', kind);
-        }
+        diagnosticHandler(uri, begin, end, text, kind);
       }
     }
 
@@ -232,16 +209,6 @@
     infoMessages.forEach((i) => processMessage(i, api.Diagnostic.INFO));
   }
 
-  bool get compilationFailed => !crashes.isEmpty || !errors.isEmpty;
-
-  void clearMessages() {
-    warnings = [];
-    errors = [];
-    hints = [];
-    infos = [];
-    crashes = [];
-  }
-
   CollectingTreeElements resolveStatement(String text) {
     parsedTree = parseStatement(text);
     return resolveNodeStatement(parsedTree, new MockElement(mainApp));
@@ -317,74 +284,6 @@
   }
 }
 
-/// A function the checks [message]. If the check fails or if [message] is
-/// `null`, an error string is returned. Otherwise `null` is returned.
-typedef String CheckMessage(Message message);
-
-CheckMessage checkMessage(MessageKind kind, Map arguments) {
-  return (Message message) {
-    if (message == null) return '$kind';
-    if (message.kind != kind) return 'Expected message $kind, found $message.';
-    for (var key in arguments.keys) {
-      if (!message.arguments.containsKey(key)) {
-        return 'Expected argument $key not found in $message.kind.';
-      }
-      String expectedValue = '${arguments[key]}';
-      String foundValue = '${message.arguments[key]}';
-      if (expectedValue != foundValue) {
-        return 'Expected argument $key with value $expectedValue, '
-               'found $foundValue.';
-      }
-    }
-    return null;
-  };
-}
-
-void compareWarningKinds(String text,
-                         List expectedWarnings,
-                         List<WarningMessage> foundWarnings) {
-  compareMessageKinds(text, expectedWarnings, foundWarnings, 'warning');
-}
-
-/// [expectedMessages] must be a list of either [MessageKind] or [CheckMessage].
-void compareMessageKinds(String text,
-                         List expectedMessages,
-                         List<WarningMessage> foundMessages,
-                         String kind) {
-  var fail = (message) => Expect.fail('$text: $message');
-  HasNextIterator expectedIterator =
-      new HasNextIterator(expectedMessages.iterator);
-  HasNextIterator<WarningMessage> foundIterator =
-      new HasNextIterator(foundMessages.iterator);
-  while (expectedIterator.hasNext && foundIterator.hasNext) {
-    var expected = expectedIterator.next();
-    var found = foundIterator.next();
-    if (expected is MessageKind) {
-      Expect.equals(expected, found.message.kind);
-    } else if (expected is CheckMessage) {
-      String error = expected(found.message);
-      Expect.isNull(error, error);
-    } else {
-      Expect.fail("Unexpected $kind value: $expected.");
-    }
-  }
-  if (expectedIterator.hasNext) {
-    do {
-      var expected = expectedIterator.next();
-      if (expected is CheckMessage) expected = expected(null);
-      print('Expected $kind "${expected}" did not occur');
-    } while (expectedIterator.hasNext);
-    fail('Too few ${kind}s');
-  }
-  if (foundIterator.hasNext) {
-    do {
-      WarningMessage message = foundIterator.next();
-      print('Additional $kind "${message}: ${message.message}"');
-    } while (foundIterator.hasNext);
-    fail('Too many ${kind}s');
-  }
-}
-
 class CollectingTreeElements extends TreeElementMapping {
   final Map<Node, Element> map = new LinkedHashMap<Node, Element>();
 
diff --git a/tests/compiler/dart2js/mock_libraries.dart b/tests/compiler/dart2js/mock_libraries.dart
index 37135b2..9b89db0 100644
--- a/tests/compiler/dart2js/mock_libraries.dart
+++ b/tests/compiler/dart2js/mock_libraries.dart
@@ -6,6 +6,15 @@
 
 library mock_libraries;
 
+const DEFAULT_PLATFORM_CONFIG = """
+[libraries]
+core:core/core.dart
+async:async/async.dart
+_js_helper:_internal/js_runtime/lib/js_helper.dart
+_interceptors:_internal/js_runtime/lib/interceptors.dart
+_isolate_helper:_internal/js_runtime/lib/isolate_helper.dart
+""";
+
 String buildLibrarySource(
     Map<String, String> elementMap,
     [Map<String, String> additionalElementMap = const <String, String>{}]) {
@@ -54,7 +63,7 @@
           E get current => null;
       }''',
   'LinkedHashMap': r'''
-      class LinkedHashMap {
+      class LinkedHashMap<K, V> implements Map<K, V> {
         factory LinkedHashMap._empty() => null;
         factory LinkedHashMap._literal(elements) => null;
         static _makeEmpty() => null;
diff --git a/tests/compiler/dart2js/no_such_method_codegen_test.dart b/tests/compiler/dart2js/no_such_method_codegen_test.dart
index 85777ad..b40d311 100644
--- a/tests/compiler/dart2js/no_such_method_codegen_test.dart
+++ b/tests/compiler/dart2js/no_such_method_codegen_test.dart
@@ -20,5 +20,5 @@
 main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  compiler.runCompiler(uri);
+  compiler.run(uri);
 }
diff --git a/tests/compiler/dart2js/no_such_method_enabled_test.dart b/tests/compiler/dart2js/no_such_method_enabled_test.dart
index cb994a9..2f5f9c7 100644
--- a/tests/compiler/dart2js/no_such_method_enabled_test.dart
+++ b/tests/compiler/dart2js/no_such_method_enabled_test.dart
@@ -18,7 +18,7 @@
 """;
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(source, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     Expect.isFalse(compiler.backend.enabledNoSuchMethod);
     ClassElement clsA = findElement(compiler, 'A');
     Expect.isTrue(
@@ -40,7 +40,7 @@
 """;
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(source, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     Expect.isFalse(compiler.backend.enabledNoSuchMethod);
     ClassElement clsA = findElement(compiler, 'A');
     Expect.isTrue(
@@ -64,7 +64,7 @@
 """;
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(source, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     Expect.isFalse(compiler.backend.enabledNoSuchMethod);
     ClassElement clsA = findElement(compiler, 'A');
     Expect.isTrue(
@@ -88,7 +88,7 @@
 """;
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(source, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     Expect.isFalse(compiler.backend.enabledNoSuchMethod);
     ClassElement clsA = findElement(compiler, 'A');
     Expect.isTrue(
@@ -116,7 +116,7 @@
 """;
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(source, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     Expect.isTrue(compiler.backend.enabledNoSuchMethod);
     ClassElement clsA = findElement(compiler, 'A');
     Expect.isTrue(
@@ -140,7 +140,7 @@
 """;
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(source, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     Expect.isTrue(compiler.backend.enabledNoSuchMethod);
     ClassElement clsA = findElement(compiler, 'A');
     Expect.isTrue(
@@ -160,7 +160,7 @@
 """;
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(source, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     Expect.isFalse(compiler.backend.enabledNoSuchMethod);
     ClassElement clsA = findElement(compiler, 'A');
     Expect.isTrue(
@@ -180,7 +180,7 @@
 """;
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(source, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     Expect.isTrue(compiler.backend.enabledNoSuchMethod);
     ClassElement clsA = findElement(compiler, 'A');
     Expect.isTrue(
@@ -200,7 +200,7 @@
 """;
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(source, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     Expect.isTrue(compiler.backend.enabledNoSuchMethod);
     ClassElement clsA = findElement(compiler, 'A');
     Expect.isTrue(
@@ -222,7 +222,7 @@
 """;
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(source, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     Expect.isTrue(compiler.backend.enabledNoSuchMethod);
     ClassElement clsA = findElement(compiler, 'A');
     Expect.isTrue(
@@ -245,7 +245,7 @@
 """;
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(source, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     Expect.isTrue(compiler.backend.enabledNoSuchMethod);
     ClassElement clsA = findElement(compiler, 'A');
     Expect.isTrue(
@@ -270,7 +270,7 @@
 """;
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(source, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     Expect.isTrue(compiler.backend.enabledNoSuchMethod);
     ClassElement clsA = findElement(compiler, 'A');
     Expect.isTrue(
diff --git a/tests/compiler/dart2js/override_inheritance_test.dart b/tests/compiler/dart2js/override_inheritance_test.dart
index c71e6b2..628f625 100644
--- a/tests/compiler/dart2js/override_inheritance_test.dart
+++ b/tests/compiler/dart2js/override_inheritance_test.dart
@@ -34,16 +34,24 @@
 
     toList(o) => o == null ? [] : o is List ? o : [o];
 
-    compareMessageKinds(source, toList(errors), compiler.errors, 'error');
+    compareMessageKinds(
+        source, toList(errors),
+        compiler.diagnosticCollector.errors, 'error');
 
-    compareMessageKinds(source, toList(warnings), compiler.warnings, 'warning');
+    compareMessageKinds(
+        source, toList(warnings),
+        compiler.diagnosticCollector.warnings, 'warning');
 
     if (infos != null) {
-      compareMessageKinds(source, toList(infos), compiler.infos, 'info');
+      compareMessageKinds(
+          source, toList(infos),
+          compiler.diagnosticCollector.infos, 'info');
     }
 
     if (hints != null) {
-      compareMessageKinds(source, toList(hints), compiler.hints, 'hint');
+      compareMessageKinds(
+          source, toList(hints),
+          compiler.diagnosticCollector.hints, 'hint');
     }
   });
 }
diff --git a/tests/compiler/dart2js/parser_helper.dart b/tests/compiler/dart2js/parser_helper.dart
index 572a082..eeba1f9 100644
--- a/tests/compiler/dart2js/parser_helper.dart
+++ b/tests/compiler/dart2js/parser_helper.dart
@@ -99,9 +99,9 @@
   Uri uri = new Uri(scheme: "source");
   Script script = new Script(uri, uri,new MockFile(text));
   LibraryElement library = new LibraryElementX(script);
-  library.canUseNative = true;
-  NodeListener listener =
-      new NodeListener(reporter, library.entryCompilationUnit);
+  NodeListener listener = new NodeListener(
+      new ScannerOptions(canUseNative: true),
+      reporter, library.entryCompilationUnit);
   Parser parser = new Parser(listener);
   Token endToken = parseMethod(parser, tokens);
   assert(endToken.kind == EOF_TOKEN);
@@ -147,7 +147,9 @@
   var unit = new CompilationUnitElementX(script, library);
   int id = 0;
   DiagnosticReporter reporter = compiler.reporter;
-  ElementListener listener = new ElementListener(reporter, unit, () => id++);
+  ElementListener listener = new ElementListener(
+      compiler.parsing.getScannerOptionsFor(library),
+      reporter, unit, () => id++);
   PartialParser parser = new PartialParser(listener);
   reporter.withCurrentElement(unit, () => parser.parseUnit(tokens));
   return unit.localMembers;
diff --git a/tests/compiler/dart2js/part_of_test.dart b/tests/compiler/dart2js/part_of_test.dart
index 979d9ca..3a134dc 100644
--- a/tests/compiler/dart2js/part_of_test.dart
+++ b/tests/compiler/dart2js/part_of_test.dart
@@ -27,13 +27,14 @@
   compiler.registerSource(partUri, PART_SOURCE);
 
   asyncTest(() => compiler.libraryLoader.loadLibrary(libraryUri).then((_) {
-    print('errors: ${compiler.errors}');
-    print('warnings: ${compiler.warnings}');
-    Expect.isTrue(compiler.errors.isEmpty);
-    Expect.equals(1, compiler.warnings.length);
+    DiagnosticCollector collector = compiler.diagnosticCollector;
+    print('errors: ${collector.errors}');
+    print('warnings: ${collector.warnings}');
+    Expect.isTrue(collector.errors.isEmpty);
+    Expect.equals(1, collector.warnings.length);
     Expect.equals(MessageKind.LIBRARY_NAME_MISMATCH,
-                  compiler.warnings[0].message.kind);
+        collector.warnings.first.messageKind);
     Expect.equals('foo',
-        compiler.warnings[0].message.arguments['libraryName'].toString());
+        collector.warnings.first.message.arguments['libraryName'].toString());
   }));
 }
diff --git a/tests/compiler/dart2js/patch_test.dart b/tests/compiler/dart2js/patch_test.dart
index 660a803..9f20998 100644
--- a/tests/compiler/dart2js/patch_test.dart
+++ b/tests/compiler/dart2js/patch_test.dart
@@ -37,7 +37,7 @@
   compiler.registerSource(uri, "$DEFAULT_PATCH_CORE_SOURCE\n$patch");
   var future;
   if (runCompiler) {
-    future = compiler.runCompiler(null, main);
+    future = compiler.run(null, main);
   } else {
     future = compiler.init(main);
   }
@@ -135,10 +135,11 @@
   ensure(compiler, "test", compiler.coreLibrary.patch.find,
          expectIsPatch: true, checkHasBody: true);
 
-  Expect.isTrue(compiler.warnings.isEmpty,
-                "Unexpected warnings: ${compiler.warnings}");
-  Expect.isTrue(compiler.errors.isEmpty,
-                "Unexpected errors: ${compiler.errors}");
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  Expect.isTrue(collector.errors.isEmpty,
+                "Unexpected errors: ${collector.errors}");
 }
 
 Future testPatchFunctionMetadata() async {
@@ -148,18 +149,19 @@
       @a external test();
       """,
       """
-      const b = 1;
-      @patch @b test() {}
+      const _b = 1;
+      @patch @_b test() {}
       """);
   Element origin = ensure(compiler, "test", compiler.coreLibrary.find,
          expectIsPatched: true, checkHasBody: true);
   Element patch = ensure(compiler, "test", compiler.coreLibrary.patch.find,
          expectIsPatch: true, checkHasBody: true);
 
-  Expect.isTrue(compiler.warnings.isEmpty,
-                "Unexpected warnings: ${compiler.warnings}");
-  Expect.isTrue(compiler.errors.isEmpty,
-                "Unexpected errors: ${compiler.errors}");
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  Expect.isTrue(collector.errors.isEmpty,
+                "Unexpected errors: ${collector.errors}");
 
   Expect.equals(1, origin.metadata.length,
                 "Unexpected origin metadata: ${origin.metadata}.");
@@ -206,14 +208,15 @@
         compiler.analyzeElement(origin);
         compiler.enqueuer.resolution.emptyDeferredTaskQueue();
 
-        Expect.isTrue(compiler.warnings.isEmpty,
-                      "Unexpected warnings: ${compiler.warnings}");
+        DiagnosticCollector collector = compiler.diagnosticCollector;
+        Expect.isTrue(collector.warnings.isEmpty,
+                      "Unexpected warnings: ${collector.warnings}");
         if (expectedError != null) {
           Expect.equals(expectedError,
-                        compiler.errors[0].message.toString());
+                        collector.errors.first.message.toString());
         } else {
-          Expect.isTrue(compiler.errors.isEmpty,
-                        "Unexpected errors: ${compiler.errors}");
+          Expect.isTrue(collector.errors.isEmpty,
+                        "Unexpected errors: ${collector.errors}");
         }
       }).catchError((error) {
         if (expectedInternalError != null) {
@@ -265,10 +268,11 @@
   Expect.equals(constructorPatch, constructorOrigin.patch);
   Expect.equals(constructorOrigin, constructorPatch.origin);
 
-  Expect.isTrue(compiler.warnings.isEmpty,
-                "Unexpected warnings: ${compiler.warnings}");
-  Expect.isTrue(compiler.errors.isEmpty,
-                "Unexpected errors: ${compiler.errors}");
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  Expect.isTrue(collector.errors.isEmpty,
+                "Unexpected errors: ${collector.errors}");
 }
 
 Future testPatchRedirectingConstructor() async {
@@ -311,10 +315,11 @@
 
   compiler.resolver.resolve(constructorRedirecting);
 
-  Expect.isTrue(compiler.warnings.isEmpty,
-                "Unexpected warnings: ${compiler.warnings}");
-  Expect.isTrue(compiler.errors.isEmpty,
-                "Unexpected errors: ${compiler.errors}");
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  Expect.isTrue(collector.errors.isEmpty,
+                "Unexpected errors: ${collector.errors}");
 }
 
 Future testPatchMember() async {
@@ -340,10 +345,11 @@
   ensure(compiler, "toString", container.patch.lookupLocalMember,
          expectIsPatch: true, checkHasBody: true);
 
-  Expect.isTrue(compiler.warnings.isEmpty,
-                "Unexpected warnings: ${compiler.warnings}");
-  Expect.isTrue(compiler.errors.isEmpty,
-                "Unexpected errors: ${compiler.errors}");
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  Expect.isTrue(collector.errors.isEmpty,
+                "Unexpected errors: ${collector.errors}");
 }
 
 Future testPatchGetter() async {
@@ -374,10 +380,11 @@
          expectIsPatch: true,
          checkHasBody: true);
 
-  Expect.isTrue(compiler.warnings.isEmpty,
-                "Unexpected warnings: ${compiler.warnings}");
-  Expect.isTrue(compiler.errors.isEmpty,
-                "Unexpected errors: ${compiler.errors}");
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  Expect.isTrue(collector.errors.isEmpty,
+                "Unexpected errors: ${collector.errors}");
 }
 
 Future testRegularMember() async {
@@ -402,13 +409,14 @@
   ensure(compiler, "regular", container.patch.lookupLocalMember,
          checkHasBody: true, expectIsRegular: true);
 
-  Expect.isTrue(compiler.warnings.isEmpty,
-                "Unexpected warnings: ${compiler.warnings}");
-  Expect.isTrue(compiler.errors.isEmpty,
-                "Unexpected errors: ${compiler.errors}");
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  Expect.isTrue(collector.errors.isEmpty,
+                "Unexpected errors: ${collector.errors}");
 }
 
-Future testGhostMember() async {
+Future testInjectedMember() async {
   var compiler = await applyPatch(
       """
       class Class {
@@ -416,7 +424,7 @@
       """,
       """
       @patch class Class {
-        void ghost() {}
+        void _injected() {}
       }
       """);
   var container = ensure(compiler, "Class", compiler.coreLibrary.find,
@@ -425,18 +433,51 @@
   ensure(compiler, "Class", compiler.coreLibrary.patch.find,
          expectIsPatch: true);
 
-  ensure(compiler, "ghost", container.lookupLocalMember,
+  ensure(compiler, "_injected", container.lookupLocalMember,
          expectIsFound: false);
-  ensure(compiler, "ghost", container.patch.lookupLocalMember,
+  ensure(compiler, "_injected", container.patch.lookupLocalMember,
          checkHasBody: true, expectIsRegular: true);
 
-  Expect.isTrue(compiler.warnings.isEmpty,
-                "Unexpected warnings: ${compiler.warnings}");
-  Expect.isTrue(compiler.errors.isEmpty,
-                "Unexpected errors: ${compiler.errors}");
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  Expect.isTrue(collector.errors.isEmpty,
+                "Unexpected errors: ${collector.errors}");
 }
 
-Future testInjectFunction() async {
+Future testInjectedPublicMember() async {
+  var compiler = await applyPatch(
+      """
+      class Class {
+      }
+      """,
+      """
+      @patch class Class {
+        void injected() {}
+      }
+      """);
+  var container = ensure(compiler, "Class", compiler.coreLibrary.find,
+                         expectIsPatched: true);
+  container.parseNode(compiler.parsing);
+  ensure(compiler, "Class", compiler.coreLibrary.patch.find,
+         expectIsPatch: true);
+
+  ensure(compiler, "injected", container.lookupLocalMember,
+         expectIsFound: false);
+  ensure(compiler, "injected", container.patch.lookupLocalMember,
+         checkHasBody: true, expectIsRegular: true);
+
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  Expect.equals(1, collector.errors.length,
+                "Unexpected errors: ${collector.errors}");
+  Expect.isTrue(
+      collector.errors.first.message.kind ==
+          MessageKind.INJECTED_PUBLIC_MEMBER);
+}
+
+Future testInjectedFunction() async {
   var compiler = await applyPatch(
       "",
       "int _function() => 5;");
@@ -449,10 +490,34 @@
          compiler.coreLibrary.patch.find,
          checkHasBody: true, expectIsRegular: true);
 
-  Expect.isTrue(compiler.warnings.isEmpty,
-                "Unexpected warnings: ${compiler.warnings}");
-  Expect.isTrue(compiler.errors.isEmpty,
-                "Unexpected errors: ${compiler.errors}");
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  Expect.isTrue(collector.errors.isEmpty,
+                "Unexpected errors: ${collector.errors}");
+}
+
+Future testInjectedPublicFunction() async {
+  var compiler = await applyPatch(
+      "",
+      "int function() => 5;");
+  ensure(compiler,
+         "function",
+         compiler.coreLibrary.find,
+         expectIsFound: false);
+  ensure(compiler,
+         "function",
+         compiler.coreLibrary.patch.find,
+         checkHasBody: true, expectIsRegular: true);
+
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  Expect.equals(1, collector.errors.length,
+                "Unexpected errors: ${collector.errors}");
+  Expect.isTrue(
+      collector.errors.first.message.kind ==
+          MessageKind.INJECTED_PUBLIC_MEMBER);
 }
 
 Future testPatchSignatureCheck() async {
@@ -491,22 +556,23 @@
                          expectIsPatched: true);
   container.ensureResolved(compiler.resolution);
   container.parseNode(compiler.parsing);
+  DiagnosticCollector collector = compiler.diagnosticCollector;
 
   void expect(String methodName, List infos, List errors) {
-    compiler.clearMessages();
+    collector.clear();
     compiler.resolver.resolveMethodElement(
         ensure(compiler, methodName, container.lookupLocalMember,
             expectIsPatched: true, checkHasBody: true));
-    Expect.equals(0, compiler.warnings.length);
-    Expect.equals(infos.length, compiler.infos.length,
-                  "Unexpected infos: ${compiler.infos} on $methodName");
+    Expect.equals(0, collector.warnings.length);
+    Expect.equals(infos.length, collector.infos.length,
+                  "Unexpected infos: ${collector.infos} on $methodName");
     for (int i = 0 ; i < infos.length ; i++) {
-      Expect.equals(infos[i], compiler.infos[i].message.kind);
+      Expect.equals(infos[i], collector.infos.elementAt(i).message.kind);
     }
-    Expect.equals(errors.length, compiler.errors.length,
-                  "Unexpected errors: ${compiler.errors} on $methodName");
+    Expect.equals(errors.length, collector.errors.length,
+                  "Unexpected errors: ${collector.errors} on $methodName");
     for (int i = 0 ; i < errors.length ; i++) {
-      Expect.equals(errors[i], compiler.errors[i].message.kind);
+      Expect.equals(errors[i], collector.errors.elementAt(i).message.kind);
     }
   }
 
@@ -543,15 +609,16 @@
       """);
   var function = ensure(compiler, "foo", compiler.coreLibrary.find);
   compiler.resolver.resolve(function);
-  Expect.isTrue(compiler.warnings.isEmpty,
-                "Unexpected warnings: ${compiler.warnings}");
-  print('testExternalWithoutImplementationTopLevel:${compiler.errors}');
-  Expect.equals(1, compiler.errors.length);
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  print('testExternalWithoutImplementationTopLevel:${collector.errors}');
+  Expect.equals(1, collector.errors.length);
   Expect.isTrue(
-      compiler.errors[0].message.kind ==
+      collector.errors.first.message.kind ==
           MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION);
   Expect.stringEquals('External method without an implementation.',
-                      compiler.errors[0].message.toString());
+                      collector.errors.first.message.toString());
 }
 
 Future testExternalWithoutImplementationMember() async {
@@ -569,20 +636,19 @@
   var container = ensure(compiler, "Class", compiler.coreLibrary.find,
                          expectIsPatched: true);
   container.parseNode(compiler.parsing);
-
-  compiler.warnings.clear();
-  compiler.errors.clear();
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  collector.clear();
   compiler.resolver.resolveMethodElement(
       ensure(compiler, "foo", container.lookupLocalMember));
-  Expect.isTrue(compiler.warnings.isEmpty,
-                "Unexpected warnings: ${compiler.warnings}");
-  print('testExternalWithoutImplementationMember:${compiler.errors}');
-  Expect.equals(1, compiler.errors.length);
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  print('testExternalWithoutImplementationMember:${collector.errors}');
+  Expect.equals(1, collector.errors.length);
   Expect.isTrue(
-      compiler.errors[0].message.kind ==
+      collector.errors.first.message.kind ==
           MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION);
   Expect.stringEquals('External method without an implementation.',
-                      compiler.errors[0].message.toString());
+                      collector.errors.first.message.toString());
 }
 
 Future testIsSubclass() async {
@@ -609,12 +675,13 @@
       """
       @patch class Class {}
       """);
-  Expect.isTrue(compiler.warnings.isEmpty,
-                "Unexpected warnings: ${compiler.warnings}");
-  print('testPatchNonExistingTopLevel:${compiler.errors}');
-  Expect.equals(1, compiler.errors.length);
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  print('testPatchNonExistingTopLevel:${collector.errors}');
+  Expect.equals(1, collector.errors.length);
   Expect.isTrue(
-      compiler.errors[0].message.kind == MessageKind.PATCH_NON_EXISTING);
+      collector.errors.first.message.kind == MessageKind.PATCH_NON_EXISTING);
 }
 
 Future testPatchNonExistingMember() async {
@@ -630,13 +697,14 @@
   var container = ensure(compiler, "Class", compiler.coreLibrary.find,
                          expectIsPatched: true);
   container.parseNode(compiler.parsing);
+  DiagnosticCollector collector = compiler.diagnosticCollector;
 
-  Expect.isTrue(compiler.warnings.isEmpty,
-                "Unexpected warnings: ${compiler.warnings}");
-  print('testPatchNonExistingMember:${compiler.errors}');
-  Expect.equals(1, compiler.errors.length);
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  print('testPatchNonExistingMember:${collector.errors}');
+  Expect.equals(1, collector.errors.length);
   Expect.isTrue(
-      compiler.errors[0].message.kind == MessageKind.PATCH_NON_EXISTING);
+      collector.errors.first.message.kind == MessageKind.PATCH_NON_EXISTING);
 }
 
 Future testPatchNonPatchablePatch() async {
@@ -649,12 +717,13 @@
       """);
   ensure(compiler, "foo", compiler.coreLibrary.find);
 
-  Expect.isTrue(compiler.warnings.isEmpty,
-                "Unexpected warnings: ${compiler.warnings}");
-  print('testPatchNonPatchablePatch:${compiler.errors}');
-  Expect.equals(1, compiler.errors.length);
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  print('testPatchNonPatchablePatch:${collector.errors}');
+  Expect.equals(1, collector.errors.length);
   Expect.isTrue(
-      compiler.errors[0].message.kind == MessageKind.PATCH_NONPATCHABLE);
+      collector.errors.first.message.kind == MessageKind.PATCH_NONPATCHABLE);
 }
 
 Future testPatchNonPatchableOrigin() async {
@@ -667,16 +736,18 @@
       """);
   ensure(compiler, "foo", compiler.coreLibrary.find);
 
-  Expect.isTrue(compiler.warnings.isEmpty,
-                "Unexpected warnings: ${compiler.warnings}");
-  print('testPatchNonPatchableOrigin:${compiler.errors}');
-  Expect.equals(2, compiler.errors.length);
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  print('testPatchNonPatchableOrigin:${collector.errors}');
+  Expect.equals(2, collector.errors.length);
   Expect.equals(
-      MessageKind.EXTRANEOUS_MODIFIER, compiler.errors[0].message.kind);
+      MessageKind.EXTRANEOUS_MODIFIER, collector.errors.first.message.kind);
   Expect.equals(
       // TODO(ahe): Eventually, this error should be removed as it will be
       // handled by the regular parser.
-      MessageKind.PATCH_NONPATCHABLE, compiler.errors[1].message.kind);
+      MessageKind.PATCH_NONPATCHABLE,
+      collector.errors.elementAt(1).message.kind);
 }
 
 Future testPatchNonExternalTopLevel() async {
@@ -687,14 +758,15 @@
       """
       @patch void foo() {}
       """);
-  print('testPatchNonExternalTopLevel.errors:${compiler.errors}');
-  print('testPatchNonExternalTopLevel.warnings:${compiler.warnings}');
-  Expect.equals(1, compiler.errors.length);
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  print('testPatchNonExternalTopLevel.errors:${collector.errors}');
+  print('testPatchNonExternalTopLevel.warnings:${collector.warnings}');
+  Expect.equals(1, collector.errors.length);
   Expect.isTrue(
-      compiler.errors[0].message.kind == MessageKind.PATCH_NON_EXTERNAL);
-  Expect.equals(0, compiler.warnings.length);
-  Expect.equals(1, compiler.infos.length);
-  Expect.isTrue(compiler.infos[0].message.kind ==
+      collector.errors.first.message.kind == MessageKind.PATCH_NON_EXTERNAL);
+  Expect.equals(0, collector.warnings.length);
+  Expect.equals(1, collector.infos.length);
+  Expect.isTrue(collector.infos.first.message.kind ==
       MessageKind.PATCH_POINT_TO_FUNCTION);
 }
 
@@ -714,14 +786,15 @@
                          expectIsPatched: true);
   container.parseNode(compiler.parsing);
 
-  print('testPatchNonExternalMember.errors:${compiler.errors}');
-  print('testPatchNonExternalMember.warnings:${compiler.warnings}');
-  Expect.equals(1, compiler.errors.length);
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  print('testPatchNonExternalMember.errors:${collector.errors}');
+  print('testPatchNonExternalMember.warnings:${collector.warnings}');
+  Expect.equals(1, collector.errors.length);
   Expect.isTrue(
-      compiler.errors[0].message.kind == MessageKind.PATCH_NON_EXTERNAL);
-  Expect.equals(0, compiler.warnings.length);
-  Expect.equals(1, compiler.infos.length);
-  Expect.isTrue(compiler.infos[0].message.kind ==
+      collector.errors.first.message.kind == MessageKind.PATCH_NON_EXTERNAL);
+  Expect.equals(0, collector.warnings.length);
+  Expect.equals(1, collector.infos.length);
+  Expect.isTrue(collector.infos.first.message.kind ==
       MessageKind.PATCH_POINT_TO_FUNCTION);
 }
 
@@ -733,15 +806,16 @@
       """
       @patch class Class {}
       """);
-  print('testPatchNonClass.errors:${compiler.errors}');
-  print('testPatchNonClass.warnings:${compiler.warnings}');
-  Expect.equals(1, compiler.errors.length);
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  print('testPatchNonClass.errors:${collector.errors}');
+  print('testPatchNonClass.warnings:${collector.warnings}');
+  Expect.equals(1, collector.errors.length);
   Expect.isTrue(
-      compiler.errors[0].message.kind == MessageKind.PATCH_NON_CLASS);
-  Expect.equals(0, compiler.warnings.length);
-  Expect.equals(1, compiler.infos.length);
+      collector.errors.first.message.kind == MessageKind.PATCH_NON_CLASS);
+  Expect.equals(0, collector.warnings.length);
+  Expect.equals(1, collector.infos.length);
   Expect.isTrue(
-      compiler.infos[0].message.kind == MessageKind.PATCH_POINT_TO_CLASS);
+      collector.infos.first.message.kind == MessageKind.PATCH_POINT_TO_CLASS);
 }
 
 Future testPatchNonGetter() async {
@@ -752,15 +826,16 @@
       """
       @patch get foo => 0;
       """);
-  print('testPatchNonClass.errors:${compiler.errors}');
-  print('testPatchNonClass.warnings:${compiler.warnings}');
-  Expect.equals(1, compiler.errors.length);
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  print('testPatchNonClass.errors:${collector.errors}');
+  print('testPatchNonClass.warnings:${collector.warnings}');
+  Expect.equals(1, collector.errors.length);
   Expect.isTrue(
-      compiler.errors[0].message.kind == MessageKind.PATCH_NON_GETTER);
-  Expect.equals(0, compiler.warnings.length);
-  Expect.equals(1, compiler.infos.length);
+      collector.errors.first.message.kind == MessageKind.PATCH_NON_GETTER);
+  Expect.equals(0, collector.warnings.length);
+  Expect.equals(1, collector.infos.length);
   Expect.isTrue(
-      compiler.infos[0].message.kind == MessageKind.PATCH_POINT_TO_GETTER);
+      collector.infos.first.message.kind == MessageKind.PATCH_POINT_TO_GETTER);
 }
 
 Future testPatchNoGetter() async {
@@ -771,15 +846,16 @@
       """
       @patch get foo => 0;
       """);
-  print('testPatchNonClass.errors:${compiler.errors}');
-  print('testPatchNonClass.warnings:${compiler.warnings}');
-  Expect.equals(1, compiler.errors.length);
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  print('testPatchNonClass.errors:${collector.errors}');
+  print('testPatchNonClass.warnings:${collector.warnings}');
+  Expect.equals(1, collector.errors.length);
   Expect.isTrue(
-      compiler.errors[0].message.kind == MessageKind.PATCH_NO_GETTER);
-  Expect.equals(0, compiler.warnings.length);
-  Expect.equals(1, compiler.infos.length);
+      collector.errors.first.message.kind == MessageKind.PATCH_NO_GETTER);
+  Expect.equals(0, collector.warnings.length);
+  Expect.equals(1, collector.infos.length);
   Expect.isTrue(
-      compiler.infos[0].message.kind == MessageKind.PATCH_POINT_TO_GETTER);
+      collector.infos.first.message.kind == MessageKind.PATCH_POINT_TO_GETTER);
 }
 
 Future testPatchNonSetter() async {
@@ -790,15 +866,16 @@
       """
       @patch set foo(var value) {}
       """);
-  print('testPatchNonClass.errors:${compiler.errors}');
-  print('testPatchNonClass.warnings:${compiler.warnings}');
-  Expect.equals(1, compiler.errors.length);
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  print('testPatchNonClass.errors:${collector.errors}');
+  print('testPatchNonClass.warnings:${collector.warnings}');
+  Expect.equals(1, collector.errors.length);
   Expect.isTrue(
-      compiler.errors[0].message.kind == MessageKind.PATCH_NON_SETTER);
-  Expect.equals(0, compiler.warnings.length);
-  Expect.equals(1, compiler.infos.length);
+      collector.errors.first.message.kind == MessageKind.PATCH_NON_SETTER);
+  Expect.equals(0, collector.warnings.length);
+  Expect.equals(1, collector.infos.length);
   Expect.isTrue(
-      compiler.infos[0].message.kind == MessageKind.PATCH_POINT_TO_SETTER);
+      collector.infos.first.message.kind == MessageKind.PATCH_POINT_TO_SETTER);
 }
 
 Future testPatchNoSetter() async {
@@ -809,15 +886,16 @@
       """
       @patch set foo(var value) {}
       """);
-  print('testPatchNonClass.errors:${compiler.errors}');
-  print('testPatchNonClass.warnings:${compiler.warnings}');
-  Expect.equals(1, compiler.errors.length);
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  print('testPatchNonClass.errors:${collector.errors}');
+  print('testPatchNonClass.warnings:${collector.warnings}');
+  Expect.equals(1, collector.errors.length);
   Expect.isTrue(
-      compiler.errors[0].message.kind == MessageKind.PATCH_NO_SETTER);
-  Expect.equals(0, compiler.warnings.length);
-  Expect.equals(1, compiler.infos.length);
+      collector.errors.first.message.kind == MessageKind.PATCH_NO_SETTER);
+  Expect.equals(0, collector.warnings.length);
+  Expect.equals(1, collector.infos.length);
   Expect.isTrue(
-      compiler.infos[0].message.kind == MessageKind.PATCH_POINT_TO_SETTER);
+      collector.infos.first.message.kind == MessageKind.PATCH_POINT_TO_SETTER);
 }
 
 Future testPatchNonFunction() async {
@@ -828,15 +906,16 @@
       """
       @patch void foo() {}
       """);
-  print('testPatchNonClass.errors:${compiler.errors}');
-  print('testPatchNonClass.warnings:${compiler.warnings}');
-  Expect.equals(1, compiler.errors.length);
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  print('testPatchNonClass.errors:${collector.errors}');
+  print('testPatchNonClass.warnings:${collector.warnings}');
+  Expect.equals(1, collector.errors.length);
   Expect.isTrue(
-      compiler.errors[0].message.kind == MessageKind.PATCH_NON_FUNCTION);
-  Expect.equals(0, compiler.warnings.length);
-  Expect.equals(1, compiler.infos.length);
+      collector.errors.first.message.kind == MessageKind.PATCH_NON_FUNCTION);
+  Expect.equals(0, collector.warnings.length);
+  Expect.equals(1, collector.infos.length);
   Expect.isTrue(
-      compiler.infos[0].message.kind ==
+      collector.infos.first.message.kind ==
           MessageKind.PATCH_POINT_TO_FUNCTION);
 }
 
@@ -863,6 +942,7 @@
       """,
       runCompiler: true, analyzeOnly: true);
   World world = compiler.world;
+  world.populate();
 
   ClassElement cls = ensure(compiler, "A", compiler.coreLibrary.find,
                             expectIsPatched: true);
@@ -915,8 +995,9 @@
     var compiler = await applyPatch('', patchText, analyzeAll: true,
                analyzeOnly: true);
       compiler.librariesToAnalyzeWhenRun = [Uri.parse('dart:core')];
-    await compiler.runCompiler(null);
-    compareWarningKinds(patchText, expectedWarnings, compiler.warnings);
+    await compiler.run(null);
+    DiagnosticCollector collector = compiler.diagnosticCollector;
+    compareWarningKinds(patchText, expectedWarnings, collector.warnings);
   }
 
   await expect('String s = 0;', MessageKind.NOT_ASSIGNABLE);
@@ -972,7 +1053,7 @@
 
   ConstructorElement forwardTwo = clsA.lookupConstructor("forwardTwo");
   target = forwardTwo.effectiveTarget;
-  Expect.isFalse(forwardTwo.isErroneous);
+  Expect.isFalse(forwardTwo.isMalformed);
   Expect.isFalse(target.isPatch);
   Expect.equals("originTarget", target.name);
 }
@@ -987,9 +1068,10 @@
   var compiler = await applyPatch(originText, patchText,
              analyzeAll: true, analyzeOnly: true);
   compiler.librariesToAnalyzeWhenRun = [Uri.parse('dart:core')];
-  await compiler.runCompiler(null);
+  await compiler.run(null);
+  DiagnosticCollector collector = compiler.diagnosticCollector;
   compareWarningKinds(patchText,
-      [MessageKind.NOT_ASSIGNABLE], compiler.warnings);
+      [MessageKind.NOT_ASSIGNABLE], collector.warnings);
 }
 
 main() {
@@ -1001,8 +1083,10 @@
     await testPatchMember();
     await testPatchGetter();
     await testRegularMember();
-    await testGhostMember();
-    await testInjectFunction();
+    await testInjectedMember();
+    await testInjectedPublicMember();
+    await testInjectedFunction();
+    await testInjectedPublicFunction();
     await testPatchSignatureCheck();
 
     await testPatchVersioned();
diff --git a/tests/compiler/dart2js/platform_config_parser_test.dart b/tests/compiler/dart2js/platform_config_parser_test.dart
new file mode 100644
index 0000000..a25e2da
--- /dev/null
+++ b/tests/compiler/dart2js/platform_config_parser_test.dart
@@ -0,0 +1,130 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:compiler/src/platform_configuration.dart";
+import "package:expect/expect.dart";
+
+/// Runs the parser on [input] and compares it with [expectedResult]
+///
+/// A '*' in [input] indicates that the parser will report an error at the
+/// given point (On [input] with the "*" removed).
+test(String input, [Map<String, Map<String, String>> expectedOutput]) {
+  int starIndex = input.indexOf("*");
+  String inputWithoutStar = input.replaceFirst("*", "");
+
+  parse() => parseIni(inputWithoutStar.codeUnits,
+      allowedSections: new Set.from(["AA", "BB"]));
+
+  if (starIndex != -1) {
+    Expect.equals(expectedOutput, null);
+    Expect.throws(parse, (e) {
+      Expect.isTrue(e is FormatException);
+      Expect.equals(starIndex, e.offset);
+      return e is FormatException;
+    });
+  } else {
+    Map<String, Map<String, String>> result = parse();
+    Expect.equals(expectedOutput.length, result.length);
+    expectedOutput.forEach((String name, Map<String, String> properties) {
+      Expect.isTrue(expectedOutput.containsKey(name), "Missing section $name");
+      Expect.mapEquals(expectedOutput[name], properties);
+    });
+  }
+}
+
+main() {
+  // Empty file.
+  test(
+      """
+# Nothing here
+""",
+      {});
+
+  // Text outside section.
+  test("""
+*aaa
+""");
+
+  // Malformed header.
+  test("""
+*[AABC
+name:value
+""");
+
+  // Text after header.
+  test("""
+[AABC]*abcde
+""");
+
+  // Empty section name.
+  test("""
+[*]
+""");
+
+  // Duplicate section name.
+  test("""
+[AA]
+[BB]
+[*AA]
+""");
+
+  // Unrecognized section name.
+  test("""
+[*CC]
+""");
+
+  // Empty property name.
+  test("""
+[AA]
+*:value
+name:value
+""");
+
+  // Ok.
+  test(
+      """
+[AA]
+name:value
+[BB]
+name:value
+name2:value2
+""",
+      {
+    "AA": {"name": "value"},
+    "BB": {"name": "value", "name2": "value2"}
+  });
+
+  // Ok, file not ending in newline.
+  test(
+      """
+[AA]
+name:value""",
+      {
+    "A": {"name": "value"}
+  });
+
+  // Ok, whitespace is trimmed away.
+  test(
+      """
+[ AA ]
+ name\t:  value """,
+      {
+        "A": {"name": "value"}
+      });
+
+  // Duplicate property name.
+  test("""
+[AA]
+a:b
+b:c
+*a:c
+""");
+
+  // No ':' on property line.
+  test("""
+[AA]
+*name1
+name2:value
+""");
+}
diff --git a/tests/compiler/dart2js/platform_consistency_test.dart b/tests/compiler/dart2js/platform_consistency_test.dart
new file mode 100644
index 0000000..e946c16
--- /dev/null
+++ b/tests/compiler/dart2js/platform_consistency_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2015, the Fletch 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.md file.
+
+import "package:compiler/src/platform_configuration.dart";
+import "package:compiler/src/source_file_provider.dart";
+import "package:compiler/compiler_new.dart";
+import "package:expect/expect.dart";
+
+Uri unsupported =  Uri.parse("unsupported:");
+
+main() async {
+  CompilerInput input = new CompilerSourceFileProvider();
+  Map<String, Uri> client = await load(
+      Uri.base.resolve("sdk/lib/dart_client.platform"),
+      input);
+  Map<String, Uri> server = await load(
+      Uri.base.resolve("sdk/lib/dart_server.platform"),
+      input);
+  Map<String, Uri> shared = await load(
+      Uri.base.resolve("sdk/lib/dart_shared.platform"),
+      input);
+  Map<String, Uri> dart2dart = await load(
+      Uri.base.resolve("sdk/lib/dart2dart.platform"),
+      input);
+  Expect.setEquals(new Set.from(shared.keys), new Set.from(client.keys));
+  Expect.setEquals(new Set.from(shared.keys), new Set.from(server.keys));
+  Expect.setEquals(new Set.from(shared.keys), new Set.from(dart2dart.keys));
+
+  for (String libraryName in shared.keys) {
+    test(Map<String, Uri> m) {
+      if (m[libraryName] != unsupported &&
+          shared[libraryName] != unsupported) {
+        Expect.equals(shared[libraryName], m[libraryName]);
+      }
+    }
+    test(client);
+    test(server);
+    test(dart2dart);
+  }
+ }
diff --git a/tests/compiler/dart2js/private_test.dart b/tests/compiler/dart2js/private_test.dart
index ed55d66..fbfba80 100644
--- a/tests/compiler/dart2js/private_test.dart
+++ b/tests/compiler/dart2js/private_test.dart
@@ -71,8 +71,9 @@
                     ''';
     Uri uri = Uri.parse('src:public');
     compiler.registerSource(uri, source);
-    return compiler.runCompiler(uri).then((_) {
-      compareWarningKinds(text, expectedWarnings, compiler.warnings);
+    return compiler.run(uri).then((_) {
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      compareWarningKinds(text, expectedWarnings, collector.warnings);
     });
   };
 }
diff --git a/tests/compiler/dart2js/related_types.dart b/tests/compiler/dart2js/related_types.dart
index d4d26d2..12b60c5 100644
--- a/tests/compiler/dart2js/related_types.dart
+++ b/tests/compiler/dart2js/related_types.dart
@@ -78,6 +78,8 @@
 
   ClassWorld get world => compiler.world;
 
+  CoreClasses get coreClasses => compiler.coreClasses;
+
   CoreTypes get coreTypes => compiler.coreTypes;
 
   DiagnosticReporter get reporter => compiler.reporter;
@@ -167,7 +169,7 @@
 
   /// Returns the supertype of [receiver] that implements `Iterable`, if any.
   InterfaceType findIterableType(DartType receiver) {
-    return findClassType(receiver, compiler.iterableClass);
+    return findClassType(receiver, coreClasses.iterableClass);
   }
 
   /// Returns the element type of the supertype of [receiver] that implements
@@ -179,7 +181,7 @@
 
   /// Returns the supertype of [receiver] that implements `Map`, if any.
   InterfaceType findMapType(DartType receiver) {
-    return findClassType(receiver, compiler.mapClass);
+    return findClassType(receiver, coreClasses.mapClass);
   }
 
   /// Returns the key type of the supertype of [receiver] that implements
@@ -198,7 +200,7 @@
 
   /// Returns the supertype of [receiver] that implements `List`, if any.
   InterfaceType findListType(DartType receiver) {
-    return findClassType(receiver, compiler.listClass);
+    return findClassType(receiver, coreClasses.listClass);
   }
 
   /// Returns the element type of the supertype of [receiver] that implements
diff --git a/tests/compiler/dart2js/resolution_test.dart b/tests/compiler/dart2js/resolution_test.dart
index 639755a..3087ee1 100644
--- a/tests/compiler/dart2js/resolution_test.dart
+++ b/tests/compiler/dart2js/resolution_test.dart
@@ -92,24 +92,24 @@
 }
 """;
 
-void test(String code, void check(Compiler compiler)) {
+void test(String code, void check(CompilerImpl compiler)) {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(code, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     check(compiler);
   }));
 }
 
 void testHasRuntimeType(String code) {
   test(code, (compiler) {
-    var element = compiler.backend.findHelper('createRuntimeType');
+    var element = compiler.backend.helpers.createRuntimeType;
     Expect.isTrue(compiler.enqueuer.resolution.isProcessed(element));
   });
 }
 
 main() {
   test(NO_RUNTIME_TYPE, (compiler) {
-    var element = compiler.backend.findHelper('createRuntimeType');
+    var element = compiler.backend.helpers.createRuntimeType;
     Expect.isFalse(compiler.enqueuer.resolution.isProcessed(element));
   });
 
diff --git a/tests/compiler/dart2js/resolver_test.dart b/tests/compiler/dart2js/resolver_test.dart
index 236b0bd..bc5878e 100644
--- a/tests/compiler/dart2js/resolver_test.dart
+++ b/tests/compiler/dart2js/resolver_test.dart
@@ -132,11 +132,12 @@
 """);
       compiler.resolveStatement("Bar bar;");
       ClassElement classBar = compiler.mainApp.find("Bar");
-      Expect.equals(0, compiler.warnings.length);
-      Expect.equals(1, compiler.errors.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length);
+      Expect.equals(1, collector.errors.length);
       Expect.equals(MessageKind.MULTI_INHERITANCE,
-                    compiler.errors[0].message.kind);
-      Expect.equals(0, compiler.crashes.length);
+                    collector.errors.first.message.kind);
+      Expect.equals(0, collector.crashes.length);
     }),
   ]);
 }
@@ -163,7 +164,8 @@
       compiler.parseScript('class Foo<T, U> {}');
       ClassElement foo = compiler.mainApp.find('Foo');
       matchResolvedTypes(visitor, 'Foo<int, String> x;', 'Foo',
-                         [compiler.intClass, compiler.stringClass]);
+                         [compiler.coreClasses.intClass,
+                          compiler.coreClasses.stringClass]);
       matchResolvedTypes(visitor, 'Foo<Foo, Foo> x;', 'Foo',
                          [foo, foo]);
     }),
@@ -171,19 +173,21 @@
     MockCompiler.create((MockCompiler compiler) {
       compiler.parseScript('class Foo<T, U> {}');
       compiler.resolveStatement('Foo<notype, int> x;');
-      Expect.equals(1, compiler.warnings.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(1, collector.warnings.length);
       Expect.equals(MessageKind.CANNOT_RESOLVE_TYPE,
-                    compiler.warnings[0].message.kind);
-      Expect.equals(0, compiler.errors.length);
+                    collector.warnings.first.message.kind);
+      Expect.equals(0, collector.errors.length);
     }),
 
     MockCompiler.create((MockCompiler compiler) {
       compiler.parseScript('class Foo<T, U> {}');
       compiler.resolveStatement('var x = new Foo<notype, int>();');
-      Expect.equals(1, compiler.warnings.length);
-      Expect.equals(0, compiler.errors.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(1, collector.warnings.length);
+      Expect.equals(0, collector.errors.length);
       Expect.equals(MessageKind.CANNOT_RESOLVE_TYPE,
-                    compiler.warnings[0].message.kind);
+                    collector.warnings.first.message.kind);
     }),
 
     MockCompiler.create((MockCompiler compiler) {
@@ -197,8 +201,9 @@
       foo.lookupLocalMember('t').computeType(compiler.resolution);
       foo.lookupLocalMember('foo').computeType(compiler.resolution);
       compiler.resolver.resolve(foo.lookupLocalMember('bar'));
-      Expect.equals(0, compiler.warnings.length);
-      Expect.equals(0, compiler.errors.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length);
+      Expect.equals(0, collector.errors.length);
     }),
   ]);
 }
@@ -239,15 +244,16 @@
     ClassElement fooElement = compiler.mainApp.find("Foo");
     FunctionElement funElement = fooElement.lookupLocalMember("foo");
     compiler.processQueue(compiler.enqueuer.resolution, funElement);
-    Expect.equals(0, compiler.warnings.length);
-    Expect.equals(1, compiler.errors.length);
+    DiagnosticCollector collector = compiler.diagnosticCollector;
+    Expect.equals(0, collector.warnings.length);
+    Expect.equals(1, collector.errors.length);
     Expect.equals(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL,
-                  compiler.errors[0].message.kind);
-    Expect.equals(2, compiler.infos.length);
+                  collector.errors.first.message.kind);
+    Expect.equals(2, collector.infos.length);
     Expect.equals(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE,
-                  compiler.infos[0].message.kind);
+                  collector.infos.first.message.kind);
     Expect.equals(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE,
-                  compiler.infos[1].message.kind);
+                  collector.infos.elementAt(1).message.kind);
   });
 }
 
@@ -267,15 +273,17 @@
       visitor.visit(function.body);
       Map mapping = map(visitor);
       List<Element> values = mapping.values.toList();
+      DiagnosticCollector collector = compiler.diagnosticCollector;
       Expect.equals(0, mapping.length);
-      Expect.equals(0, compiler.warnings.length);
+      Expect.equals(0, collector.warnings.length);
     }),
     MockCompiler.create((MockCompiler compiler) {
       compiler.resolveStatement("main() { return this; }");
-      Expect.equals(0, compiler.warnings.length);
-      Expect.equals(1, compiler.errors.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length);
+      Expect.equals(1, collector.errors.length);
       Expect.equals(MessageKind.NO_INSTANCE_AVAILABLE,
-                    compiler.errors[0].message.kind);
+                    collector.errors.first.message.kind);
     }),
     MockCompiler.create((MockCompiler compiler) {
       compiler.parseScript("class Foo { static foo() { return this; } }");
@@ -288,10 +296,11 @@
       FunctionExpression function =
           (funElement as FunctionElementX).parseNode(compiler.parsing);
       visitor.visit(function.body);
-      Expect.equals(0, compiler.warnings.length);
-      Expect.equals(1, compiler.errors.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length);
+      Expect.equals(1, collector.errors.length);
       Expect.equals(MessageKind.NO_INSTANCE_AVAILABLE,
-                    compiler.errors[0].message.kind);
+                    collector.errors.first.message.kind);
     }),
   ]);
 }
@@ -312,12 +321,13 @@
 
       () => testLocals([["foo", false], ["foo", false]])
           .then((MockCompiler compiler) {
-      Expect.equals(1, compiler.errors.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(1, collector.errors.length);
       Expect.equals(
           new Message(
               MessageTemplate.TEMPLATES[MessageKind.DUPLICATE_DEFINITION],
               {'name': 'foo'}, false),
-          compiler.errors[0].message);
+          collector.errors.first.message);
     })], (f) => f());
 }
 
@@ -485,29 +495,26 @@
     Map mapping = compiler.resolveStatement(statement).map;
 
     Expect.equals(1, mapping.length); // Only [bar] has an element.
-    Expect.equals(1, compiler.warnings.length);
-
-    Node warningNode = compiler.warnings[0].node;
+    DiagnosticCollector collector = compiler.diagnosticCollector;
+    Expect.equals(1, collector.warnings.length);
 
     Expect.equals(
         new Message(
             MessageTemplate.TEMPLATES[MessageKind.CANNOT_RESOLVE_TYPE],
             {'typeName': 'Foo'}, false),
-        compiler.warnings[0].message);
-    VariableDefinitions definition = compiler.parsedTree;
-    Expect.equals(warningNode, definition.type);
-    compiler.clearMessages();
+        collector.warnings.first.message);
+    collector.clear();
 
     // Test that there is no warning after defining Foo.
     compiler.parseScript("class Foo {}");
     mapping = compiler.resolveStatement(statement).map;
     Expect.equals(1, mapping.length);
-    Expect.equals(0, compiler.warnings.length);
+    Expect.equals(0, collector.warnings.length);
 
     // Test that 'var' does not create a warning.
     mapping = compiler.resolveStatement("var foo;").map;
     Expect.equals(1, mapping.length);
-    Expect.equals(0, compiler.warnings.length);
+    Expect.equals(0, collector.warnings.length);
   });
 }
 
@@ -516,12 +523,13 @@
     MockCompiler.create((MockCompiler compiler) {
       compiler.parseScript("class Foo extends Bar {}");
       compiler.resolveStatement("Foo bar;");
-      Expect.equals(1, compiler.errors.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(1, collector.errors.length);
       var cannotResolveBar = new Message(
           MessageTemplate.TEMPLATES[MessageKind.CANNOT_EXTEND_MALFORMED],
           {'className': 'Foo', 'malformedType': 'Bar'}, false);
-      Expect.equals(cannotResolveBar, compiler.errors[0].message);
-      compiler.clearMessages();
+      Expect.equals(cannotResolveBar, collector.errors.first.message);
+      collector.clear();
     }),
     MockCompiler.create((MockCompiler compiler) {
       compiler.parseScript("class Foo extends Bar {}");
@@ -543,13 +551,14 @@
   return MockCompiler.create((MockCompiler compiler) {
     compiler.parseScript("class Foo extends var {}");
     compiler.resolveStatement("Foo bar;");
-    Expect.equals(1, compiler.errors.length);
+    DiagnosticCollector collector = compiler.diagnosticCollector;
+    Expect.equals(1, collector.errors.length);
     Expect.equals(
         new Message(
             MessageTemplate.TEMPLATES[MessageKind.CANNOT_RESOLVE_TYPE],
             {'typeName': 'var'}, false),
-        compiler.errors[0].message);
-    compiler.clearMessages();
+        collector.errors.first.message);
+    collector.clear();
   });
 }
 
@@ -557,13 +566,14 @@
   return MockCompiler.create((MockCompiler compiler) {
     compiler.parseScript("class Foo implements Bar {}");
     compiler.resolveStatement("Foo bar;");
-    Expect.equals(1, compiler.errors.length);
+    DiagnosticCollector collector = compiler.diagnosticCollector;
+    Expect.equals(1, collector.errors.length);
     Expect.equals(
         new Message(
             MessageTemplate.TEMPLATES[MessageKind.CANNOT_RESOLVE_TYPE],
             {'typeName': 'bar'}, false),
-        compiler.errors[0].message);
-    compiler.clearMessages();
+        collector.errors.first.message);
+    collector.clear();
 
     // Add the abstract class to the world and make sure everything is setup
     // correctly.
@@ -698,9 +708,10 @@
     Expect.equals(expectedElementCount, map(visitor).length,
         "${map(visitor).values} for '$statement' in context of `$script`");
 
-    compareWarningKinds(script, expectedWarnings, compiler.warnings);
-    compareWarningKinds(script, expectedErrors, compiler.errors);
-    compareWarningKinds(script, expectedInfos, compiler.infos);
+    DiagnosticCollector collector = compiler.diagnosticCollector;
+    compareWarningKinds(script, expectedWarnings, collector.warnings);
+    compareWarningKinds(script, expectedErrors, collector.errors);
+    compareWarningKinds(script, expectedInfos, collector.infos);
   });
 }
 
@@ -712,10 +723,11 @@
                               main() { return new A(); }""");
       FunctionElement mainElement = compiler.mainApp.find(MAIN);
       compiler.resolver.resolve(mainElement);
-      Expect.equals(0, compiler.warnings.length);
-      Expect.equals(1, compiler.errors.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length);
+      Expect.equals(1, collector.errors.length);
       Expect.equals(MessageKind.CYCLIC_CLASS_HIERARCHY,
-                    compiler.errors[0].message.kind);
+                    collector.errors.first.message.kind);
     }),
     MockCompiler.create((MockCompiler compiler) {
       compiler.parseScript("""class A extends B {}
@@ -723,12 +735,13 @@
                               main() { return new A(); }""");
       FunctionElement mainElement = compiler.mainApp.find(MAIN);
       compiler.resolver.resolve(mainElement);
-      Expect.equals(0, compiler.warnings.length);
-      Expect.equals(2, compiler.errors.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length);
+      Expect.equals(2, collector.errors.length);
       Expect.equals(MessageKind.CYCLIC_CLASS_HIERARCHY,
-                    compiler.errors[0].message.kind);
-      Expect.equals(MessageKind.CANNOT_FIND_CONSTRUCTOR,
-                    compiler.errors[1].message.kind);
+                    collector.errors.first.message.kind);
+      Expect.equals(MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR,
+                    collector.errors.elementAt(1).message.kind);
     }),
     MockCompiler.create((MockCompiler compiler) {
       compiler.parseScript("""abstract class A extends B {}
@@ -737,10 +750,11 @@
                               main() { return new C(); }""");
       FunctionElement mainElement = compiler.mainApp.find(MAIN);
       compiler.resolver.resolve(mainElement);
-      Expect.equals(0, compiler.warnings.length);
-      Expect.equals(1, compiler.errors.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length);
+      Expect.equals(1, collector.errors.length);
       Expect.equals(MessageKind.CYCLIC_CLASS_HIERARCHY,
-                    compiler.errors[0].message.kind);
+                    collector.errors.first.message.kind);
     }),
     MockCompiler.create((MockCompiler compiler) {
       compiler.parseScript("""class A extends B {}
@@ -749,8 +763,9 @@
                               main() { return new A(); }""");
       FunctionElement mainElement = compiler.mainApp.find(MAIN);
       compiler.resolver.resolve(mainElement);
-      Expect.equals(0, compiler.warnings.length);
-      Expect.equals(0, compiler.errors.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length);
+      Expect.equals(0, collector.errors.length);
       ClassElement aElement = compiler.mainApp.find("A");
       Link<DartType> supertypes = aElement.allSupertypes;
       Expect.equals(<String>['B', 'C', 'Object'].toString(),
@@ -765,8 +780,9 @@
                               main() { return new C(); }""");
       FunctionElement mainElement = compiler.mainApp.find(MAIN);
       compiler.resolver.resolve(mainElement);
-      Expect.equals(0, compiler.warnings.length);
-      Expect.equals(0, compiler.errors.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length);
+      Expect.equals(0, collector.errors.length);
       ClassElement aElement = compiler.mainApp.find("C");
       Link<DartType> supertypes = aElement.allSupertypes;
       // Object is once per inheritance path, that is from both A and I.
@@ -781,8 +797,9 @@
                               main() { return new E(); }""");
       FunctionElement mainElement = compiler.mainApp.find(MAIN);
       compiler.resolver.resolve(mainElement);
-      Expect.equals(0, compiler.warnings.length);
-      Expect.equals(0, compiler.errors.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length);
+      Expect.equals(0, collector.errors.length);
       ClassElement aElement = compiler.mainApp.find("E");
       Link<DartType> supertypes = aElement.allSupertypes;
       Expect.equals(<String>['A<E>', 'D', 'Object'].toString(),
@@ -794,11 +811,12 @@
                               main() { return new D(); }""");
       FunctionElement mainElement = compiler.mainApp.find(MAIN);
       compiler.resolver.resolve(mainElement);
-      Expect.equals(0, compiler.warnings.length);
-      Expect.equals(1, compiler.errors.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length);
+      Expect.equals(1, collector.errors.length);
       Expect.equals(MessageKind.MULTI_INHERITANCE,
-                    compiler.errors[0].message.kind);
-      Expect.equals(0, compiler.crashes.length);
+                    collector.errors.first.message.kind);
+      Expect.equals(0, collector.crashes.length);
     }),
   ]);
 }
@@ -811,10 +829,11 @@
                               main() { Enum e; }""");
       FunctionElement mainElement = compiler.mainApp.find(MAIN);
       compiler.resolver.resolve(mainElement);
-      Expect.equals(0, compiler.warnings.length,
-                    'Unexpected warnings: ${compiler.warnings}');
-      Expect.equals(1, compiler.errors.length,
-                    'Unexpected errors: ${compiler.errors}');
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length,
+                    'Unexpected warnings: ${collector.warnings}');
+      Expect.equals(1, collector.errors.length,
+                    'Unexpected errors: ${collector.errors}');
     }),
 
     MockCompiler.create((MockCompiler compiler) {
@@ -822,10 +841,11 @@
                               main() { Enum e = Enum.A; }""");
       FunctionElement mainElement = compiler.mainApp.find(MAIN);
       compiler.resolver.resolve(mainElement);
-      Expect.equals(0, compiler.warnings.length,
-                    'Unexpected warnings: ${compiler.warnings}');
-      Expect.equals(0, compiler.errors.length,
-                    'Unexpected errors: ${compiler.errors}');
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length,
+                    'Unexpected warnings: ${collector.warnings}');
+      Expect.equals(0, collector.errors.length,
+                    'Unexpected errors: ${collector.errors}');
     }),
 
     MockCompiler.create((MockCompiler compiler) {
@@ -833,12 +853,13 @@
                               main() { Enum e = Enum.B; }""");
       FunctionElement mainElement = compiler.mainApp.find(MAIN);
       compiler.resolver.resolve(mainElement);
-      Expect.equals(1, compiler.warnings.length,
-                    'Unexpected warnings: ${compiler.warnings}');
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(1, collector.warnings.length,
+                    'Unexpected warnings: ${collector.warnings}');
       Expect.equals(MessageKind.MEMBER_NOT_FOUND,
-                    compiler.warnings[0].message.kind);
-      Expect.equals(0, compiler.errors.length,
-                    'Unexpected errors: ${compiler.errors}');
+                    collector.warnings.first.message.kind);
+      Expect.equals(0, collector.errors.length,
+                    'Unexpected errors: ${collector.errors}');
     }),
 
     MockCompiler.create((MockCompiler compiler) {
@@ -846,10 +867,11 @@
                               main() { List values = Enum.values; }""");
       FunctionElement mainElement = compiler.mainApp.find(MAIN);
       compiler.resolver.resolve(mainElement);
-      Expect.equals(0, compiler.warnings.length,
-                    'Unexpected warnings: ${compiler.warnings}');
-      Expect.equals(0, compiler.errors.length,
-                    'Unexpected errors: ${compiler.errors}');
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length,
+                    'Unexpected warnings: ${collector.warnings}');
+      Expect.equals(0, collector.errors.length,
+                    'Unexpected errors: ${collector.errors}');
     }),
 
     MockCompiler.create((MockCompiler compiler) {
@@ -857,12 +879,13 @@
                               main() { new Enum(0, ''); }""");
       FunctionElement mainElement = compiler.mainApp.find(MAIN);
       compiler.resolver.resolve(mainElement);
-      Expect.equals(0, compiler.warnings.length,
-                    'Unexpected warnings: ${compiler.warnings}');
-      Expect.equals(1, compiler.errors.length,
-                    'Unexpected errors: ${compiler.errors}');
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length,
+                    'Unexpected warnings: ${collector.warnings}');
+      Expect.equals(1, collector.errors.length,
+                    'Unexpected errors: ${collector.errors}');
       Expect.equals(MessageKind.CANNOT_INSTANTIATE_ENUM,
-                    compiler.errors[0].message.kind);
+                    collector.errors.first.message.kind);
     }),
 
     MockCompiler.create((MockCompiler compiler) {
@@ -870,12 +893,13 @@
                               main() { const Enum(0, ''); }""");
       FunctionElement mainElement = compiler.mainApp.find(MAIN);
       compiler.resolver.resolve(mainElement);
-      Expect.equals(0, compiler.warnings.length,
-                    'Unexpected warnings: ${compiler.warnings}');
-      Expect.equals(1, compiler.errors.length,
-                    'Unexpected errors: ${compiler.errors}');
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length,
+                    'Unexpected warnings: ${collector.warnings}');
+      Expect.equals(1, collector.errors.length,
+                    'Unexpected errors: ${collector.errors}');
       Expect.equals(MessageKind.CANNOT_INSTANTIATE_ENUM,
-                    compiler.errors[0].message.kind);
+                    collector.errors.first.message.kind);
     }),
   ]);
 }
@@ -1038,8 +1062,9 @@
       CollectingTreeElements elements =
           compiler.resolveStatement("main() => $constant;");
       List<String> expectedConstants = testedConstants[constant];
-      Expect.equals(0, compiler.warnings.length);
-      Expect.equals(0, compiler.errors.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length);
+      Expect.equals(0, collector.errors.length);
       List<ConstantExpression> constants = elements.constants;
       String constantsText =
           '[${constants.map((c) => c.getText()).join(', ')}]';
@@ -1073,7 +1098,7 @@
   Uri uri = new Uri(scheme: 'source');
   MockCompiler compiler = compilerFor(source, uri);
   compiler.diagnosticHandler = createHandler(compiler, source);
-  return compiler.runCompiler(uri).then((_) {
+  return compiler.run(uri).then((_) {
     return compiler;
   });
 }
@@ -1147,25 +1172,27 @@
         new A() == new B();
       }""";
   asyncTest(() => compileScript(script).then((compiler) {
-    Expect.equals(0, compiler.warnings.length);
-    Expect.equals(0, compiler.infos.length);
-    Expect.equals(1, compiler.hints.length);
+    DiagnosticCollector collector = compiler.diagnosticCollector;
+    Expect.equals(0, collector.warnings.length);
+    Expect.equals(0, collector.infos.length);
+    Expect.equals(1, collector.hints.length);
     Expect.equals(MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE,
-                  compiler.hints[0].message.kind);
-    Expect.equals(0, compiler.errors.length);
+                  collector.hints.first.message.kind);
+    Expect.equals(0, collector.errors.length);
   }));
 }
 
 testConstConstructorAndNonFinalFields() {
   void expect(compiler, List errors, List infos) {
-    Expect.equals(errors.length, compiler.errors.length);
+    DiagnosticCollector collector = compiler.diagnosticCollector;
+    Expect.equals(errors.length, collector.errors.length);
     for (int i = 0 ; i < errors.length ; i++) {
-      Expect.equals(errors[i], compiler.errors[i].message.kind);
+      Expect.equals(errors[i], collector.errors.elementAt(i).message.kind);
     }
-    Expect.equals(0, compiler.warnings.length);
-    Expect.equals(infos.length, compiler.infos.length);
+    Expect.equals(0, collector.warnings.length);
+    Expect.equals(infos.length, collector.infos.length);
     for (int i = 0 ; i < infos.length ; i++) {
-      Expect.equals(infos[i], compiler.infos[i].message.kind);
+      Expect.equals(infos[i], collector.infos.elementAt(i).message.kind);
     }
   }
 
@@ -1369,13 +1396,14 @@
 checkWarningOn(String script, List<MessageKind> warnings) {
   Expect.isTrue(warnings.length >= 0 && warnings.length <= 2);
   asyncTest(() => compileScript(script).then((compiler) {
-    Expect.equals(0, compiler.errors.length,
-        'Unexpected errors in\n$script\n${compiler.errors}');
-    Expect.equals(warnings.length, compiler.warnings.length,
+    DiagnosticCollector collector = compiler.diagnosticCollector;
+    Expect.equals(0, collector.errors.length,
+        'Unexpected errors in\n$script\n${collector.errors}');
+    Expect.equals(warnings.length, collector.warnings.length,
         'Unexpected warnings in\n$script\n'
-        'Expected:$warnings\nFound:${compiler.warnings}');
+        'Expected:$warnings\nFound:${collector.warnings}');
     for (int i = 0; i < warnings.length; i++) {
-      Expect.equals(warnings[i], compiler.warnings[i].message.kind);
+      Expect.equals(warnings[i], collector.warnings.elementAt(i).message.kind);
     }
   }));
 }
@@ -1388,11 +1416,12 @@
     var where = functionName == null
         ? 'the enclosing function' : "'$functionName'";
     asyncTest(() => compileScript(script).then((compiler) {
-      Expect.equals(0, compiler.errors.length);
-      Expect.equals(1, compiler.warnings.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.errors.length);
+      Expect.equals(1, collector.warnings.length);
       Expect.equals("$prefix.\n"
           "Did you mean to add the 'async' marker to $where?",
-          '${compiler.warnings[0].message}');
+          '${collector.warnings.first.message}');
     }));
   }
   check('main() { await -3; }', functionName: 'main');
diff --git a/tests/compiler/dart2js/semantic_visitor_test.dart b/tests/compiler/dart2js/semantic_visitor_test.dart
index f8ea57f..72f93e1 100644
--- a/tests/compiler/dart2js/semantic_visitor_test.dart
+++ b/tests/compiler/dart2js/semantic_visitor_test.dart
@@ -313,14 +313,14 @@
     }
     var expectedVisits = test.expectedVisits;
     if (expectedVisits == null) {
-      Expect.isTrue(element.isErroneous,
+      Expect.isTrue(element.isMalformed,
           "Element '$method' expected to be have parse errors in:\n"
           "${library.compilationUnit.script.text}");
       return;
     } else if (expectedVisits is! List) {
       expectedVisits = [expectedVisits];
     }
-    Expect.isFalse(element.isErroneous,
+    Expect.isFalse(element.isMalformed,
         "Element '$method' is not expected to be have parse errors in:\n"
         "${library.compilationUnit.script.text}");
 
diff --git a/tests/compiler/dart2js/semantic_visitor_test_decl_data.dart b/tests/compiler/dart2js/semantic_visitor_test_decl_data.dart
index f31b688..1019d8c 100644
--- a/tests/compiler/dart2js/semantic_visitor_test_decl_data.dart
+++ b/tests/compiler/dart2js/semantic_visitor_test_decl_data.dart
@@ -536,7 +536,7 @@
         ''',
         const [
           const Visit(VisitKind.VISIT_FACTORY_CONSTRUCTOR_DECL,
-              element: 'function(C#)',
+              element: 'factory_constructor(C#)',
               parameters: '(a,b)',
               body: '=>null;'),
           const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
@@ -556,7 +556,7 @@
         ''',
         const [
           const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,
-              element: 'function(C#)',
+              element: 'factory_constructor(C#)',
               parameters: '(a,b)',
               target: 'generative_constructor(C#_)',
               type: 'C'),
@@ -579,7 +579,7 @@
         ''',
         const [
           const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,
-              element: 'function(C#)',
+              element: 'factory_constructor(C#)',
               parameters: '(a,b)',
               target: 'generative_constructor(D#)',
               type: 'D'),
@@ -602,7 +602,7 @@
         ''',
         const [
           const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,
-              element: 'function(C#)',
+              element: 'factory_constructor(C#)',
               parameters: '(a,b)',
               target: 'generative_constructor(D#)',
               type: 'D<int>'),
@@ -628,9 +628,9 @@
         ''',
         const [
           const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,
-              element: 'function(C#)',
+              element: 'factory_constructor(C#)',
               parameters: '(a,b)',
-              target: 'function(D#)',
+              target: 'factory_constructor(D#)',
               type: 'D<int>'),
           const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
               element: 'parameter(#a)',
diff --git a/tests/compiler/dart2js/semantic_visitor_test_send_data.dart b/tests/compiler/dart2js/semantic_visitor_test_send_data.dart
index c407766..a0fd164 100644
--- a/tests/compiler/dart2js/semantic_visitor_test_send_data.dart
+++ b/tests/compiler/dart2js/semantic_visitor_test_send_data.dart
@@ -803,6 +803,13 @@
         const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_SET,
                     element: 'field(o)',
                     rhs: '42')),
+    const Test.prefix(
+        '''
+        ''',
+        'm() { p = 42; }',
+        const Visit(VisitKind.ERROR_INVALID_SET,
+                    error: MessageKind.PREFIX_AS_EXPRESSION,
+                    rhs: '42')),
     const Test(
         '''
         final o = 0;
@@ -851,6 +858,13 @@
         const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_INVOKE,
                     element: 'field(o)',
                     arguments: '(null,42)')),
+    const Test.prefix(
+        '''
+        ''',
+        'm() { p(null, 42); }',
+        const Visit(VisitKind.ERROR_INVALID_INVOKE,
+                    error: MessageKind.PREFIX_AS_EXPRESSION,
+                    arguments: '(null,42)')),
     const Test(
         '''
         m() => o;
@@ -2414,6 +2428,16 @@
                     error: MessageKind.NO_INSTANCE_AVAILABLE,
                     operator: '+=',
                     rhs: '42')),
+    const Test.prefix(
+        '''
+        ''',
+        '''
+        m() { p += 42; }
+        ''',
+        const Visit(VisitKind.ERROR_INVALID_COMPOUND,
+                    error: MessageKind.PREFIX_AS_EXPRESSION,
+                    operator: '+=',
+                    rhs: '42')),
     const Test(
         '''
         class C {
@@ -2933,6 +2957,15 @@
         const Visit(VisitKind.ERROR_INVALID_PREFIX,
                     error: MessageKind.NO_INSTANCE_AVAILABLE,
                     operator: '++')),
+    const Test.prefix(
+        '''
+        ''',
+        '''
+        m() { ++p; }
+        ''',
+        const Visit(VisitKind.ERROR_INVALID_PREFIX,
+                    error: MessageKind.PREFIX_AS_EXPRESSION,
+                    operator: '++')),
     const Test(
         '''
         class C {
@@ -3318,6 +3351,15 @@
         const Visit(VisitKind.ERROR_INVALID_POSTFIX,
                     error: MessageKind.NO_INSTANCE_AVAILABLE,
                     operator: '--')),
+    const Test.prefix(
+        '''
+        ''',
+        '''
+        m() { p--; }
+        ''',
+        const Visit(VisitKind.ERROR_INVALID_POSTFIX,
+                    error: MessageKind.PREFIX_AS_EXPRESSION,
+                    operator: '--')),
     const Test(
         '''
         class C {
@@ -3715,7 +3757,7 @@
         m() => new Class(true, 42);
         ''',
         const Visit(VisitKind.VISIT_FACTORY_CONSTRUCTOR_INVOKE,
-            element: 'function(Class#)',
+            element: 'factory_constructor(Class#)',
             arguments: '(true,42)',
             type: 'Class',
             selector: 'CallStructure(arity=2)')),
@@ -3728,7 +3770,7 @@
         m() => new Class(true, 42);
         ''',
         const Visit(VisitKind.VISIT_CONSTRUCTOR_INCOMPATIBLE_INVOKE,
-            element: 'function(Class#)',
+            element: 'factory_constructor(Class#)',
             arguments: '(true,42)',
             type: 'Class',
             selector: 'CallStructure(arity=2)')),
@@ -3742,7 +3784,7 @@
         m() => new Class<double>(true, 42);
         ''',
         const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
-            element: 'function(Class#)',
+            element: 'factory_constructor(Class#)',
             arguments: '(true,42)',
             type: 'Class<double>',
             target: 'generative_constructor(Class#b)',
@@ -3758,7 +3800,7 @@
         m() => new Class<double>(true, 42);
         ''',
         const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
-            element: 'function(Class#)',
+            element: 'factory_constructor(Class#)',
             arguments: '(true,42)',
             type: 'Class<double>',
             target: 'generative_constructor(Class#b)',
@@ -3774,7 +3816,7 @@
         ''',
         const Visit(
             VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
-            element: 'function(Class#)',
+            element: 'factory_constructor(Class#)',
             arguments: '(true,42)',
             type: 'Class',
             selector: 'CallStructure(arity=2)')),
@@ -3789,7 +3831,7 @@
         ''',
         const Visit(
             VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
-            element: 'function(Class#)',
+            element: 'factory_constructor(Class#)',
             arguments: '(true,42)',
             type: 'Class<double>',
             selector: 'CallStructure(arity=2)')),
@@ -3830,7 +3872,7 @@
         ''',
         const Visit(
             VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
-            element: 'function(Class#)',
+            element: 'factory_constructor(Class#)',
             arguments: '(true,42)',
             type: 'Class',
             selector: 'CallStructure(arity=2)')),
@@ -3843,7 +3885,7 @@
         ''',
         const Visit(
             VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
-            element: 'function(Class#)',
+            element: 'factory_constructor(Class#)',
             arguments: '(true,42)',
             type: 'Class',
             selector: 'CallStructure(arity=2)')),
@@ -3857,7 +3899,7 @@
         ''',
         const Visit(
             VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
-            element: 'function(Class#)',
+            element: 'factory_constructor(Class#)',
             arguments: '(true,42)',
             type: 'Class',
             selector: 'CallStructure(arity=2)')),
@@ -3873,7 +3915,7 @@
         ''',
         const Visit(
             VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
-            element: 'function(Class#)',
+            element: 'factory_constructor(Class#)',
             arguments: '(true,42)',
             type: 'Class',
             selector: 'CallStructure(arity=2)')),
@@ -4122,6 +4164,15 @@
         const Visit(VisitKind.ERROR_INVALID_SET_IF_NULL,
                     error: MessageKind.NO_INSTANCE_AVAILABLE,
                     rhs: '42')),
+    const Test.prefix(
+        '''
+        ''',
+        '''
+        m() { p ??= 42; }
+        ''',
+        const Visit(VisitKind.ERROR_INVALID_SET_IF_NULL,
+                    error: MessageKind.PREFIX_AS_EXPRESSION,
+                    rhs: '42')),
     const Test(
         '''
         class C {
diff --git a/tests/compiler/dart2js/serialization_analysis_test.dart b/tests/compiler/dart2js/serialization_analysis_test.dart
index 445ea45..ffef134 100644
--- a/tests/compiler/dart2js/serialization_analysis_test.dart
+++ b/tests/compiler/dart2js/serialization_analysis_test.dart
@@ -10,11 +10,11 @@
 import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/elements/elements.dart';
 import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/enqueue.dart';
 import 'package:compiler/src/filenames.dart';
 import 'package:compiler/src/serialization/serialization.dart';
 import 'package:compiler/src/serialization/json_serializer.dart';
 import 'package:compiler/src/serialization/task.dart';
+import 'package:compiler/src/universe/world_impact.dart';
 import 'memory_compiler.dart';
 
 const List<Test> TESTS = const <Test>[
@@ -204,7 +204,7 @@
 Future<String> serializeDartCore() async {
   Compiler compiler = compilerFor(
       options: ['--analyze-all', '--output-type=dart']);
-  await compiler.runCompiler(Uri.parse('dart:core'));
+  await compiler.run(Uri.parse('dart:core'));
   return serialize(compiler.libraryLoader.libraries);
 }
 
diff --git a/tests/compiler/dart2js/show_package_warnings_test.dart b/tests/compiler/dart2js/show_package_warnings_test.dart
index e94983c..6a1aa3f 100644
--- a/tests/compiler/dart2js/show_package_warnings_test.dart
+++ b/tests/compiler/dart2js/show_package_warnings_test.dart
@@ -75,8 +75,8 @@
   print('==================================================================');
 }
 
-void checkUriSchemes(Iterable<DiagnosticMessage> messages) {
-  for (DiagnosticMessage message in messages) {
+void checkUriSchemes(Iterable<CollectedMessage> messages) {
+  for (CollectedMessage message in messages) {
     if (message.uri != null) {
       Expect.notEquals('package', message.uri.scheme,
           "Unexpected package uri `${message.uri}` in message: $message");
diff --git a/tests/compiler/dart2js/simple_inferrer_and_or_test.dart b/tests/compiler/dart2js/simple_inferrer_and_or_test.dart
index dea4f69..306392c 100644
--- a/tests/compiler/dart2js/simple_inferrer_and_or_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_and_or_test.dart
@@ -96,7 +96,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkReturn(String name, type) {
diff --git a/tests/compiler/dart2js/simple_inferrer_callers_test.dart b/tests/compiler/dart2js/simple_inferrer_callers_test.dart
index 4f2e5a8..2242d55 100644
--- a/tests/compiler/dart2js/simple_inferrer_callers_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_callers_test.dart
@@ -38,7 +38,7 @@
   var compiler = compilerFor(TEST, uri);
   var inferrer = new MyInferrer(compiler);
   compiler.typesTask.typesInferrer = inferrer;
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var mainElement = findElement(compiler, 'main');
     var classA = findElement(compiler, 'A');
     var fieldA = classA.lookupLocalMember('field');
diff --git a/tests/compiler/dart2js/simple_inferrer_closure_test.dart b/tests/compiler/dart2js/simple_inferrer_closure_test.dart
index c9776f1..9eaefa2 100644
--- a/tests/compiler/dart2js/simple_inferrer_closure_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_closure_test.dart
@@ -118,7 +118,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkReturn(String name, type) {
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure2_test.dart b/tests/compiler/dart2js/simple_inferrer_const_closure2_test.dart
index d8bdeb3..c12eff3 100644
--- a/tests/compiler/dart2js/simple_inferrer_const_closure2_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_const_closure2_test.dart
@@ -28,7 +28,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkReturn(String name, type) {
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure3_test.dart b/tests/compiler/dart2js/simple_inferrer_const_closure3_test.dart
index 8e1ef62..225d204 100644
--- a/tests/compiler/dart2js/simple_inferrer_const_closure3_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_const_closure3_test.dart
@@ -28,7 +28,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkArgument(String functionName, type) {
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure4_test.dart b/tests/compiler/dart2js/simple_inferrer_const_closure4_test.dart
index 9a2fb7c..b52e17a 100644
--- a/tests/compiler/dart2js/simple_inferrer_const_closure4_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_const_closure4_test.dart
@@ -29,7 +29,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkArgument(String functionName, type) {
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure5_test.dart b/tests/compiler/dart2js/simple_inferrer_const_closure5_test.dart
index 50d6f2a..9b550e5 100644
--- a/tests/compiler/dart2js/simple_inferrer_const_closure5_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_const_closure5_test.dart
@@ -29,7 +29,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkArgument(String functionName, type) {
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure_default_test.dart b/tests/compiler/dart2js/simple_inferrer_const_closure_default_test.dart
index b5bc4e6..f83a4d9 100644
--- a/tests/compiler/dart2js/simple_inferrer_const_closure_default_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_const_closure_default_test.dart
@@ -44,7 +44,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkArgument(String functionName, type) {
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure_test.dart b/tests/compiler/dart2js/simple_inferrer_const_closure_test.dart
index 7b7be1a..3f3056c 100644
--- a/tests/compiler/dart2js/simple_inferrer_const_closure_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_const_closure_test.dart
@@ -37,7 +37,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkReturn(String name, type) {
diff --git a/tests/compiler/dart2js/simple_inferrer_final_field2_test.dart b/tests/compiler/dart2js/simple_inferrer_final_field2_test.dart
index 36019136..8147f14 100644
--- a/tests/compiler/dart2js/simple_inferrer_final_field2_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_final_field2_test.dart
@@ -27,7 +27,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkFieldTypeInClass(String className, String fieldName, type) {
diff --git a/tests/compiler/dart2js/simple_inferrer_final_field3_test.dart b/tests/compiler/dart2js/simple_inferrer_final_field3_test.dart
index e010677..ffb277d 100644
--- a/tests/compiler/dart2js/simple_inferrer_final_field3_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_final_field3_test.dart
@@ -26,7 +26,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkFieldTypeInClass(String className, String fieldName, type) {
diff --git a/tests/compiler/dart2js/simple_inferrer_final_field_test.dart b/tests/compiler/dart2js/simple_inferrer_final_field_test.dart
index 7e5853c..1b74240 100644
--- a/tests/compiler/dart2js/simple_inferrer_final_field_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_final_field_test.dart
@@ -30,7 +30,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkFieldTypeInClass(String className, String fieldName, type) {
diff --git a/tests/compiler/dart2js/simple_inferrer_global_field_closure2_test.dart b/tests/compiler/dart2js/simple_inferrer_global_field_closure2_test.dart
index 2d673f1..07156f81 100644
--- a/tests/compiler/dart2js/simple_inferrer_global_field_closure2_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_global_field_closure2_test.dart
@@ -28,7 +28,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkArgument(String functionName, type) {
diff --git a/tests/compiler/dart2js/simple_inferrer_global_field_closure_test.dart b/tests/compiler/dart2js/simple_inferrer_global_field_closure_test.dart
index fcfa00c9..bfae05a 100644
--- a/tests/compiler/dart2js/simple_inferrer_global_field_closure_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_global_field_closure_test.dart
@@ -37,7 +37,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkReturn(String name, type) {
diff --git a/tests/compiler/dart2js/simple_inferrer_no_such_method_test.dart b/tests/compiler/dart2js/simple_inferrer_no_such_method_test.dart
index f3e44d4..3dc9993 100644
--- a/tests/compiler/dart2js/simple_inferrer_no_such_method_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_no_such_method_test.dart
@@ -173,7 +173,7 @@
   }
 
   var compiler1 = compilerFor(TEST1, uri);
-  asyncTest(() => compiler1.runCompiler(uri).then((_) {
+  asyncTest(() => compiler1.run(uri).then((_) {
     checkReturn(compiler1, 'test1', compiler1.typesTask.uint31Type);
     checkReturn(compiler1, 'test2',
         compiler1.typesTask.dynamicType.nonNullable());
@@ -186,7 +186,7 @@
   }));
 
   var compiler2 = compilerFor(TEST2, uri);
-  asyncTest(() => compiler2.runCompiler(uri).then((_) {
+  asyncTest(() => compiler2.run(uri).then((_) {
     checkReturn(compiler2, 'test1', compiler2.typesTask.mapType.nonNullable());
     checkReturn(compiler2, 'test2', compiler2.typesTask.mapType);
     checkReturn(compiler2, 'test3', compiler2.typesTask.mapType);
@@ -202,7 +202,7 @@
   }));
 
   var compiler3 = compilerFor(TEST3, uri);
-  asyncTest(() => compiler3.runCompiler(uri).then((_) {
+  asyncTest(() => compiler3.run(uri).then((_) {
     checkReturn(compiler3, 'test1', const TypeMask.nonNullEmpty());
     checkReturn(compiler3, 'test2', compiler3.typesTask.mapType);
     checkReturn(compiler3, 'test3', compiler3.typesTask.mapType);
@@ -212,7 +212,7 @@
   }));
 
   var compiler4 = compilerFor(TEST4, uri);
-  asyncTest(() => compiler4.runCompiler(uri).then((_) {
+  asyncTest(() => compiler4.run(uri).then((_) {
     checkReturn(compiler4, 'test1', const TypeMask.nonNullEmpty());
     checkReturn(compiler4, 'test2', compiler4.typesTask.mapType);
     checkReturn(compiler4, 'test3', compiler4.typesTask.mapType);
diff --git a/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart b/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart
index c26104d..f55f609 100644
--- a/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart
@@ -65,7 +65,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesTask = compiler.typesTask;
     var typesInferrer = typesTask.typesInferrer;
 
diff --git a/tests/compiler/dart2js/simple_inferrer_test.dart b/tests/compiler/dart2js/simple_inferrer_test.dart
index 1bc1cf5..f23b1f1 100644
--- a/tests/compiler/dart2js/simple_inferrer_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_test.dart
@@ -726,7 +726,7 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
   compiler.diagnosticHandler = createHandler(compiler, TEST);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesTask = compiler.typesTask;
     var typesInferrer = typesTask.typesInferrer;
     var world = compiler.world;
@@ -757,8 +757,8 @@
     checkReturn('returnInt8', typesTask.positiveIntType);
     checkReturn('returnEmpty1', const TypeMask.nonNullEmpty());
     checkReturn('returnEmpty2', const TypeMask.nonNullEmpty());
-    TypeMask intType = new TypeMask.nonNullSubtype(compiler.intClass,
-        compiler.world);
+    TypeMask intType = new TypeMask.nonNullSubtype(
+        compiler.coreClasses.intClass, compiler.world);
     checkReturn('testIsCheck1', intType);
     checkReturn('testIsCheck2', intType);
     checkReturn('testIsCheck3', intType.nullable());
@@ -790,8 +790,8 @@
     checkReturn('testIsCheck29', typesTask.dynamicType);
     checkReturn('testIf1', typesTask.uint31Type.nullable());
     checkReturn('testIf2', typesTask.uint31Type.nullable());
-    checkReturn('returnAsString',
-        new TypeMask.subtype(compiler.stringClass, compiler.world));
+    checkReturn('returnAsString', new TypeMask.subtype(
+        compiler.coreClasses.stringClass, compiler.world));
     checkReturn('returnIntAsNum', typesTask.uint31Type);
     checkReturn('returnAsTypedef', typesTask.functionType.nullable());
     checkReturn('returnTopLevelGetter', typesTask.uint31Type);
diff --git a/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart b/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
index 19053d8..82ec5ed 100644
--- a/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
@@ -168,7 +168,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesTask = compiler.typesTask;
     var typesInferrer = typesTask.typesInferrer;
 
@@ -183,8 +183,8 @@
     checkReturn('returnInt3', typesTask.uint31Type);
     checkReturn('returnInt4', typesTask.uint31Type);
     checkReturn('returnInt5', typesTask.uint31Type);
-    checkReturn('returnInt6',
-        new TypeMask.nonNullSubtype(compiler.intClass, compiler.world));
+    checkReturn('returnInt6', new TypeMask.nonNullSubtype(
+        compiler.coreClasses.intClass, compiler.world));
 
     var subclassOfInterceptor =
         findTypeMask(compiler, 'Interceptor', 'nonNullSubclass');
diff --git a/tests/compiler/dart2js/simple_inferrer_unregister_call_test.dart b/tests/compiler/dart2js/simple_inferrer_unregister_call_test.dart
index 06bba80..6cf04020 100644
--- a/tests/compiler/dart2js/simple_inferrer_unregister_call_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_unregister_call_test.dart
@@ -32,7 +32,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkReturnInClass(String className, String methodName, type) {
diff --git a/tests/compiler/dart2js/source_map_d2js_validity_test.dart b/tests/compiler/dart2js/source_map_d2js_validity_test.dart
index ac24952..062a35a 100644
--- a/tests/compiler/dart2js/source_map_d2js_validity_test.dart
+++ b/tests/compiler/dart2js/source_map_d2js_validity_test.dart
@@ -23,7 +23,7 @@
          '-o${tmpDir.path}/out.js',
          '--library-root=sdk']);
       return result.then((CompilationResult result) {
-        Compiler compiler = result.compiler;
+        CompilerImpl compiler = result.compiler;
         Uri uri =
             new Uri.file('${tmpDir.path}/out.js', windows: Platform.isWindows);
         validateSourceMap(uri,
diff --git a/tests/compiler/dart2js/source_map_deferred_d2js_validity_test.dart b/tests/compiler/dart2js/source_map_deferred_d2js_validity_test.dart
index 19c8f71..36a4878 100644
--- a/tests/compiler/dart2js/source_map_deferred_d2js_validity_test.dart
+++ b/tests/compiler/dart2js/source_map_deferred_d2js_validity_test.dart
@@ -22,7 +22,7 @@
          '-o${tmpDir.path}/out.js',
          '--library-root=sdk']);
       return result.then((CompilationResult result) {
-        Compiler compiler = result.compiler;
+        CompilerImpl compiler = result.compiler;
         Uri mainUri = new Uri.file('${tmpDir.path}/out.js',
                                    windows: Platform.isWindows);
         Uri deferredUri = new Uri.file('${tmpDir.path}/out.js_1.part.js',
diff --git a/tests/compiler/dart2js/source_map_validator_helper.dart b/tests/compiler/dart2js/source_map_validator_helper.dart
index e8ca28c..84e410c 100644
--- a/tests/compiler/dart2js/source_map_validator_helper.dart
+++ b/tests/compiler/dart2js/source_map_validator_helper.dart
@@ -25,7 +25,7 @@
 validateSourceMap(Uri targetUri,
                   {Uri mainUri,
                    Position mainPosition,
-                   Compiler compiler}) {
+                   CompilerImpl compiler}) {
   Uri mapUri = getMapUri(targetUri);
   List<String> targetLines = new File.fromUri(targetUri).readAsLinesSync();
   SingleMapping sourceMap = getSourceMap(mapUri);
@@ -100,7 +100,7 @@
 }
 
 checkNames(Uri targetUri, Uri mapUri,
-           SingleMapping sourceMap, Compiler compiler) {
+           SingleMapping sourceMap, CompilerImpl compiler) {
   Map<Uri, CompilationUnitElement> compilationUnitMap = {};
 
   void mapCompilationUnits(LibraryElement library) {
diff --git a/tests/compiler/dart2js/source_mapping_test.dart b/tests/compiler/dart2js/source_mapping_test.dart
index 6c7b46f..c061f99 100644
--- a/tests/compiler/dart2js/source_mapping_test.dart
+++ b/tests/compiler/dart2js/source_mapping_test.dart
@@ -19,7 +19,7 @@
   Uri uri = new Uri(path: sourceFile.filename);
   compiler.sourceFiles[uri.toString()] = sourceFile;
   JavaScriptBackend backend = compiler.backend;
-  return compiler.runCompiler(uri).then((_) {
+  return compiler.run(uri).then((_) {
     // TODO(floitsch): the outputBuffers are only accessible in the full
     // emitter.
     full.Emitter fullEmitter = backend.emitter.emitter;
diff --git a/tests/compiler/dart2js/sourcemaps/sourcemap_helper.dart b/tests/compiler/dart2js/sourcemaps/sourcemap_helper.dart
index eac4637..9cb53e5 100644
--- a/tests/compiler/dart2js/sourcemaps/sourcemap_helper.dart
+++ b/tests/compiler/dart2js/sourcemaps/sourcemap_helper.dart
@@ -120,7 +120,7 @@
       if (verbose) print('Using the new source information system.');
       useNewSourceInfo = true;
     }
-    api.Compiler compiler = await compilerFor(
+    api.CompilerImpl compiler = await compilerFor(
         outputProvider: outputProvider,
         // TODO(johnniwinther): Use [verbose] to avoid showing diagnostics.
         options: ['--out=$targetUri', '--source-map=$sourceMapFileUri']
@@ -134,7 +134,7 @@
     var handler = compiler.handler;
     SourceFileProvider sourceFileProvider = handler.provider;
     sourceFileManager = new ProviderSourceFileManager(sourceFileProvider);
-    await compiler.runCompiler(inputUri);
+    await compiler.run(inputUri);
 
     List<SourceMapInfo> infoList = <SourceMapInfo>[];
     backend.generatedCode.forEach((Element element, js.Expression node) {
diff --git a/tests/compiler/dart2js/trust_type_annotations_test.dart b/tests/compiler/dart2js/trust_type_annotations_test.dart
index 301d061..f165166 100644
--- a/tests/compiler/dart2js/trust_type_annotations_test.dart
+++ b/tests/compiler/dart2js/trust_type_annotations_test.dart
@@ -49,7 +49,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri, trustTypeAnnotations: true);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     ClassElement classA = findElement(compiler, "A");
@@ -66,7 +66,8 @@
                 typesInferrer.getTypeOfElement(element), compiler.world));
     }
 
-    var intMask = new TypeMask.subtype(compiler.intClass, compiler.world);
+    var intMask = new TypeMask.subtype(
+        compiler.coreClasses.intClass, compiler.world);
 
     checkReturn('foo', intMask);
     checkReturn('faa', intMask);
diff --git a/tests/compiler/dart2js/type_checker_test.dart b/tests/compiler/dart2js/type_checker_test.dart
index 045d2be..d0e7db5 100644
--- a/tests/compiler/dart2js/type_checker_test.dart
+++ b/tests/compiler/dart2js/type_checker_test.dart
@@ -19,6 +19,7 @@
 import 'package:compiler/src/resolution/tree_elements.dart' show
     TreeElements,
     TreeElementMapping;
+import 'package:compiler/src/parser/element_listener.dart';
 import 'package:compiler/src/tree/tree.dart';
 import 'package:compiler/src/typechecker.dart';
 import 'package:compiler/src/script.dart';
@@ -75,11 +76,10 @@
     Expect.equals(type, analyzeType(compiler, code));
   }
 
-  checkType(compiler.intClass.computeType(compiler.resolution), "3");
-  checkType(compiler.boolClass.computeType(compiler.resolution), "false");
-  checkType(compiler.boolClass.computeType(compiler.resolution), "true");
-  checkType(
-      compiler.stringClass.computeType(compiler.resolution), "'hestfisk'");
+  checkType(compiler.coreTypes.intType, "3");
+  checkType(compiler.coreTypes.boolType, "false");
+  checkType(compiler.coreTypes.boolType, "true");
+  checkType(compiler.coreTypes.stringType, "'hestfisk'");
 }
 
 Future testReturn(MockCompiler compiler) {
@@ -2524,9 +2524,10 @@
     // Type check last class declaration or member.
     TypeCheckerVisitor checker =
         new TypeCheckerVisitor(compiler, mapping, compiler.types);
-    compiler.clearMessages();
+    DiagnosticCollector collector = compiler.diagnosticCollector;
+    collector.clear();
     checker.analyze(node);
-    compareWarningKinds(text, expectedWarnings, compiler.warnings);
+    compareWarningKinds(text, expectedWarnings, collector.warnings);
 
     compiler.diagnosticHandler = null;
   });
@@ -2550,7 +2551,8 @@
   compiler.diagnosticHandler = createHandler(compiler, text);
 
   Token tokens = scan(text);
-  NodeListener listener = new NodeListener(compiler.reporter, null);
+  NodeListener listener = new NodeListener(
+      const ScannerOptions(), compiler.reporter, null);
   Parser parser = new Parser(listener);
   parser.parseStatement(tokens);
   Node node = listener.popNode();
@@ -2561,25 +2563,23 @@
   compiler.enqueuer.resolution.emptyDeferredTaskQueue();
   TypeCheckerVisitor checker = new TypeCheckerVisitor(
       compiler, elements, compiler.types);
-  compiler.clearMessages();
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  collector.clear();
   checker.analyze(node);
   if (flushDeferred) {
     compiler.enqueuer.resolution.emptyDeferredTaskQueue();
   }
-  compareWarningKinds(text, warnings, compiler.warnings);
-  compareWarningKinds(text, errors, compiler.errors);
-  if (hints != null) compareWarningKinds(text, hints, compiler.hints);
-  if (infos != null) compareWarningKinds(text, infos, compiler.infos);
+  compareWarningKinds(text, warnings, collector.warnings);
+  compareWarningKinds(text, errors, collector.errors);
+  if (hints != null) compareWarningKinds(text, hints, collector.hints);
+  if (infos != null) compareWarningKinds(text, infos, collector.infos);
   compiler.diagnosticHandler = null;
 }
 
 void generateOutput(MockCompiler compiler, String text) {
-  for (WarningMessage message in compiler.warnings) {
-    Node node = message.node;
-    var beginToken = node.getBeginToken();
-    var endToken = node.getEndToken();
-    int begin = beginToken.charOffset;
-    int end = endToken.charOffset + endToken.charCount;
+  for (CollectedMessage message in compiler.diagnosticCollector.warnings) {
+    int begin = message.begin;
+    int end = message.end;
     SourceFile sourceFile = new StringSourceFile.fromName('analysis', text);
     print(sourceFile.getLocationMessage(message.message.toString(),
                                         begin, end));
@@ -2597,7 +2597,8 @@
 
   compiler.resolver.resolve(element);
   Token tokens = scan(text);
-  NodeListener listener = new NodeListener(compiler.reporter, null);
+  NodeListener listener = new NodeListener(
+      const ScannerOptions(), compiler.reporter, null);
   Parser parser = new Parser(listener,
       yieldIsKeyword: element.asyncMarker.isYielding,
       awaitIsKeyword: element.asyncMarker.isAsync);
@@ -2606,9 +2607,10 @@
   TreeElements elements = compiler.resolveNodeStatement(node, element);
   TypeCheckerVisitor checker = new TypeCheckerVisitor(
       compiler, elements, compiler.types);
-  compiler.clearMessages();
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  collector.clear();
   checker.analyze(node);
   generateOutput(compiler, text);
-  compareWarningKinds(text, warnings, compiler.warnings);
-  compareWarningKinds(text, hints, compiler.hints);
+  compareWarningKinds(text, warnings, collector.warnings);
+  compareWarningKinds(text, hints, collector.hints);
 }
diff --git a/tests/compiler/dart2js/type_combination_test.dart b/tests/compiler/dart2js/type_combination_test.dart
index c75ad56..3aef5f8 100644
--- a/tests/compiler/dart2js/type_combination_test.dart
+++ b/tests/compiler/dart2js/type_combination_test.dart
@@ -4,6 +4,7 @@
 
 import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
+import 'package:compiler/src/js_backend/backend_helpers.dart';
 import 'package:compiler/src/js_backend/js_backend.dart';
 import 'package:compiler/src/types/types.dart';
 import 'package:compiler/src/world.dart';
@@ -75,8 +76,9 @@
 
     var r1 = operate(type1, type2);
     var r2 = operate(type2, type1);
-    Expect.equals(result, r1);
-    Expect.equals(r1, r2, 'symmetry violation');
+    Expect.equals(result, r1,
+        "Unexpected result of $name($type1,$type2)");
+    Expect.equals(r1, r2, 'Symmetry violation of $name($type1,$type2)');
   }
 
   void check(type1, type2, predicate) {
@@ -412,6 +414,7 @@
 
 void testIntersection(MockCompiler compiler) {
   JavaScriptBackend backend = compiler.backend;
+  BackendHelpers helpers = backend.helpers;
   RuleSet ruleSet = new RuleSet('intersection',
       (t1, t2) => t1.intersection(t2, compiler.world));
   rule(type1, type2, result) => ruleSet.rule(type1, type2, result);
@@ -554,9 +557,9 @@
   rule(jsIndexable, nonPrimitive1, emptyType);
   rule(jsIndexable, nonPrimitive2, emptyType);
   rule(jsIndexable, potentialArray, new TypeMask.nonNullSubtype(
-      backend.jsArrayClass, compiler.world));
+      helpers.jsArrayClass, compiler.world));
   rule(jsIndexable, potentialString, new TypeMask.nonNullSubtype(
-      backend.jsStringClass, compiler.world));
+      helpers.jsStringClass, compiler.world));
   rule(jsIndexable, jsBooleanOrNull, emptyType);
   rule(jsIndexable, jsNumberOrNull, emptyType);
   rule(jsIndexable, jsIntegerOrNull, emptyType);
@@ -729,10 +732,15 @@
 }
 
 void main() {
-  asyncTest(() => MockCompiler.create((MockCompiler compiler) {
+  asyncTest(() async {
+    MockCompiler compiler = new MockCompiler.internal();
+    await compiler.init("""
+    class PatternImpl implements Pattern {}
+    """);
     JavaScriptBackend backend = compiler.backend;
+    BackendHelpers helpers = backend.helpers;
     World world = compiler.world;
-    backend.interceptorsLibrary.forEachLocalMember((element) {
+    helpers.interceptorsLibrary.forEachLocalMember((element) {
       if (element.isClass) {
         element.ensureResolved(compiler.resolution);
         backend.registerInstantiatedType(
@@ -741,6 +749,9 @@
             compiler.globalDependencies);
       }
     });
+    ClassElement patternImplClass = compiler.mainApp.find('PatternImpl');
+    patternImplClass.ensureResolved(compiler.resolution);
+
     backend.registerInstantiatedType(
         compiler.coreTypes.mapType(),
         compiler.enqueuer.resolution,
@@ -749,6 +760,10 @@
         compiler.coreTypes.functionType,
         compiler.enqueuer.resolution,
         compiler.globalDependencies);
+    backend.registerInstantiatedType(
+        patternImplClass.rawType,
+        compiler.enqueuer.resolution,
+        compiler.globalDependencies);
     compiler.world.populate();
 
     // Grab hold of a supertype for String so we can produce potential
@@ -756,54 +771,61 @@
     patternClass = compiler.coreLibrary.find('Pattern');
 
     nonPrimitive1 = new TypeMask.nonNullSubtype(
-        compiler.mapClass, world);
+        compiler.coreClasses.mapClass, world);
     nonPrimitive2 = new TypeMask.nonNullSubtype(
-        compiler.functionClass, world);
+        compiler.coreClasses.functionClass, world);
     potentialArray = new TypeMask.subtype(
-        compiler.listClass, world);
+        compiler.coreClasses.listClass, world);
     potentialString = new TypeMask.subtype(patternClass, world);
-    jsInterceptor = new TypeMask.nonNullSubclass(backend.jsInterceptorClass,
+    jsInterceptor = new TypeMask.nonNullSubclass(helpers.jsInterceptorClass,
         world);
-    jsArrayOrNull = new TypeMask.subclass(backend.jsArrayClass, world);
-    jsReadableArray = new TypeMask.nonNullSubclass(backend.jsArrayClass,
+    jsArrayOrNull = new TypeMask.subclass(helpers.jsArrayClass, world);
+    jsReadableArray = new TypeMask.nonNullSubclass(helpers.jsArrayClass,
         world);
-    jsMutableArrayOrNull = new TypeMask.subclass(backend.jsMutableArrayClass,
+    jsMutableArrayOrNull = new TypeMask.subclass(helpers.jsMutableArrayClass,
         world);
-    jsMutableArray = new TypeMask.nonNullSubclass(backend.jsMutableArrayClass,
+    jsMutableArray = new TypeMask.nonNullSubclass(helpers.jsMutableArrayClass,
         world);
-    jsFixedArrayOrNull = new TypeMask.exact(backend.jsFixedArrayClass, world);
-    jsFixedArray = new TypeMask.nonNullExact(backend.jsFixedArrayClass, world);
-    jsExtendableArrayOrNull = new TypeMask.exact(backend.jsExtendableArrayClass,
+    jsFixedArrayOrNull = new TypeMask.exact(helpers.jsFixedArrayClass, world);
+    jsFixedArray = new TypeMask.nonNullExact(helpers.jsFixedArrayClass, world);
+    jsExtendableArrayOrNull = new TypeMask.exact(helpers.jsExtendableArrayClass,
         world);
     jsExtendableArray = new TypeMask.nonNullExact(
-        backend.jsExtendableArrayClass, world);
+        helpers.jsExtendableArrayClass, world);
     jsUnmodifiableArrayOrNull =
-        new TypeMask.exact(backend.jsUnmodifiableArrayClass, world);
+        new TypeMask.exact(helpers.jsUnmodifiableArrayClass, world);
     jsUnmodifiableArray =
-        new TypeMask.nonNullExact(backend.jsUnmodifiableArrayClass, world);
-    jsIndexableOrNull = new TypeMask.subtype(backend.jsIndexableClass, world);
-    jsIndexable = new TypeMask.nonNullSubtype(backend.jsIndexableClass, world);
-    jsInterceptorOrNull = new TypeMask.subclass(backend.jsInterceptorClass,
+        new TypeMask.nonNullExact(helpers.jsUnmodifiableArrayClass, world);
+    jsIndexableOrNull = new TypeMask.subtype(helpers.jsIndexableClass, world);
+    jsIndexable = new TypeMask.nonNullSubtype(helpers.jsIndexableClass, world);
+    jsInterceptorOrNull = new TypeMask.subclass(helpers.jsInterceptorClass,
         world);
-    jsStringOrNull = new TypeMask.exact(backend.jsStringClass, world);
-    jsString = new TypeMask.nonNullExact(backend.jsStringClass, world);
-    jsBoolean = new TypeMask.nonNullExact(backend.jsBoolClass, world);
-    jsNumber = new TypeMask.nonNullSubclass(backend.jsNumberClass, world);
-    jsInteger = new TypeMask.nonNullExact(backend.jsIntClass, world);
-    jsDouble = new TypeMask.nonNullExact(backend.jsDoubleClass, world);
-    jsBooleanOrNull = new TypeMask.exact(backend.jsBoolClass, world);
-    jsNumberOrNull = new TypeMask.subclass(backend.jsNumberClass, world);
-    jsIntegerOrNull = new TypeMask.exact(backend.jsIntClass, world);
-    jsDoubleOrNull = new TypeMask.exact(backend.jsDoubleClass, world);
+    jsStringOrNull = new TypeMask.exact(helpers.jsStringClass, world);
+    jsString = new TypeMask.nonNullExact(helpers.jsStringClass, world);
+    jsBoolean = new TypeMask.nonNullExact(helpers.jsBoolClass, world);
+    jsNumber = new TypeMask.nonNullSubclass(helpers.jsNumberClass, world);
+    jsInteger = new TypeMask.nonNullExact(helpers.jsIntClass, world);
+    jsDouble = new TypeMask.nonNullExact(helpers.jsDoubleClass, world);
+    jsBooleanOrNull = new TypeMask.exact(helpers.jsBoolClass, world);
+    jsNumberOrNull = new TypeMask.subclass(helpers.jsNumberClass, world);
+    jsIntegerOrNull = new TypeMask.exact(helpers.jsIntClass, world);
+    jsDoubleOrNull = new TypeMask.exact(helpers.jsDoubleClass, world);
     nullType = const TypeMask.empty();
     objectType = new TypeMask.nonNullSubclass(
-        compiler.objectClass, world);
+        compiler.coreClasses.objectClass, world);
     emptyType = const TypeMask.nonNullEmpty();
     dynamicType = new TypeMask.subclass(
-        compiler.objectClass, world);
+        compiler.coreClasses.objectClass, world);
+
+    Expect.notEquals(emptyType, nonPrimitive1,
+        "nonPrimitive1 expected to be non-empty.");
+    Expect.notEquals(jsStringOrNull, potentialString,
+        "potentialString expected not to be exact JSString");
+    Expect.notEquals(jsArrayOrNull, potentialArray,
+        "potentialArray expected not to be JSArray subclass");
 
     testUnion(compiler);
     testIntersection(compiler);
     testRegressions(compiler);
-  }));
+  });
 }
diff --git a/tests/compiler/dart2js/type_equals_test.dart b/tests/compiler/dart2js/type_equals_test.dart
index 0911d60..edeacdc 100644
--- a/tests/compiler/dart2js/type_equals_test.dart
+++ b/tests/compiler/dart2js/type_equals_test.dart
@@ -89,7 +89,7 @@
       """,
       uri,
       analyzeAll: true, analyzeOnly: true);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     test(compiler, "void1", "void2", expect: true);
     test(compiler, "int1", "int2", expect: true);
     test(compiler, "String1", "String2", expect: true);
diff --git a/tests/compiler/dart2js/type_inference6_test.dart b/tests/compiler/dart2js/type_inference6_test.dart
index d0da1e7..bfee36c 100644
--- a/tests/compiler/dart2js/type_inference6_test.dart
+++ b/tests/compiler/dart2js/type_inference6_test.dart
@@ -23,7 +23,7 @@
 Future runTest() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  return compiler.runCompiler(uri).then((_) {
+  return compiler.run(uri).then((_) {
     var typesTask = compiler.typesTask;
     var typesInferrer = typesTask.typesInferrer;
     var element = findElement(compiler, "foo");
diff --git a/tests/compiler/dart2js/type_inference7_test.dart b/tests/compiler/dart2js/type_inference7_test.dart
index 64b8cbc..072d42d 100644
--- a/tests/compiler/dart2js/type_inference7_test.dart
+++ b/tests/compiler/dart2js/type_inference7_test.dart
@@ -22,7 +22,7 @@
   {
     // Assertions enabled:
     var compiler = compilerFor(TEST, uri, enableUserAssertions: true);
-    await compiler.runCompiler(uri);
+    await compiler.run(uri);
     var typesTask = compiler.typesTask;
     var typesInferrer = typesTask.typesInferrer;
     var foo = findElement(compiler, "foo");
@@ -51,7 +51,7 @@
   {
     // Assertions disabled:
     var compiler = compilerFor(TEST, uri, enableUserAssertions: false);
-    await compiler.runCompiler(uri);
+    await compiler.run(uri);
     var typesTask = compiler.typesTask;
     var typesInferrer = typesTask.typesInferrer;
     var foo = findElement(compiler, "foo");
diff --git a/tests/compiler/dart2js/type_inference8_test.dart b/tests/compiler/dart2js/type_inference8_test.dart
index 570e43a..001b1aa 100644
--- a/tests/compiler/dart2js/type_inference8_test.dart
+++ b/tests/compiler/dart2js/type_inference8_test.dart
@@ -33,7 +33,7 @@
 Future runTest1() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST1, uri);
-  return compiler.runCompiler(uri).then((_) {
+  return compiler.run(uri).then((_) {
     var typesTask = compiler.typesTask;
     var typesInferrer = typesTask.typesInferrer;
     var element = findElement(compiler, "foo");
@@ -76,7 +76,7 @@
 Future runTest2() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST2, uri);
-  return compiler.runCompiler(uri).then((_) {
+  return compiler.run(uri).then((_) {
     var typesTask = compiler.typesTask;
     var typesInferrer = typesTask.typesInferrer;
     var element = findElement(compiler, "foo");
diff --git a/tests/compiler/dart2js/type_inference_switch_test.dart b/tests/compiler/dart2js/type_inference_switch_test.dart
new file mode 100644
index 0000000..795684c
--- /dev/null
+++ b/tests/compiler/dart2js/type_inference_switch_test.dart
@@ -0,0 +1,159 @@
+// Copyright (c) 2011, 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:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+import 'compiler_helper.dart';
+import 'type_mask_test_helper.dart';
+
+import 'dart:async';
+
+const String TEST1 = r"""
+foo(int x) {
+  var a = "one";
+  switch (x) {
+    case 1:
+      a = "two";
+      break;
+    case 2:
+      break;
+  }
+
+  return a;
+}
+
+main() {
+  foo(new DateTime.now().millisecondsSinceEpoch);
+}
+""";
+
+const String TEST2 = r"""
+foo(int x) {
+  var a;
+  switch (x) {
+    case 1:
+      a = "two";
+      break;
+    case 2:
+      break;
+  }
+
+  return a;
+}
+
+main() {
+  foo(new DateTime.now().millisecondsSinceEpoch);
+}
+""";
+
+const String TEST3 = r"""
+foo(int x) {
+  var a;
+  switch (x) {
+    case 1:
+      a = 1;
+    case 2:  // illegal fall through
+      a = 2;
+      break;
+  }
+
+  return a;
+}
+
+main() {
+  foo(new DateTime.now().millisecondsSinceEpoch);
+}
+""";
+
+const String TEST4 = r"""
+foo(int x) {
+  var a;
+  switch (x) {
+    case 1:
+      a = 1;
+    case 2:  // illegal fall through
+      a = 2;
+      break;
+    default:
+      a = 0;
+  }
+
+  return a;
+}
+
+main() {
+  foo(new DateTime.now().millisecondsSinceEpoch);
+}
+""";
+
+const String TEST5 = r"""
+foo(int x) {
+  var a;
+  switch (x) {
+    case 1:
+      a = 1;
+      break;
+    case 2:
+      a = 2;
+      break;
+    default:
+  }
+
+  return a;
+}
+
+main() {
+  foo(new DateTime.now().millisecondsSinceEpoch);
+}
+""";
+
+const String TEST6 = r"""
+foo(int x) {
+  var a;
+  do {  // add extra locals scope
+    switch (x) {
+      case 1:
+        a = 1;
+        break;
+      case 2:
+        a = 2;
+        break;
+    }
+  } while (false);
+
+  return a;
+}
+
+main() {
+  foo(new DateTime.now().millisecondsSinceEpoch);
+}
+""";
+
+Future runTest(String test, checker) {
+  Uri uri = new Uri(scheme: 'source');
+  var compiler = compilerFor(test, uri);
+
+  checkTypeOf(String name, TypeMask type) {
+    var typesTask = compiler.typesTask;
+    var typesInferrer = typesTask.typesInferrer;
+    var element = findElement(compiler, name);
+    var mask = typesInferrer.getReturnTypeOfElement(element);
+    Expect.equals(type, simplify(mask, compiler));
+  }
+
+  return compiler.run(uri).then((_) {
+    checker(compiler.typesTask, checkTypeOf);
+  });
+}
+
+main() {
+  asyncTest(() async {
+    await runTest(TEST1, (t, c) => c("foo", t.stringType));
+    await runTest(TEST2, (t, c) => c("foo", t.stringType.nullable()));
+    await runTest(TEST3, (t, c) => c("foo", t.uint31Type.nullable()));
+    await runTest(TEST4, (t, c) => c("foo", t.uint31Type));
+    await runTest(TEST5, (t, c) => c("foo", t.uint31Type.nullable()));
+    await runTest(TEST6, (t, c) => c("foo", t.uint31Type.nullable()));
+  });
+}
diff --git a/tests/compiler/dart2js/type_mask2_test.dart b/tests/compiler/dart2js/type_mask2_test.dart
index 25c19e1..03db580 100644
--- a/tests/compiler/dart2js/type_mask2_test.dart
+++ b/tests/compiler/dart2js/type_mask2_test.dart
@@ -4,12 +4,15 @@
 
 library type_mask2_test;
 
+import 'dart:async';
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
 import 'type_test_helper.dart';
 import 'package:compiler/src/elements/elements.dart'
        show Element, ClassElement;
 import 'package:compiler/src/types/types.dart';
+import 'package:compiler/src/world.dart' show
+    ClassWorld;
 
 isCheckedMode() {
   try {
@@ -22,11 +25,67 @@
 }
 
 void main() {
-  testUnionTypeMaskFlatten();
+  asyncTest(() async {
+    await testUnionTypeMaskFlatten();
+    await testStringSubtypes();
+  });
 }
 
-void testUnionTypeMaskFlatten() {
-  asyncTest(() => TypeEnvironment.create(r"""
+checkMasks(ClassWorld classWorld,
+           List<ClassElement> allClasses,
+           List<FlatTypeMask> masks,
+           {FlatTypeMask result,
+            List<FlatTypeMask> disjointMasks,
+            FlatTypeMask flattened,
+            List<ClassElement> containedClasses}) {
+  List<FlatTypeMask> disjoint = <FlatTypeMask>[];
+  UnionTypeMask.unionOfHelper(masks, disjoint, classWorld);
+  Expect.listEquals(disjointMasks, disjoint,
+      'Unexpected disjoint masks: $disjoint, expected $disjointMasks.');
+  if (flattened == null) {
+    // We only do the invalid call to flatten in checked mode, as flatten's
+    // behaviour in unchecked mode is not defined and thus cannot be
+    // reliably tested.
+    if (isCheckedMode()) {
+      Expect.throws(() => UnionTypeMask.flatten(disjoint, classWorld),
+        (e) => e is AssertionError,
+        'Expect assertion failure on flattening of $disjoint.');
+    }
+  } else {
+    TypeMask flattenResult =
+        UnionTypeMask.flatten(disjoint, classWorld);
+    Expect.equals(flattened, flattenResult,
+        'Unexpected flattening of $disjoint: '
+        '$flattenResult, expected $flattened.');
+  }
+  var union = UnionTypeMask.unionOf(masks, classWorld);
+  if (result == null) {
+    Expect.isTrue(union is UnionTypeMask,
+        'Expected union of $masks to be a union-type: $union.');
+    Expect.listEquals(disjointMasks, union.disjointMasks,
+        'Unexpected union masks: '
+        '${union.disjointMasks}, expected $disjointMasks.');
+  } else {
+    Expect.equals(result, union,
+        'Unexpected union of $masks: $union, expected $result.');
+  }
+  if (containedClasses != null) {
+    for (ClassElement cls in allClasses) {
+      if (containedClasses.contains(cls)) {
+        Expect.isTrue(union.contains(cls, classWorld),
+            'Expected $union to contain $cls.');
+      } else {
+        Expect.isFalse(union.contains(cls, classWorld),
+            '$union not expected to contain $cls.');
+      }
+    }
+
+  }
+  return union;
+}
+
+Future testUnionTypeMaskFlatten() async  {
+  TypeEnvironment env = await TypeEnvironment.create(r"""
       class A {}
       class B {}
       class C extends A {}
@@ -42,153 +101,158 @@
         new E();
       }
       """,
-      useMockCompiler: false).then((env) {
+      useMockCompiler: false);
+
+  ClassWorld classWorld = env.compiler.world;
+
+  ClassElement Object_ = env.getElement("Object");
+  ClassElement A = env.getElement("A");
+  ClassElement B = env.getElement("B");
+  ClassElement C = env.getElement("C");
+  ClassElement D = env.getElement("D");
+  ClassElement E = env.getElement("E");
+
+  List<ClassElement> allClasses = <ClassElement>[Object_, A, B, C, D, E];
+
+  check(List<FlatTypeMask> masks,
+        {FlatTypeMask result,
+         List<FlatTypeMask> disjointMasks,
+         FlatTypeMask flattened,
+         List<ClassElement> containedClasses}) {
+    return checkMasks(
+        classWorld,
+        allClasses,
+        masks,
+        result: result,
+        disjointMasks: disjointMasks,
+        flattened: flattened,
+        containedClasses: containedClasses);
+  }
+
+  TypeMask empty = const TypeMask.nonNullEmpty();
+  TypeMask subclassObject = new TypeMask.nonNullSubclass(Object_, classWorld);
+  TypeMask exactA = new TypeMask.nonNullExact(A, classWorld);
+  TypeMask subclassA = new TypeMask.nonNullSubclass(A, classWorld);
+  TypeMask subtypeA = new TypeMask.nonNullSubtype(A, classWorld);
+  TypeMask exactB = new TypeMask.nonNullExact(B, classWorld);
+  TypeMask subclassB = new TypeMask.nonNullSubclass(B, classWorld);
+  TypeMask exactC = new TypeMask.nonNullExact(C, classWorld);
+  TypeMask exactD = new TypeMask.nonNullExact(D, classWorld);
+  TypeMask exactE = new TypeMask.nonNullExact(E, classWorld);
+
+  check([],
+        result: empty,
+        disjointMasks: [],
+        containedClasses: []);
+
+  check([exactA],
+        result: exactA,
+        disjointMasks: [exactA],
+        containedClasses: [A]);
+
+  check([exactA, exactA],
+        result: exactA,
+        disjointMasks: [exactA],
+        containedClasses: [A]);
+
+  check([exactA, exactB],
+        disjointMasks: [exactA, exactB],
+        flattened: subclassObject,
+        containedClasses: [A, B]);
+
+  check([subclassObject],
+        result: subclassObject,
+        disjointMasks: [subclassObject],
+        containedClasses: [Object_, A, B, C, D, E]);
+
+  check([subclassObject, exactA],
+        disjointMasks: [subclassObject],
+        result: subclassObject,
+        containedClasses: [Object_, A, B, C, D, E]);
+
+  check([exactA, exactC],
+        disjointMasks: [subclassA],
+        result: subclassA,
+        containedClasses: [A, C]);
+
+  check([exactA, exactB, exactC],
+        disjointMasks: [subclassA, exactB],
+        flattened: subclassObject,
+        containedClasses: [A, B, C]);
+
+  check([exactA, exactD],
+        disjointMasks: [subtypeA],
+        result: subtypeA,
+        containedClasses: [A, C, D, E]);
+
+  check([exactA, exactB, exactD],
+        disjointMasks: [subtypeA, exactB],
+        flattened: subclassObject,
+        containedClasses: [A, B, C, D, E]);
+
+  check([exactA, exactE],
+        disjointMasks: [subtypeA],
+        result: subtypeA,
+        containedClasses: [A, C, D, E]);
+
+  check([exactA, exactB, exactE],
+        disjointMasks: [subtypeA, exactB],
+        flattened: subclassObject,
+        containedClasses: [A, B, C, D, E]);
+
+  check([exactB, exactE, exactA],
+        disjointMasks: [subclassB, exactA],
+        flattened: subclassObject,
+        containedClasses: [A, B, E]);
+
+  check([exactE, exactA, exactB],
+        disjointMasks: [subtypeA, exactB],
+        flattened: subclassObject,
+        containedClasses: [A, B, C, D, E]);
+
+  check([exactE, exactB, exactA],
+        disjointMasks: [subclassB, exactA],
+        flattened: subclassObject,
+        containedClasses: [A, B, E]);
+}
+
+Future testStringSubtypes() async {
+  TypeEnvironment env = await TypeEnvironment.create('',
+      mainSource: r"""
+      main() {
+        '' is String;
+      }
+      """,
+      useMockCompiler: false);
     var classWorld = env.compiler.world;
+    var backend = env.compiler.backend;
 
     ClassElement Object_ = env.getElement("Object");
-    ClassElement A = env.getElement("A");
-    ClassElement B = env.getElement("B");
-    ClassElement C = env.getElement("C");
-    ClassElement D = env.getElement("D");
-    ClassElement E = env.getElement("E");
+    ClassElement String_ = env.getElement("String");
+    ClassElement JSString = backend.helpers.jsStringClass;
 
-    List<ClassElement> allClasses = <ClassElement>[Object_, A, B, C, D, E];
+    List<ClassElement> allClasses = <ClassElement>[Object_, String_];
 
-    check(List<FlatTypeMask> masks,
-          {FlatTypeMask result,
-           List<FlatTypeMask> disjointMasks,
-           FlatTypeMask flattened,
-           List<ClassElement> containedClasses}) {
-      List<FlatTypeMask> disjoint = <FlatTypeMask>[];
-      UnionTypeMask.unionOfHelper(masks, disjoint, classWorld);
-      Expect.listEquals(disjointMasks, disjoint,
-          'Unexpected disjoint masks: $disjoint, expected $disjointMasks.');
-      if (flattened == null) {
-        // We only do the invalid call to flatten in checked mode, as flatten's
-        // brehaviour in unchecked more is not defined and thus cannot be
-        // reliably tested.
-        if (isCheckedMode()) {
-          Expect.throws(() => UnionTypeMask.flatten(disjoint, classWorld),
-            (e) => e is AssertionError,
-            'Expect assertion failure on flattening of $disjoint.');
-        }
-      } else {
-        TypeMask flattenResult =
-            UnionTypeMask.flatten(disjoint, classWorld);
-        Expect.equals(flattened, flattenResult,
-            'Unexpected flattening of $disjoint: '
-            '$flattenResult, expected $flattened.');
-      }
-      var union = UnionTypeMask.unionOf(masks, classWorld);
-      if (result == null) {
-        Expect.isTrue(union is UnionTypeMask,
-            'Expected union of $masks to be a union-type: $union.');
-        Expect.listEquals(disjointMasks, union.disjointMasks,
-            'Unexpected union masks: '
-            '${union.disjointMasks}, expected $disjointMasks.');
-      } else {
-        Expect.equals(result, union,
-            'Unexpected union of $masks: $union, expected $result.');
-      }
-      if (containedClasses != null) {
-        for (ClassElement cls in allClasses) {
-          if (containedClasses.contains(cls)) {
-            Expect.isTrue(union.contains(cls, classWorld),
-                'Expected $union to contain $cls.');
-          } else {
-            Expect.isFalse(union.contains(cls, classWorld),
-                '$union not expected to contain $cls.');
-          }
-        }
+    Expect.isFalse(classWorld.isDirectlyInstantiated(Object_));
+    Expect.isTrue(classWorld.isIndirectlyInstantiated(Object_));
+    Expect.isTrue(classWorld.isInstantiated(Object_));
 
-      }
-      return union;
-    }
+    Expect.isFalse(classWorld.isDirectlyInstantiated(String_));
+    Expect.isFalse(classWorld.isIndirectlyInstantiated(String_));
+    Expect.isFalse(classWorld.isInstantiated(String_));
 
-    TypeMask empty = const TypeMask.nonNullEmpty();
-    TypeMask subclassObject = new TypeMask.nonNullSubclass(Object_, classWorld);
-    TypeMask exactA = new TypeMask.nonNullExact(A, classWorld);
-    TypeMask subclassA = new TypeMask.nonNullSubclass(A, classWorld);
-    TypeMask subtypeA = new TypeMask.nonNullSubtype(A, classWorld);
-    TypeMask exactB = new TypeMask.nonNullExact(B, classWorld);
-    TypeMask subclassB = new TypeMask.nonNullSubclass(B, classWorld);
-    TypeMask exactC = new TypeMask.nonNullExact(C, classWorld);
-    TypeMask exactD = new TypeMask.nonNullExact(D, classWorld);
-    TypeMask exactE = new TypeMask.nonNullExact(E, classWorld);
+    Expect.isTrue(classWorld.isDirectlyInstantiated(JSString));
+    Expect.isFalse(classWorld.isIndirectlyInstantiated(JSString));
+    Expect.isTrue(classWorld.isInstantiated(JSString));
 
-    check([],
-          result: empty,
-          disjointMasks: [],
-          containedClasses: []);
+    TypeMask subtypeString = new TypeMask.nonNullSubtype(String_, classWorld);
+    TypeMask exactJSString = new TypeMask.nonNullExact(JSString, classWorld);
+    TypeMask subtypeJSString =
+        new TypeMask.nonNullSubtype(JSString, classWorld);
+    TypeMask subclassJSString =
+        new TypeMask.nonNullSubclass(JSString, classWorld);
 
-    check([exactA],
-          result: exactA,
-          disjointMasks: [exactA],
-          containedClasses: [A]);
-
-    check([exactA, exactA],
-          result: exactA,
-          disjointMasks: [exactA],
-          containedClasses: [A]);
-
-    check([exactA, exactB],
-          disjointMasks: [exactA, exactB],
-          flattened: subclassObject,
-          containedClasses: [A, B]);
-
-    check([subclassObject],
-          result: subclassObject,
-          disjointMasks: [subclassObject],
-          containedClasses: [Object_, A, B, C, D, E]);
-
-    check([subclassObject, exactA],
-          disjointMasks: [subclassObject],
-          result: subclassObject,
-          containedClasses: [Object_, A, B, C, D, E]);
-
-    check([exactA, exactC],
-          disjointMasks: [subclassA],
-          result: subclassA,
-          containedClasses: [A, C]);
-
-    check([exactA, exactB, exactC],
-          disjointMasks: [subclassA, exactB],
-          flattened: subclassObject,
-          containedClasses: [A, B, C]);
-
-    check([exactA, exactD],
-          disjointMasks: [subtypeA],
-          result: subtypeA,
-          containedClasses: [A, C, D, E]);
-
-    check([exactA, exactB, exactD],
-          disjointMasks: [subtypeA, exactB],
-          flattened: subclassObject,
-          containedClasses: [A, B, C, D, E]);
-
-    check([exactA, exactE],
-          disjointMasks: [subtypeA],
-          result: subtypeA,
-          containedClasses: [A, C, D, E]);
-
-    check([exactA, exactB, exactE],
-          disjointMasks: [subtypeA, exactB],
-          flattened: subclassObject,
-          containedClasses: [A, B, C, D, E]);
-
-    check([exactB, exactE, exactA],
-          disjointMasks: [subclassB, exactA],
-          flattened: subclassObject,
-          containedClasses: [A, B, E]);
-
-    check([exactE, exactA, exactB],
-          disjointMasks: [subtypeA, exactB],
-          flattened: subclassObject,
-          containedClasses: [A, B, C, D, E]);
-
-    check([exactE, exactB, exactA],
-          disjointMasks: [subclassB, exactA],
-          flattened: subclassObject,
-          containedClasses: [A, B, E]);
-  }));
+    Expect.equals(exactJSString, subtypeString);
+    Expect.equals(exactJSString, subtypeJSString);
+    Expect.equals(exactJSString, subclassJSString);
 }
diff --git a/tests/compiler/dart2js/type_mask_test.dart b/tests/compiler/dart2js/type_mask_test.dart
index fa7d108..0547260 100644
--- a/tests/compiler/dart2js/type_mask_test.dart
+++ b/tests/compiler/dart2js/type_mask_test.dart
@@ -23,7 +23,7 @@
   var compiler = compilerFor(CODE, uri);
   var classWorld = compiler.world;
 
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var classA = findElement(compiler, 'A');
     var classB = findElement(compiler, 'B');
     var classC = findElement(compiler, 'C');
@@ -37,8 +37,8 @@
     var subclassA = new TypeMask.nonNullSubclass(classA, classWorld);
     var subtypeA = new TypeMask.nonNullSubtype(classA, classWorld);
 
-    var subclassObject = new TypeMask.nonNullSubclass(compiler.objectClass,
-        classWorld);
+    var subclassObject = new TypeMask.nonNullSubclass(
+        compiler.coreClasses.objectClass, classWorld);
 
     var unionABC = UnionTypeMask.unionOf([exactA, exactB, exactC], classWorld);
     var unionABnC = UnionTypeMask.unionOf([exactA, exactB.nullable(), exactC],
diff --git a/tests/compiler/dart2js/type_test_helper.dart b/tests/compiler/dart2js/type_test_helper.dart
index 32ed3ff..df06008 100644
--- a/tests/compiler/dart2js/type_test_helper.dart
+++ b/tests/compiler/dart2js/type_test_helper.dart
@@ -37,8 +37,6 @@
                       bool stopAfterTypeInference: false,
                       String mainSource}) {
     Uri uri;
-    Function getErrors;
-    Function getWarnings;
     Compiler compiler;
     bool stopAfterTypeInference = mainSource != null;
     if (mainSource == null) {
@@ -48,6 +46,7 @@
     } else {
       source = '$mainSource\n$source';
     }
+    memory.DiagnosticCollector collector;
     if (useMockCompiler) {
       uri = new Uri(scheme: 'source');
       mock.MockCompiler mockCompiler = mock.compilerFor(
@@ -56,29 +55,26 @@
           analyzeAll: !stopAfterTypeInference,
           analyzeOnly: !stopAfterTypeInference);
       mockCompiler.diagnosticHandler = mock.createHandler(mockCompiler, source);
-      getErrors = () => mockCompiler.errors;
-      getWarnings = () => mockCompiler.warnings;
+      collector = mockCompiler.diagnosticCollector;
       compiler = mockCompiler;
     } else {
-      memory.DiagnosticCollector collector = new memory.DiagnosticCollector();
+      collector = new memory.DiagnosticCollector();
       uri = Uri.parse('memory:main.dart');
       compiler = memory.compilerFor(
           memorySourceFiles: {'main.dart': source},
           diagnosticHandler: collector,
           options: stopAfterTypeInference
               ? [] : [Flags.analyzeAll, Flags.analyzeOnly]);
-      getErrors = () => collector.errors;
-      getWarnings = () => collector.warnings;
     }
     compiler.stopAfterTypeInference = stopAfterTypeInference;
-    return compiler.runCompiler(uri).then((_) {
+    return compiler.run(uri).then((_) {
       if (expectNoErrors || expectNoWarningsOrErrors) {
-        var errors = getErrors();
+        var errors = collector.errors;
         Expect.isTrue(errors.isEmpty,
             'Unexpected errors: ${errors}');
       }
       if (expectNoWarningsOrErrors) {
-        var warnings = getWarnings();
+        var warnings = collector.warnings;
         Expect.isTrue(warnings.isEmpty,
             'Unexpected warnings: ${warnings}');
       }
diff --git a/tests/compiler/dart2js/type_variable_bound_test.dart b/tests/compiler/dart2js/type_variable_bound_test.dart
index b93c42d..d8a6903 100644
--- a/tests/compiler/dart2js/type_variable_bound_test.dart
+++ b/tests/compiler/dart2js/type_variable_bound_test.dart
@@ -12,7 +12,7 @@
   var compiler =
       compilerFor(source, uri, analyzeOnly: true, enableTypeAssertions: true);
   compiler.diagnosticHandler = createHandler(compiler, source);
-  return compiler.runCompiler(uri).then((_) {
+  return compiler.run(uri).then((_) {
     return compiler;
   });
 }
@@ -23,19 +23,20 @@
   if (warnings == null) warnings = [];
   if (warnings is! List) warnings = [warnings];
   asyncTest(() => compile(source).then((compiler) {
+    DiagnosticCollector collector = compiler.diagnosticCollector;
     Expect.equals(!errors.isEmpty, compiler.compilationFailed);
-    Expect.equals(errors.length, compiler.errors.length,
-                  'unexpected error count: ${compiler.errors.length} '
+    Expect.equals(errors.length, collector.errors.length,
+                  'unexpected error count: ${collector.errors.length} '
                   'expected ${errors.length}');
-    Expect.equals(warnings.length, compiler.warnings.length,
-                  'unexpected warning count: ${compiler.warnings.length} '
+    Expect.equals(warnings.length, collector.warnings.length,
+                  'unexpected warning count: ${collector.warnings.length} '
                   'expected ${warnings.length}');
 
     for (int i = 0 ; i < errors.length ; i++) {
-      Expect.equals(errors[i], compiler.errors[i].message.kind);
+      Expect.equals(errors[i], collector.errors.elementAt(i).message.kind);
     }
     for (int i = 0 ; i < warnings.length ; i++) {
-      Expect.equals(warnings[i], compiler.warnings[i].message.kind);
+      Expect.equals(warnings[i], collector.warnings.elementAt(i).message.kind);
     }
   }));
 }
@@ -48,15 +49,18 @@
   new A();
 }
 """).then((compiler) {
+    DiagnosticCollector collector = compiler.diagnosticCollector;
     Expect.isFalse(compiler.compilationFailed);
-    Expect.isTrue(compiler.errors.isEmpty,
-                  'unexpected errors: ${compiler.errors}');
-    Expect.equals(1, compiler.warnings.length,
-                  'expected exactly one warning, but got ${compiler.warnings}');
+    Expect.isTrue(collector.errors.isEmpty,
+                  'unexpected errors: ${collector.errors}');
+    Expect.equals(1, collector.warnings.length,
+                  'expected exactly one warning, but got ${collector.warnings}');
 
+    print(collector.warnings.elementAt(0));
     Expect.equals(MessageKind.CYCLIC_TYPE_VARIABLE,
-                  compiler.warnings[0].message.kind);
-    Expect.equals("T", compiler.warnings[0].node.toString());
+                  collector.warnings.elementAt(0).message.kind);
+    Expect.equals("T",
+        collector.warnings.elementAt(0).message.arguments['typeVariableName']);
   }));
 }
 
@@ -68,19 +72,22 @@
   new B();
 }
 """).then((compiler) {
+    DiagnosticCollector collector = compiler.diagnosticCollector;
     Expect.isFalse(compiler.compilationFailed);
-    print(compiler.errors);
-    Expect.isTrue(compiler.errors.isEmpty, 'unexpected errors');
-    Expect.equals(2, compiler.warnings.length,
-                  'expected exactly two errors, but got ${compiler.warnings}');
+    print(collector.errors);
+    Expect.isTrue(collector.errors.isEmpty, 'unexpected errors');
+    Expect.equals(2, collector.warnings.length,
+                  'expected exactly two errors, but got ${collector.warnings}');
 
     Expect.equals(MessageKind.CYCLIC_TYPE_VARIABLE,
-                  compiler.warnings[0].message.kind);
-    Expect.equals("T", compiler.warnings[0].node.toString());
+                  collector.warnings.elementAt(0).message.kind);
+    Expect.equals("T",
+        collector.warnings.elementAt(0).message.arguments['typeVariableName']);
 
     Expect.equals(MessageKind.CYCLIC_TYPE_VARIABLE,
-                  compiler.warnings[1].message.kind);
-    Expect.equals("S", compiler.warnings[1].node.toString());
+                  collector.warnings.elementAt(1).message.kind);
+    Expect.equals("S",
+        collector.warnings.elementAt(1).message.arguments['typeVariableName']);
   }));
 }
 
@@ -92,23 +99,27 @@
   new C();
 }
 """).then((compiler) {
+    DiagnosticCollector collector = compiler.diagnosticCollector;
     Expect.isFalse(compiler.compilationFailed);
-    print(compiler.errors);
-    Expect.isTrue(compiler.errors.isEmpty, 'unexpected errors');
-    Expect.equals(3, compiler.warnings.length,
-                  'expected exactly one error, but got ${compiler.warnings}');
+    print(collector.errors);
+    Expect.isTrue(collector.errors.isEmpty, 'unexpected errors');
+    Expect.equals(3, collector.warnings.length,
+                  'expected exactly one error, but got ${collector.warnings}');
 
     Expect.equals(MessageKind.CYCLIC_TYPE_VARIABLE,
-                  compiler.warnings[0].message.kind);
-    Expect.equals("T", compiler.warnings[0].node.toString());
+                  collector.warnings.elementAt(0).message.kind);
+    Expect.equals("T",
+        collector.warnings.elementAt(0).message.arguments['typeVariableName']);
 
     Expect.equals(MessageKind.CYCLIC_TYPE_VARIABLE,
-                  compiler.warnings[1].message.kind);
-    Expect.equals("S", compiler.warnings[1].node.toString());
+                  collector.warnings.elementAt(1).message.kind);
+    Expect.equals("S",
+        collector.warnings.elementAt(1).message.arguments['typeVariableName']);
 
     Expect.equals(MessageKind.CYCLIC_TYPE_VARIABLE,
-                  compiler.warnings[2].message.kind);
-    Expect.equals("U", compiler.warnings[2].node.toString());
+                  collector.warnings.elementAt(2).message.kind);
+    Expect.equals("U",
+        collector.warnings.elementAt(2).message.arguments['typeVariableName']);
   }));
 }
 
@@ -120,19 +131,22 @@
   new D();
 }
 """).then((compiler) {
+    DiagnosticCollector collector = compiler.diagnosticCollector;
     Expect.isFalse(compiler.compilationFailed);
-    print(compiler.errors);
-    Expect.isTrue(compiler.errors.isEmpty, 'unexpected errors');
-    Expect.equals(2, compiler.warnings.length,
-                  'expected exactly one error, but got ${compiler.warnings}');
+    print(collector.errors);
+    Expect.isTrue(collector.errors.isEmpty, 'unexpected errors');
+    Expect.equals(2, collector.warnings.length,
+                  'expected exactly one error, but got ${collector.warnings}');
 
     Expect.equals(MessageKind.CYCLIC_TYPE_VARIABLE,
-                  compiler.warnings[0].message.kind);
-    Expect.equals("S", compiler.warnings[0].node.toString());
+                  collector.warnings.elementAt(0).message.kind);
+    Expect.equals("S",
+        collector.warnings.elementAt(0).message.arguments['typeVariableName']);
 
     Expect.equals(MessageKind.CYCLIC_TYPE_VARIABLE,
-                  compiler.warnings[1].message.kind);
-    Expect.equals("U", compiler.warnings[1].node.toString());
+                  collector.warnings.elementAt(1).message.kind);
+    Expect.equals("U",
+        collector.warnings.elementAt(1).message.arguments['typeVariableName']);
   }));
 }
 
diff --git a/tests/compiler/dart2js/union_type_test.dart b/tests/compiler/dart2js/union_type_test.dart
index c103d6f..4ae2dac 100644
--- a/tests/compiler/dart2js/union_type_test.dart
+++ b/tests/compiler/dart2js/union_type_test.dart
@@ -5,22 +5,29 @@
 import "package:async_helper/async_helper.dart";
 import "package:expect/expect.dart";
 import "package:compiler/src/types/types.dart";
-
-import "compiler_helper.dart";
+import "package:compiler/src/world.dart";
+import 'type_test_helper.dart';
 
 main() {
-  MockCompiler compiler = new MockCompiler.internal(analyzeOnly: true);
-  asyncTest(() => compiler.runCompiler(null, """
+
+  asyncTest(() async {
+    TypeEnvironment env = await TypeEnvironment.create(r"""
+      class A {}
+      class B {}
+      """,
+      mainSource: r"""
       main() {
-        print(2); print("Hello");
+        new A();
+        new B();
       }
-    """).then((_) {
-    FlatTypeMask mask1 =
-        new FlatTypeMask.exact(compiler.intClass);
-    FlatTypeMask mask2 =
-        new FlatTypeMask.exact(compiler.stringClass);
-    UnionTypeMask union1 = mask1.nonNullable().union(mask2, compiler.world);
-    UnionTypeMask union2 = mask2.nonNullable().union(mask1, compiler.world);
+      """,
+      useMockCompiler: false);
+    World world = env.compiler.world;
+    world.populate();
+    FlatTypeMask mask1 = new FlatTypeMask.exact(env.getElement('A'));
+    FlatTypeMask mask2 = new FlatTypeMask.exact(env.getElement('B'));
+    UnionTypeMask union1 = mask1.nonNullable().union(mask2, world);
+    UnionTypeMask union2 = mask2.nonNullable().union(mask1, world);
     Expect.equals(union1, union2);
-  }));
+  });
 }
diff --git a/tests/compiler/dart2js/unparser2_test.dart b/tests/compiler/dart2js/unparser2_test.dart
index 91e13aa..8ede8c9 100644
--- a/tests/compiler/dart2js/unparser2_test.dart
+++ b/tests/compiler/dart2js/unparser2_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import "package:expect/expect.dart";
+import "package:compiler/src/parser/element_listener.dart";
 import "package:compiler/src/parser/node_listener.dart";
 import "package:compiler/src/parser/parser.dart";
 import "package:compiler/src/scanner/string_scanner.dart";
@@ -91,7 +92,8 @@
   CompilationUnitElement element = new CompilationUnitElementX(script, lib);
   StringScanner scanner = new StringScanner.fromString(source);
   Token beginToken = scanner.tokenize();
-  NodeListener listener = new NodeListener(diagnosticListener, element);
+  NodeListener listener = new NodeListener(
+      const ScannerOptions(), diagnosticListener, element);
   Parser parser = new Parser(listener);
   parser.parseUnit(beginToken);
   Node node = listener.popNode();
diff --git a/tests/compiler/dart2js/warnings_checker.dart b/tests/compiler/dart2js/warnings_checker.dart
index 1652a1e..3e50eae 100644
--- a/tests/compiler/dart2js/warnings_checker.dart
+++ b/tests/compiler/dart2js/warnings_checker.dart
@@ -55,7 +55,7 @@
     if (statusMap != null && statusMap.containsKey('missing')) {
       missingStatus = statusMap['missing'];
     }
-    for (DiagnosticMessage message in collector.warnings) {
+    for (CollectedMessage message in collector.warnings) {
       Expect.equals(uri, message.uri);
       int lineNo = file.getLine(message.begin);
       if (expectedWarnings.containsKey(lineNo)) {
diff --git a/tests/compiler/dart2js_extra/23404_test.dart b/tests/compiler/dart2js_extra/23404_test.dart
index 113d78a..bfd52ba 100644
--- a/tests/compiler/dart2js_extra/23404_test.dart
+++ b/tests/compiler/dart2js_extra/23404_test.dart
@@ -11,8 +11,8 @@
 foo([a='\u00a0']) => a;
 bar() => '';
 
-@NoInline
-@AssumeDynamic
+@NoInline()
+@AssumeDynamic()
 confuse(x) => x;
 
 main() {
diff --git a/tests/compiler/dart2js_extra/big_allocation_expression_test.dart b/tests/compiler/dart2js_extra/big_allocation_expression_test.dart
new file mode 100644
index 0000000..586376a
--- /dev/null
+++ b/tests/compiler/dart2js_extra/big_allocation_expression_test.dart
@@ -0,0 +1,4140 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This program crashes the SSA backend. http://dartbug.com/24635.
+
+import "package:expect/expect.dart";
+
+class A {
+  var a;
+  var b;
+
+  factory A(a, x) = A.q;
+
+  // @NoInline()  // This annotation causes the test to compile on SSA backend.
+  A.q(this.a, x) : b = x == null ? null : new W(x);
+}
+
+class W {
+  var a;
+  W(this.a);
+}
+
+measure(x, m) {
+  if (x == null) {
+    m['null']++;
+  } else if (x is W) {
+    m['W']++;
+    measure(x.a, m);
+  } else if (x is A) {
+    m['A']++;
+    measure(x.a, m);
+    measure(x.b, m);
+  }
+  return m;
+}
+
+main() {
+  // 4095 'new A'(...)' expressions, 12 calls deep.
+  var e = new A(
+      new A(
+          new A(
+              new A(
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))))),
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))))),
+              new A(
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))))),
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))))))),
+          new A(
+              new A(
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))))),
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))))),
+              new A(
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))))),
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))))))),
+      new A(
+          new A(
+              new A(
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))))),
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))))),
+              new A(
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))))),
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))))))),
+          new A(
+              new A(
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))))),
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))))),
+              new A(
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))))),
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))))))));
+
+  var m = measure(e, {'null': 0, 'A': 0, 'W': 0});
+  Expect.equals(4096, m['null']);
+  Expect.equals(4095, m['A']);
+  Expect.equals(2047, m['W']);
+}
diff --git a/tests/compiler/dart2js_extra/dart2js_extra.status b/tests/compiler/dart2js_extra/dart2js_extra.status
index c530b1e..9a04a94 100644
--- a/tests/compiler/dart2js_extra/dart2js_extra.status
+++ b/tests/compiler/dart2js_extra/dart2js_extra.status
@@ -67,11 +67,12 @@
 invalid_annotation_test/01: MissingCompileTimeError, OK # vm is lazy
 lookup_map/dead_entry_through_mirrors_test: SkipByDesign # Test for tree-shaking, vm never tree-shakes
 
+[ $compiler == dart2js && $cps_ir == false ]
+big_allocation_expression_test: Crash # Issue 24635
+
 [ $compiler == dart2js && $cps_ir ]
 16407_test: Pass # Please triage this failure.
-23432_test: RuntimeError # Issue 23432
 async_stacktrace_test/asyncStar: Crash # (foo()async*{try {tr...  cannot handle sync*/async* functions
-closure_capture5_test: Crash # (i=0): For-loop variable captured in loop header
 deferred/deferred_class_test: RuntimeError # Z.loadLibrary is not a function
 deferred/deferred_constant2_test: RuntimeError # U.loadLibrary is not a function
 deferred/deferred_constant3_test: RuntimeError # Y.loadLibrary is not a function
diff --git a/tests/compiler/dart2js_extra/operator_test.dart b/tests/compiler/dart2js_extra/operator_test.dart
index 225976f..96ee9dc 100644
--- a/tests/compiler/dart2js_extra/operator_test.dart
+++ b/tests/compiler/dart2js_extra/operator_test.dart
@@ -3,22 +3,80 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import "package:expect/expect.dart";
+@NoInline() @AssumeDynamic()
+confuse(x) => x;
 
+@NoInline()
+asNum(x) {
+  var result = confuse(x);
+  if (result is num) return result;
+  throw new ArgumentError.value(x);
+}
+
+@NoInline()
+uint31(x) {
+  var result = confuse(x);
+  if (x is int) {
+    var masked = 0x7fffffff & x;  // inferred uint31 type.
+    if (masked == x) return masked;
+  }
+  throw new ArgumentError('Not uint31: $x');
+}
+
+@NoInline()
+uint32(x) {
+  var result = confuse(x);
+  if (x is int) {
+    var masked = 0xffffffff & x;  // inferred uint32 type.
+    if (masked == x) return masked;
+  }
+  throw new ArgumentError('Not uint32: $x');
+}
+
+@NoInline()
 int zero() { return 0; }
+
+@NoInline()
 int one() { return 1; }
+
+@NoInline()
 int minus1() { return 0 - 1; }
+
+@NoInline()
+int minus2() { return 0 - 2; }
+
+@NoInline()
 int two() { return 2; }
+
+@NoInline()
 int three() { return 3; }
+
+@NoInline()
 int five() { return 5; }
+
+@NoInline()
 int minus5() { return 0 - 5; }
+
+@NoInline()
 int ninetyNine() { return 99; }
+
+@NoInline()
 int four99() { return 499; }
+
+@NoInline()
 int four99times99() { return 499 * 99; }
+
+@NoInline()
 int four99times99plus1() { return 499 * 99 + 1; }
 
+@NoInline()
 void addTest() {
   var m1 = 0 - 1;
   Expect.equals(0, 0 + 0);
+  Expect.equals(0, confuse(0) + 0);
+  Expect.equals(0, asNum(0) + 0);
+  Expect.equals(0, uint31(0) + 0);
+
   Expect.equals(m1, m1 + 0);
   Expect.equals(0, m1 + 1);
   Expect.equals(499, 400 + 99);
@@ -27,6 +85,7 @@
   Expect.equals(2, one() + one());
 }
 
+@NoInline()
 void subTest() {
   var m1 = 0 - 1;
   Expect.equals(0, 0 - 0);
@@ -38,6 +97,7 @@
   Expect.equals(0, one() - one());
 }
 
+@NoInline()
 void mulTest() {
   var m1 = 0 - 1;
   Expect.equals(0, 0 * 0);
@@ -49,23 +109,30 @@
   Expect.equals(49401, four99() * 99);
 }
 
+@NoInline()
 void divTest() {
   var m1 = 0.0 - 1.0;
   var m2 = 0 - 2;
   Expect.equals(1.0, 2 / 2);
   Expect.equals(m1, m2 / 2);
+  Expect.equals(m1, minus2() / 2);
   Expect.equals(0.5, 1 / 2);
   Expect.equals(499.0, 49401 / 99);
 
   Expect.equals(1.0, two() / 2);
   Expect.equals(1.0, 2 / two());
   Expect.equals(m1, m2 / two());
+  Expect.equals(m1, minus2() / two());
   Expect.equals(m1, two() / m2);
+  Expect.equals(m1, two() / minus2());
   Expect.equals(0.5, 1 / two());
   Expect.equals(0.5, one() / 2);
   Expect.equals(499.0, four99times99() / 99);
+
+  Expect.equals(1.5, confuse(150) / confuse(100));
 }
 
+@NoInline()
 void tdivTest() {
   var m1 = 0 - 1;
   var m2 = 0 - 2;
@@ -84,8 +151,62 @@
   Expect.equals(0, one() ~/ 2);
   Expect.equals(499, four99times99() ~/ 99);
   Expect.equals(499, four99times99plus1() ~/ 99);
+
+  Expect.equals(-33, -100 ~/ 3);
+  Expect.equals(-33, asNum(-100) ~/ 3);
+  Expect.equals(33, -100 ~/ -3);
+  Expect.equals(33, asNum(-100) ~/ -3);
+
+  // Signed int32 boundary is involved in optimizations.
+
+  Expect.equals(-0x80000000,  -0x80000000 ~/ 1.0);
+  Expect.equals(-0x80000000,  -0x80000000 ~/ 1.0000000000000001);
+  Expect.equals(-0x7fffffff,  -0x80000000 ~/ 1.0000000000000002);
+
+  Expect.equals(-0x80000000,  asNum(-0x80000000) ~/ 1.0);
+  Expect.equals(-0x80000000,  asNum(-0x80000000) ~/ 1.0000000000000001);
+  Expect.equals(-0x7fffffff,  asNum(-0x80000000) ~/ 1.0000000000000002);
+
+  Expect.equals(-0x80000000,  asNum(0x80000000) ~/ -1.0);
+  Expect.equals(-0x80000000,  asNum(0x80000000) ~/ -1.0000000000000001);
+  Expect.equals(-0x7fffffff,  asNum(0x80000000) ~/ -1.0000000000000002);
+
+  Expect.equals(0x7fffffff,  0x10000000 ~/ .12500000000000002);
+  Expect.equals(0x80000000,  0x10000000 ~/ .125);
+  Expect.equals(-0x7fffffff,  0x10000000 ~/ -.12500000000000002);
+  Expect.equals(-0x80000000,  0x10000000 ~/ -.125);
+
+  Expect.equals(0x7fffffff,  uint31(0x10000000) ~/ .12500000000000002);
+  Expect.equals(0x80000000,  uint31(0x10000000) ~/ .125);
+  Expect.equals(-0x7fffffff,  uint31(0x10000000) ~/ -.12500000000000002);
+  Expect.equals(-0x80000000,  uint31(0x10000000) ~/ -.125);
+
+  // These can be compiled to `(a / 2) | 0`.
+  Expect.equals(100,  uint31(200) ~/ 2);
+  Expect.equals(100,  uint32(200) ~/ 2);
+
+  Expect.equals(100,  asNum(200) ~/ 2);
+  Expect.equals(100,  confuse(200) ~/ 2);
+  Expect.equals(-100,  uint31(200) ~/ -2);
+  Expect.equals(-100,  uint32(200) ~/ -2);
+  Expect.equals(-100,  asNum(200) ~/ -2);
+  Expect.equals(-100,  confuse(200) ~/ -2);
+
+  // These can be compiled to `((a + b) / 2) | 0`.
+  Expect.equals(100,  (uint31(100) + uint31(100)) ~/ 2);
+  Expect.equals(0x7fffffff,  (uint31(0x7fffffff) + uint31(0x7fffffff)) ~/ 2);
+
+  // NaN and Infinity results are errors.
+  Expect.throws(() => -1 ~/ 0);
+  Expect.throws(() => 1.5 ~/ 0);
+  Expect.throws(() => 1e200 ~/ 1e-200);
+  Expect.throws(() => -1e200 ~/ 1e-200);
+  Expect.throws(() => 1e200 ~/ -1e-200);
+  Expect.throws(() => -1e200 ~/ -1e-200);
+  Expect.throws(() => double.NAN ~/ 2);
 }
 
+@NoInline()
 void modTest() {
   var m5 = 0 - 5;
   var m3 = 0 - 3;
@@ -103,6 +224,36 @@
   Expect.equals(2, five() % m3);
 }
 
+@NoInline()
+void remainderTest() {
+  var m5 = 0 - 5;
+  Expect.equals(2, confuse(5).remainder(3));
+  Expect.equals(0, confuse(49401).remainder(99));
+  Expect.equals(1, confuse(49402).remainder(99));
+  Expect.equals(-2, confuse(m5).remainder(3));
+  Expect.equals(2, confuse(5).remainder(-3));
+
+  Expect.equals(2, uint32(5).remainder(3));
+  Expect.equals(0, uint32(49401).remainder(99));
+  Expect.equals(1, uint32(49402).remainder(99));
+  Expect.equals(-2, (-5).remainder(uint32(3)));
+  Expect.equals(2, uint32(5).remainder(-3));
+
+  Expect.equals(2, 5.remainder(3));
+  Expect.equals(0, 49401.remainder(99));
+  Expect.equals(1, 49402.remainder(99));
+  Expect.equals(-2, (-5).remainder(3));
+  Expect.equals(2, 5.remainder(-3));
+
+  Expect.equals(2, five().remainder(3));
+  Expect.equals(2, 5.remainder(three()));
+  Expect.equals(0, four99times99().remainder(99));
+  Expect.equals(1, four99times99plus1().remainder(99));
+  Expect.equals(-2, minus5().remainder(3));
+  Expect.equals(2, five().remainder(-3));
+}
+
+@NoInline()
 void shlTest() {
   Expect.equals(2, 1 << 1);
   Expect.equals(8, 1 << 3);
@@ -110,17 +261,38 @@
 
   Expect.equals(10, five() << 1);
   Expect.equals(24, 3 << three());
+
+  Expect.equals(10, confuse(5) << 1);
+  Expect.equals(24, 3 << confuse(3));
+
+  Expect.equals(10, uint31(5) << 1);
+  Expect.equals(24, 3 << uint31(3));
+
+  Expect.equals(10, asNum(5) << 1);
+  Expect.equals(24, 3 << asNum(3));
 }
 
+@NoInline()
 void shrTest() {
   Expect.equals(1, 2 >> 1);
   Expect.equals(1, 8 >> 3);
   Expect.equals(3, 6 >> 1);
 
-  var x = 0 - ninetyNine();
   Expect.equals(6, ninetyNine() >> 4);
+  Expect.equals(6, confuse(99) >> 4);
+  Expect.equals(6, asNum(99) >> 4);
+  Expect.equals(6, uint31(99) >> 4);
+
+  Expect.equals(6, 99 >> 4);
+  Expect.equals(6, 99 >> confuse(4));
+  Expect.equals(6, 99 >> asNum(4));
+  Expect.equals(6, 99 >> uint31(4));
+
+  Expect.equals(0, uint31(1) >> 31);
+  Expect.equals(0, asNum(0xffffffff) >> 32);
 }
 
+@NoInline()
 void andTest() {
   Expect.equals(2, 10 & 3);
   Expect.equals(7, 15 & 7);
@@ -129,8 +301,12 @@
   Expect.equals(99, ninetyNine() & ninetyNine());
   Expect.equals(34, four99() & 42);
   Expect.equals(3, minus5() & 7);
+
+  Expect.equals(0,  uint31(0x7ffffffe) & uint31(1));
+  Expect.equals(0,  asNum(0x7ffffffe) & asNum(1));
 }
 
+@NoInline()
 void orTest() {
   Expect.equals(11, 10 | 3);
   Expect.equals(15, 15 | 7);
@@ -138,8 +314,13 @@
 
   Expect.equals(99, ninetyNine() | ninetyNine());
   Expect.equals(507, four99() | 42);
+
+  Expect.equals(11, asNum(10) | 3);
+  Expect.equals(15, asNum(15) | 7);
+  Expect.equals(10, asNum(10) | 10);
 }
 
+@NoInline()
 void xorTest() {
   Expect.equals(9, 10 ^ 3);
   Expect.equals(8, 15 ^ 7);
@@ -151,21 +332,26 @@
   Expect.equals(6, minus5() ^ -3);
 }
 
+@NoInline()
 void notTest() {
   Expect.equals(4, ~minus5());
 }
 
+@NoInline()
 void negateTest() {
   Expect.equals(minus5(), -5);
   Expect.equals(-5, -five());
   Expect.equals(5, -minus5());
-  var x = 3;
-  if (false) x = 5;
-  Expect.equals(-3, -x);
-  var y = -5;
-  Expect.equals(8, x - y);
+
+  Expect.equals(-3, -confuse(3));
+  Expect.equals(-3, -asNum(3));
+  Expect.equals(-3, -uint31(3));
+
+  Expect.equals(3, -confuse(-3));
+  Expect.equals(3, -asNum(-3));
 }
 
+@NoInline()
 void equalsTest() {
   // Equality of normal numbers is already well tested with "Expect.equals".
   Expect.equals(true, true == true);
@@ -209,6 +395,7 @@
   Expect.equals(false, null == falseValue);
 }
 
+@NoInline()
 void lessTest() {
   var m1 = minus1();
   Expect.equals(true, 1 < 2);
@@ -230,8 +417,13 @@
   Expect.equals(true, m1 < 0);
   Expect.equals(false, 0 < m1);
   Expect.equals(false, m1 < m1);
+
+  Expect.equals(true, minus1() < 0);
+  Expect.equals(false, 0 < minus1());
+  Expect.equals(false, minus1() < minus1());
 }
 
+@NoInline()
 void lessEqualTest() {
   var m1 = minus1();
   Expect.equals(true, 1 <= 2);
@@ -242,6 +434,14 @@
   Expect.equals(false, 1 <= 0);
   Expect.equals(true, 0 <= 0);
 
+  Expect.equals(true, confuse(1) <= 2);
+  Expect.equals(false, confuse(2) <= 1);
+  Expect.equals(true, confuse(1) <= 1);
+
+  Expect.equals(true, confuse(0) <= 1);
+  Expect.equals(false, confuse(1) <= 0);
+  Expect.equals(true, confuse(0) <= 0);
+
   Expect.equals(true, one() <= 2);
   Expect.equals(false, 2 <= one());
   Expect.equals(true, 1 <= one());
@@ -253,8 +453,13 @@
   Expect.equals(true, m1 <= 0);
   Expect.equals(false, 0 <= m1);
   Expect.equals(true, m1 <= m1);
+
+  Expect.equals(true, minus1() <= 0);
+  Expect.equals(false, 0 <= minus1());
+  Expect.equals(true, minus1() <= minus1());
 }
 
+@NoInline()
 void greaterTest() {
   var m1 = minus1();
   Expect.equals(false, 1 > 2);
@@ -276,8 +481,13 @@
   Expect.equals(false, m1 > 0);
   Expect.equals(true, 0 > m1);
   Expect.equals(false, m1 > m1);
+
+  Expect.equals(false, minus1() > 0);
+  Expect.equals(true, 0 > minus1());
+  Expect.equals(false, minus1() > minus1());
 }
 
+@NoInline()
 void greaterEqualTest() {
   var m1 = minus1();
   Expect.equals(false, 1 >= 2);
@@ -299,6 +509,10 @@
   Expect.equals(false, m1 >= 0);
   Expect.equals(true, 0 >= m1);
   Expect.equals(true, m1 >= m1);
+
+  Expect.equals(false, minus1() >= 0);
+  Expect.equals(true, 0 >= minus1());
+  Expect.equals(true, minus1() >= minus1());
 }
 
 void main() {
@@ -308,6 +522,7 @@
   divTest();
   tdivTest();
   modTest();
+  remainderTest();
   shlTest();
   shrTest();
   andTest();
diff --git a/tests/compiler/dart2js_extra/useful_error_message_1_test.dart b/tests/compiler/dart2js_extra/useful_error_message_1_test.dart
index 59a3bc913..07a6de0 100644
--- a/tests/compiler/dart2js_extra/useful_error_message_1_test.dart
+++ b/tests/compiler/dart2js_extra/useful_error_message_1_test.dart
@@ -7,8 +7,8 @@
 
 import "package:expect/expect.dart";
 
-@NoInline
-@AssumeDynamic
+@NoInline()
+@AssumeDynamic()
 confuse(x) => x;
 
 class CCCC {
diff --git a/tests/compiler/dart2js_native/js_constant_test.dart b/tests/compiler/dart2js_native/js_constant_test.dart
new file mode 100644
index 0000000..19b2e6f
--- /dev/null
+++ b/tests/compiler/dart2js_native/js_constant_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:_foreign_helper' show JS;
+import "package:expect/expect.dart";
+
+// Negative constant numbers must be generated as negation, not just a literal
+// with a sign, i.e.
+//
+//     (-5).toString()
+//
+// not
+//
+//     -5 .toString()
+//
+// The unparethesized version is `-(5 .toString())`, which creates the string
+// `"5"`, then converts it to a number for negation, giving a number result
+// instead of a string result.
+
+@NoInline()
+checkString(r) {
+  Expect.isTrue(r is String,
+      'Expected string, found ${r} of type ${r.runtimeType}');
+}
+
+test1() {
+  checkString(JS('', '#.toString()', -5));
+}
+
+test2() {
+  checkString(JS('', '#.toString()', -1.5));
+}
+
+test3() {
+  checkString(JS('', '#.toString()', -0.0));
+}
+
+
+main() {
+  test1();
+  test2();
+  test3();
+}
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 9bda275..125d665 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -232,7 +232,7 @@
 map_values4_test: RuntimeError # Please triage this failure.
 package_resource_test: Crash # (await for(var byteSlice in resource.openRead()){streamBytes.addAll(byteSlice);}): await for
 regexp/pcre_test: Crash # Stack Overflow in LoopHierarchy.
-symbol_operator_test/03: RuntimeError # Please triage this failure.
+symbol_operator_test/03: RuntimeError # Issue 24878
 symbol_reserved_word_test/03: Pass # Please triage this failure.
 symbol_reserved_word_test/06: RuntimeError # Please triage this failure.
 symbol_reserved_word_test/09: RuntimeError # Please triage this failure.
@@ -241,3 +241,10 @@
 
 [ $compiler == dart2js && $cps_ir && $host_checked ]
 regexp/pcre_test: Crash # Stack Overflow
+
+[ $noopt ]
+apply3_test: CompileTimeError # Imports dart:mirrors
+regexp/stack-overflow_test: RuntimeError, OK # Smaller limit with irregex interpreter
+big_integer_huge_mul_vm_test: Pass, Timeout
+big_integer_parsed_mul_div_vm_test: Pass, Timeout
+int_parse_radix_test: Pass, Timeout
diff --git a/tests/corelib/data_uri_test.dart b/tests/corelib/data_uri_test.dart
new file mode 100644
index 0000000..1a21be1
--- /dev/null
+++ b/tests/corelib/data_uri_test.dart
@@ -0,0 +1,252 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import "dart:convert";
+import "dart:typed_data";
+
+main() {
+  testMediaType();
+
+  testRoundTrip("");
+  testRoundTrip("a");
+  testRoundTrip("ab");
+  testRoundTrip("abc");
+  testRoundTrip("abcd");
+  testRoundTrip("Content with special%25 characters: # ? = % # ? = %");
+  testRoundTrip("blåbærgrød", UTF8);
+  testRoundTrip("blåbærgrød", LATIN1);
+
+  testUtf8Encoding("\u1000\uffff");
+  testBytes();
+  testInvalidCharacters();
+  testErrors();
+}
+
+void testMediaType() {
+  for (var mimeType in ["", "text/plain", "text/javascript"]) {
+    for (var charset in ["", ";charset=US-ASCII", ";charset=UTF-8"]) {
+      for (var base64 in ["", ";base64"]) {
+        bool isBase64 = base64.isNotEmpty;
+        var text = "data:$mimeType$charset$base64,";
+        var uri = UriData.parse(text);
+
+        String expectedCharset =
+            charset.isEmpty ? "US-ASCII" : charset.substring(9);
+        String expectedMimeType =
+            mimeType.isEmpty ? "text/plain" : mimeType;
+
+        Expect.equals(text, "$uri");
+        Expect.equals(expectedMimeType, uri.mimeType);
+        Expect.equals(expectedCharset, uri.charset);
+        Expect.equals(isBase64, uri.isBase64);
+      }
+    }
+  }
+}
+
+void testRoundTrip(String content, [Encoding encoding]) {
+  UriData dataUri =
+      new UriData.fromString(content, encoding: encoding);
+  Expect.isFalse(dataUri.isBase64);
+  Uri uri = dataUri.uri;
+  expectUriEquals(new Uri.dataFromString(content, encoding: encoding), uri);
+
+  if (encoding != null) {
+    UriData dataUriParams = new UriData.fromString(
+        content, parameters: {"charset" : encoding.name});
+    Expect.equals("$dataUri", "$dataUriParams");
+  }
+
+  Expect.equals(encoding ?? ASCII, Encoding.getByName(dataUri.charset));
+  Expect.equals(content, dataUri.contentAsString(encoding: encoding));
+  Expect.equals(content, dataUri.contentAsString());
+  Expect.equals(content, (encoding ?? ASCII).decode(dataUri.contentAsBytes()));
+
+  uri = dataUri.uri;
+  Expect.equals(uri.toString(), dataUri.toString());
+  Expect.equals(dataUri.toString(), new UriData.fromUri(uri).toString());
+
+  dataUri = new UriData.fromBytes(content.codeUnits);
+  Expect.listEquals(content.codeUnits, dataUri.contentAsBytes());
+  Expect.equals(content, dataUri.contentAsString(encoding: LATIN1));
+
+  uri = dataUri.uri;
+  Expect.equals(uri.toString(), dataUri.toString());
+  Expect.equals(dataUri.toString(), new UriData.fromUri(uri).toString());
+  // Check that the URI is properly normalized.
+  expectUriEquals(uri, Uri.parse("$uri"));
+}
+
+void testUtf8Encoding(String content) {
+  UriData uri = new UriData.fromString(content, encoding: UTF8);
+  Expect.equals(content, uri.contentAsString(encoding: UTF8));
+  Expect.listEquals(UTF8.encode(content), uri.contentAsBytes());
+}
+
+void testInvalidCharacters() {
+  // SPACE, CTL and tspecial, plus '%' and '#' (URI gen-delim)
+  // This contains all ASCII character that are not valid in attribute/value
+  // parts.
+  var invalid =
+    '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x7f'
+    ' ()<>@,;:"/[]?=%#\x80\u{1000}\u{10000}';
+  var invalidNoSlash = invalid.replaceAll('/', '');
+  var dataUri = new UriData.fromString(
+      invalid,
+      encoding: UTF8,
+      mimeType: "$invalidNoSlash/$invalidNoSlash",
+      parameters: {invalid: invalid});
+
+  Expect.equals(invalid, dataUri.contentAsString());
+  Expect.equals("$invalidNoSlash/$invalidNoSlash", dataUri.mimeType);
+  Expect.equals(invalid, dataUri.parameters[invalid]);
+
+  var uri = dataUri.uri;
+  Expect.equals("$uri", "$dataUri");
+  expectUriEquals(uri, Uri.parse("$uri"));  // Check that it's canonicalized.
+  Expect.equals("$dataUri", new UriData.fromUri(uri).toString());
+}
+
+void testBytes() {
+  void testList(List<int> list) {
+    var dataUri = new UriData.fromBytes(list);
+    Expect.equals("application/octet-stream", dataUri.mimeType);
+    Expect.isTrue(dataUri.isBase64);
+    Expect.listEquals(list, dataUri.contentAsBytes());
+
+    dataUri = new UriData.fromBytes(list, percentEncoded: true);
+    Expect.equals("application/octet-stream", dataUri.mimeType);
+    Expect.isFalse(dataUri.isBase64);
+    Expect.listEquals(list, dataUri.contentAsBytes());
+
+    var string = new String.fromCharCodes(list);
+
+    dataUri = new UriData.fromString(string, encoding: LATIN1);
+    Expect.equals("text/plain", dataUri.mimeType);
+    Expect.isFalse(dataUri.isBase64);
+    Expect.listEquals(list, dataUri.contentAsBytes());
+
+    dataUri =
+        new UriData.fromString(string, encoding: LATIN1, base64: true);
+    Expect.equals("text/plain", dataUri.mimeType);
+    Expect.isTrue(dataUri.isBase64);
+    Expect.listEquals(list, dataUri.contentAsBytes());
+  }
+
+  void testLists(List<int> list) {
+    testList(list);
+    for (int i = 0; i < 27; i++) {
+      testList(list.sublist(i, i + i));  // All lengths from 0 to 27.
+    }
+  }
+
+  var bytes = new Uint8List(512);
+  for (int i = 0; i < bytes.length; i++) {
+    bytes[i] = i;
+  }
+  testLists(bytes);
+  testLists(new List.from(bytes));
+  testLists(new List.unmodifiable(bytes));
+}
+
+bool badArgument(e) => e is ArgumentError;
+bool badFormat(e) => e is FormatException;
+
+void testErrors() {
+  // Invalid constructor parameters.
+  Expect.throws(() { new UriData.fromBytes([], mimeType: "noslash"); },
+                badArgument);
+  Expect.throws(() { new UriData.fromBytes([257]); },
+                badArgument);
+  Expect.throws(() { new UriData.fromBytes([-1]); },
+                badArgument);
+  Expect.throws(() { new UriData.fromBytes([0x10000000]); },
+                badArgument);
+  Expect.throws(() { new UriData.fromString("", mimeType: "noslash"); },
+                badArgument);
+
+  Expect.throws(() { new Uri.dataFromBytes([], mimeType: "noslash"); },
+                badArgument);
+  Expect.throws(() { new Uri.dataFromBytes([257]); },
+                badArgument);
+  Expect.throws(() { new Uri.dataFromBytes([-1]); },
+                badArgument);
+  Expect.throws(() { new Uri.dataFromBytes([0x10000000]); },
+                badArgument);
+  Expect.throws(() { new Uri.dataFromString("", mimeType: "noslash"); },
+                badArgument);
+
+  // Empty parameters allowed, not an error.
+  var uri = new UriData.fromString("", mimeType: "", parameters: {});
+  Expect.equals("data:,", "$uri");
+  // Empty parameter key or value is an error.
+  Expect.throws(() =>  new UriData.fromString("", parameters: {"": "X"}),
+                badArgument);
+  Expect.throws(() =>  new UriData.fromString("", parameters: {"X": ""}),
+                badArgument);
+
+  // Not recognizing charset is an error.
+  uri = UriData.parse("data:;charset=arglebargle,X");
+  Expect.throws(() {
+    uri.contentAsString();
+  });
+  // Doesn't throw if we specify the encoding.
+  Expect.equals("X", uri.contentAsString(encoding: ASCII));
+
+  // Parse format.
+  Expect.throws(() { UriData.parse("notdata:,");}, badFormat);
+  Expect.throws(() { UriData.parse("text/plain,noscheme");}, badFormat);
+  Expect.throws(() { UriData.parse("data:noseparator");}, badFormat);
+  Expect.throws(() { UriData.parse("data:noslash,text");}, badFormat);
+  Expect.throws(() { UriData.parse("data:type/sub;noequals,text");},
+                badFormat);
+  Expect.throws(() { UriData.parse("data:type/sub;knocomma=");},
+                badFormat);
+  Expect.throws(() { UriData.parse("data:type/sub;k=v;nocomma");},
+                badFormat);
+  Expect.throws(() { UriData.parse("data:type/sub;k=nocomma");},
+                badFormat);
+  Expect.throws(() { UriData.parse("data:type/sub;k=v;base64");},
+                badFormat);
+
+  // Invalid base64 format (only detected when decodeing).
+  for (var a = 0; a <= 4; a++) {
+    for (var p = 0; p <= 4; p++) {
+      // Base-64 encoding must have length divisible by four and no more
+      // than two padding characters at the end.
+      if (p < 3 && (a + p) % 4 == 0) continue;
+      uri = UriData.parse("data:;base64," + "A" * a + "=" * p);
+      Expect.throws(uri.contentAsBytes, badFormat);
+    }
+  }
+  // Invalid base64 encoding: padding not at end.
+  uri = UriData.parse("data:;base64,AA=A");
+  Expect.throws(uri.contentAsBytes, badFormat);
+  uri = UriData.parse("data:;base64,A=AA");
+  Expect.throws(uri.contentAsBytes, badFormat);
+  uri = UriData.parse("data:;base64,=AAA");
+  Expect.throws(uri.contentAsBytes, badFormat);
+  uri = UriData.parse("data:;base64,A==A");
+  Expect.throws(uri.contentAsBytes, badFormat);
+  uri = UriData.parse("data:;base64,==AA");
+  Expect.throws(uri.contentAsBytes, badFormat);
+  uri = UriData.parse("data:;base64,===A");
+  Expect.throws(uri.contentAsBytes, badFormat);
+}
+
+/// Checks that two [Uri]s are exactly the same.
+expectUriEquals(Uri expect, Uri actual) {
+  Expect.equals(expect.scheme, actual.scheme, "scheme");
+  Expect.equals(expect.hasAuthority, actual.hasAuthority, "hasAuthority");
+  Expect.equals(expect.userInfo, actual.userInfo, "userInfo");
+  Expect.equals(expect.host, actual.host, "host");
+  Expect.equals(expect.hasPort, actual.hasPort, "hasPort");
+  Expect.equals(expect.port, actual.port, "port");
+  Expect.equals(expect.port, actual.port, "port");
+  Expect.equals(expect.hasQuery, actual.hasQuery, "hasQuery");
+  Expect.equals(expect.query, actual.query, "query");
+  Expect.equals(expect.hasFragment, actual.hasFragment, "hasFragment");
+  Expect.equals(expect.fragment, actual.fragment, "fragment");
+}
diff --git a/tests/corelib/growable_list_test.dart b/tests/corelib/growable_list_test.dart
index b1d6e09..4b125bf 100644
--- a/tests/corelib/growable_list_test.dart
+++ b/tests/corelib/growable_list_test.dart
@@ -88,8 +88,10 @@
   }
   testFixedLength(new List<int>(0));
   testFixedLength(new List<int>(5));
+  testFixedLength(new List<int>.filled(5, null));  // default growable: false.
   testGrowable(new List<int>());
   testGrowable(new List<int>()..length = 5);
+  testGrowable(new List<int>.filled(5, null, growable: true));
   Expect.throws(() => new List<int>(-1), (e) => e is ArgumentError, "-1");
   // There must be limits. Fix this test if we ever allow 10^30 elements.
   Expect.throws(() => new List<int>(0x1000000000000000000000000000000),
diff --git a/tests/corelib/list_filled_type_argument_test.dart b/tests/corelib/list_filled_type_argument_test.dart
index 6d361cc..1c3aff4 100644
--- a/tests/corelib/list_filled_type_argument_test.dart
+++ b/tests/corelib/list_filled_type_argument_test.dart
@@ -8,4 +8,8 @@
   var a = new List<int>.filled(42, 42);
   Expect.isTrue(a is List<int>);
   Expect.isFalse(a is List<String>);
+
+  a = new List<int>.filled(42, 42, growable: true);
+  Expect.isTrue(a is List<int>);
+  Expect.isFalse(a is List<String>);
 }
diff --git a/tests/corelib/list_test.dart b/tests/corelib/list_test.dart
index c26c1cf..a72a189 100644
--- a/tests/corelib/list_test.dart
+++ b/tests/corelib/list_test.dart
@@ -33,6 +33,7 @@
   testGrowableList(new List());
   testGrowableList(new List().toList());
   testGrowableList(new List(0).toList());
+  testGrowableList(new List.filled(0, null, growable: true));
   testGrowableList([]);
   testGrowableList((const []).toList());
   testGrowableList(new MyList([]));
diff --git a/tests/html/history_test.dart b/tests/html/history_test.dart
index 893fb77..d801a72 100644
--- a/tests/html/history_test.dart
+++ b/tests/html/history_test.dart
@@ -34,6 +34,17 @@
       }, expectation);
     });
 
+    test('pushState with data', () {
+      expect(() {
+        window.history.pushState({'one' : 1}, document.title, '?dummy');
+        expect(window.history.state, equals({'one' : 1}));
+        window.history.pushState(null, document.title, '?foo=bar');
+
+        expect(window.location.href.endsWith('foo=bar'), isTrue);
+
+      }, expectation);
+    });
+
     test('back', () {
       expect(() {
         window.history.pushState(null, document.title, '?dummy1');
diff --git a/tests/html/html.status b/tests/html/html.status
index 56276ae..60180f9 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -34,7 +34,9 @@
 
 [ $compiler == dart2js && $checked ]
 js_function_getter_trust_types_test: Skip # --trust-type-annotations incompatible with --checked
-js_typed_interop_test: Pass, Fail # Issue 24822
+
+[ $compiler == dart2js && $checked && $browser ]
+js_typed_interop_test/method: Fail # Issue 24822
 
 [ $compiler == dart2js && $csp && $browser ]
 custom/js_custom_test: Fail # Issue 14643
@@ -371,6 +373,10 @@
 touchevent_test/supported: Fail
 websql_test/supported: Fail
 
+[ $compiler == dart2js && $runtime == ff && $system == windows ]
+mediasource_test/supported: Pass
+mediasource_test/functional: RuntimeError # Issue 24838
+
 # 'html' tests import the HTML library, so they only make sense in
 # a browser environment.
 [ $runtime == vm ]
diff --git a/tests/html/js_typed_interop_test.dart b/tests/html/js_typed_interop_test.dart
index 0e7cd0c..14d931f 100644
--- a/tests/html/js_typed_interop_test.dart
+++ b/tests/html/js_typed_interop_test.dart
@@ -86,6 +86,11 @@
       return this.str.charCodeAt(index);
     }
   };
+  function getCanvasContext() {
+    return document.createElement('canvas').getContext('2d');
+  }
+  window.windowProperty = 42;
+  document.documentProperty = 45;
 """);
 }
 
@@ -176,6 +181,15 @@
 @JS()
 external confuse(obj);
 
+@JS()
+external CanvasRenderingContext2D getCanvasContext();
+
+@JS('window.window.document.documentProperty')
+external num get propertyOnDocument;
+
+@JS('window.self.window.window.windowProperty')
+external num get propertyOnWindow;
+
 main() {
   _injectJs();
 
@@ -374,4 +388,13 @@
       expect(selection is List, isTrue);
     });
   });
+  group('html', () {
+    test('return html type', () {
+      expect(getCanvasContext() is CanvasRenderingContext2D, isTrue);
+    });
+    test('js path contains html types', () {
+      expect(propertyOnWindow, equals(42));
+      expect(propertyOnDocument, equals(45));
+    });
+  });
 }
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status
index 95b36d0..06e949a 100644
--- a/tests/isolate/isolate.status
+++ b/tests/isolate/isolate.status
@@ -18,7 +18,7 @@
 ping_pause_test: Skip     # Resolve test issues
 kill3_test: Pass, Fail    # Bad test: expects total message order
 
-message3_test/int32x4: Crash # Issue 21818
+message3_test/int32x4: Crash, Timeout # Issue 21818
 
 [ $compiler == none && $runtime == ContentShellOnAndroid ]
 *: Skip # Isolate tests are timing out flakily on Android content_shell.  Issue 19795
@@ -93,6 +93,9 @@
 [ $compiler == none && ($runtime == dartium || $runtime == ContentShellOnAndroid) ]
 spawn_uri_nested_vm_test: Skip # Issue 14479: This test is timing out.
 
+[ $compiler == none && $runtime == dartium && $arch == x64 ]
+isolate/spawn_uri_multi_test/01: Skip # Times out. Issue 24795
+
 [ $compiler == none && ( $runtime == dartium || $runtime == drt || $runtime == ContentShellOnAndroid) ]
 typed_message_test: Crash, Fail # Issue 13921, 14400
 message_enum_test: Fail, OK # Issue 13921 Dom isolates don't support spawnFunction
@@ -141,3 +144,25 @@
 [ $compiler == dart2js && $cps_ir ]
 deferred_in_isolate2_test: RuntimeError # A.loadLibrary is not a function
 isolate_current_test: RuntimeError # Please triage this failure.
+
+[ $noopt ]
+# Imports dart:mirrors
+count_test: CompileTimeError
+cross_isolate_message_test: CompileTimeError
+illegal_msg_function_test: CompileTimeError
+illegal_msg_mirror_test: CompileTimeError
+isolate_complex_messages_test: CompileTimeError
+mandel_isolate_test: CompileTimeError
+message2_test: CompileTimeError
+message_test: CompileTimeError
+mint_maker_test: CompileTimeError
+nested_spawn2_test: CompileTimeError
+nested_spawn_test: CompileTimeError
+raw_port_test: CompileTimeError
+request_reply_test: CompileTimeError
+spawn_function_custom_class_test: CompileTimeError
+spawn_function_test: CompileTimeError
+stacktrace_message_test: CompileTimeError
+stacktrace_message_test: CompileTimeError
+static_function_test: CompileTimeError
+unresolved_ports_test: CompileTimeError
diff --git a/tests/language/and_operation_on_non_integer_operand_test.dart b/tests/language/and_operation_on_non_integer_operand_test.dart
deleted file mode 100644
index 9d7b067..0000000
--- a/tests/language/and_operation_on_non_integer_operand_test.dart
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Regression test for dart2js that used to miscompile boolean add operations 
-// if one of the operands was an int and the other was not (issue 22427).
-
-import "package:expect/expect.dart";
-
-class NotAnInt {
-  NotAnInt operator&(b) => this;
-}
-
-@AssumeDynamic() @NoInline()
-id(x) => x;
-
-main () {
-  var a = id(new NotAnInt());
-  Expect.equals(a, a & 5 & 2);
-}
diff --git a/tests/language/await_null_aware_test.dart b/tests/language/await_null_aware_test.dart
new file mode 100644
index 0000000..483d9dd
--- /dev/null
+++ b/tests/language/await_null_aware_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for issue dartbug.com/24392
+
+import 'package:expect/expect.dart';
+import 'dart:async';
+
+Future<int> f() async {
+  // Unreachable.
+  Expect.isTrue(false);
+}
+
+main() async {
+  int x = 1;
+  x ??= await f();
+  Expect.equals(1, x);
+
+  int y = 1;
+  y = y ?? await f();
+  Expect.equals(1, y);
+}
diff --git a/tests/language/constant_string_interpolation2_test.dart b/tests/language/constant_string_interpolation2_test.dart
new file mode 100644
index 0000000..9853b0e
--- /dev/null
+++ b/tests/language/constant_string_interpolation2_test.dart
@@ -0,0 +1,97 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Regression test for issue #24839 - http://dartbug.com/24839
+
+const u1 = null;
+const int u2 = null;
+const List u3 = null;
+const u4 = const String.fromEnvironment("XXXXX");
+const u5 = const int.fromEnvironment("XXXXX");
+const u6 = const bool.fromEnvironment("XXXXX", defaultValue: null);
+const n1 = 42;
+const n2 = 3.1415;
+const int n3 = 37;
+const double n4 = 4.6692;
+const num n5 = b3 ? 1 : 2.71828;
+const n6 = const int.fromEnvironment("XXXXX", defaultValue: 87);
+const s1 = "s1";
+const String s2 = "s2";
+const String s3 = "$s1$s2";
+const s4 = const String.fromEnvironment("XXXXX", defaultValue: "s4");
+const b1 = true;
+const b2 = false;
+const b3 = b1 && (b2 || !b1);
+const b4 = const bool.fromEnvironment("XXXXX", defaultValue: true);
+
+// Individually
+const su1 = "$u1";
+const su2 = "$u2";
+const su3 = "$u3";
+const su4 = "$u4";
+const su5 = "$u5";
+const su6 = "$u6";
+const sn1 = "$n1";
+const sn2 = "$n2";
+const sn3 = "$n3";
+const sn4 = "$n4";
+const sn5 = "$n5";
+const sn6 = "$n6";
+const ss1 = "$s1";
+const ss2 = "$s2";
+const ss3 = "$s3";
+const ss4 = "$s4";
+const sb1 = "$b1";
+const sb2 = "$b2";
+const sb3 = "$b3";
+const sb4 = "$b4";
+
+// Constant variables in interpolation.
+const interpolation1 =
+  "$u1 $u2 $u3 $u4 $u5 $u6 $n1 $n2 $n3 $n4 $n5 $n6 $s1 $s2 $s3 $s4 $b1 $b2 $b3 $b4";
+// Constant expressions in interpolation.
+// (Single string, the linebreak to fit this into 80 chars is inside an
+// interpolation, which is allowed, even for single-line strings).
+const interpolation2 =
+    "${u1} ${u2} ${u3} ${u4} ${u5} ${u6} ${n1} ${n2} ${n3} ${n4} ${n5} ${n6} ${
+     s1} ${s2} ${s3} ${s4} ${b1} ${b2} ${b3} ${b4}";
+// Adjacent string literals are combined.
+const interpolation3 =
+  "$u1 $u2 $u3 $u4 $u5 " '$u6 $n1 $n2 $n3 $n4 '
+  """$n5 $n6 $s1 $s2 $s3 """ '''$s4 $b1 $b2 $b3 $b4''';
+// Nested interpolations.
+const interpolation4 =
+  "${"$u1 $u2 $u3 $u4 $u5 " '$u6 $n1 $n2 $n3 $n4'} ${
+     """$n5 $n6 $s1 $s2 $s3 """ '''$s4 $b1 $b2 $b3 $b4'''}";
+
+main() {
+  Expect.equals(u1.toString(), su1);
+  Expect.equals(u2.toString(), su2);
+  Expect.equals(u3.toString(), su3);
+  Expect.equals(u4.toString(), su4);
+  Expect.equals(u5.toString(), su5);
+  Expect.equals(u6.toString(), su6);
+  Expect.equals(n1.toString(), sn1);
+  Expect.equals(n2.toString(), sn2);
+  Expect.equals(n3.toString(), sn3);
+  Expect.equals(n4.toString(), sn4);
+  Expect.equals(n5.toString(), sn5);
+  Expect.equals(n6.toString(), sn6);
+  Expect.equals(s1.toString(), ss1);
+  Expect.equals(s2.toString(), ss2);
+  Expect.equals(s3.toString(), ss3);
+  Expect.equals(s4.toString(), ss4);
+  Expect.equals(b1.toString(), sb1);
+  Expect.equals(b2.toString(), sb2);
+  Expect.equals(b3.toString(), sb3);
+  Expect.equals(b4.toString(), sb4);
+  var expect = "null null null null null null 42 3.1415 37 4.6692 2.71828 87 "
+               "s1 s2 s1s2 s4 true false false true";
+  Expect.equals(expect, interpolation1);
+  Expect.equals(expect, interpolation2);
+  Expect.equals(expect, interpolation3);
+  Expect.equals(expect, interpolation4);
+}
diff --git a/tests/language/constructor_redirect2_test.dart b/tests/language/constructor_redirect2_test.dart
index e0ceb8d..b8d8db4 100644
--- a/tests/language/constructor_redirect2_test.dart
+++ b/tests/language/constructor_redirect2_test.dart
@@ -23,7 +23,7 @@
 main() {
   new A(3);
   new A.illegalBody(10);         /// 01: continued
-  new A.illegalInit(10);         /// 02: continued
+  new A.illegalInit();           /// 02: continued
   new A.illegalFormal(10);       /// 03: continued
-  new A.illegalSuper(10);        /// 04: continued
+  new A.illegalSuper();          /// 04: continued
 }
diff --git a/tests/language/enum_test.dart b/tests/language/enum_test.dart
index 84daba1..0e41965 100644
--- a/tests/language/enum_test.dart
+++ b/tests/language/enum_test.dart
@@ -11,6 +11,7 @@
 enum Enum3 { B, C }
 enum Enum4 { D, E, }
 enum Enum5 { F, G, H }
+enum _Enum6 { I, _J }
 
 main() {
   Expect.equals('Enum1._', Enum1._.toString());
@@ -21,6 +22,7 @@
   Expect.equals('Enum2.A', Enum2.A.toString());
   Expect.equals(0, Enum2.A.index);
   Expect.listEquals([Enum2.A], Enum2.values);
+  Expect.identical(const [Enum2.A], Enum2.values);
   Enum2.values.forEach(test2);
 
   Expect.equals('Enum3.B', Enum3.B.toString());
@@ -45,6 +47,9 @@
   Expect.equals(2, Enum5.H.index);
   Expect.listEquals([Enum5.F, Enum5.G, Enum5.H], Enum5.values);
   Enum5.values.forEach(test5);
+
+  Expect.equals('_Enum6.I', _Enum6.I.toString());
+  Expect.equals('_Enum6._J', _Enum6._J.toString());
 }
 
 test1(Enum1 e) {
diff --git a/tests/language/generic_instanceof4_test.dart b/tests/language/generic_instanceof4_test.dart
index 15896cb..95ff9bb 100644
--- a/tests/language/generic_instanceof4_test.dart
+++ b/tests/language/generic_instanceof4_test.dart
@@ -6,9 +6,8 @@
 import "package:expect/expect.dart";
 
 class A<T> {
+  @NoInline()
   foo(x) {
-    // Don't inline.
-    if (new DateTime.now().millisecondsSinceEpoch == 42) return foo(x);
     return x is T;
   }
 }
@@ -16,9 +15,8 @@
 class BB {}
 
 class B<T> implements BB {
+  @NoInline()
   foo() {
-    // Don't inline.
-    if (new DateTime.now().millisecondsSinceEpoch == 42) return foo();
     return new A<T>().foo(new B());
   }
 }
diff --git a/tests/language/language.status b/tests/language/language.status
index 28dedba..c2d3f88 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -101,3 +101,40 @@
 
 [ $compiler == none && ($runtime == vm || $runtime == drt || $runtime == dartium) && $arch == ia32 ]
 vm/regress_24517_test: Pass, Fail # Issue 24517.
+
+[ $noopt ]
+# Imports dart:mirrors
+const_evaluation_test: CompileTimeError
+deferred_constraints_constants_test: CompileTimeError
+enum_mirror_test: CompileTimeError
+field_increment_bailout_test: CompileTimeError
+instance_creation_in_function_annotation_test: CompileTimeError
+invocation_mirror2_test: CompileTimeError
+invocation_mirror_invoke_on2_test: CompileTimeError
+invocation_mirror_invoke_on_test: CompileTimeError
+issue21079_test: CompileTimeError
+many_overridden_no_such_method_test: CompileTimeError
+no_such_method_test: CompileTimeError
+null_test/none: CompileTimeError
+overridden_no_such_method_test: CompileTimeError
+regress_13462_0_test: CompileTimeError
+regress_13462_1_test: CompileTimeError
+regress_18535_test: CompileTimeError
+super_call4_test: CompileTimeError
+super_getter_setter_test: CompileTimeError
+vm/reflect_core_vm_test: CompileTimeError
+redirecting_factory_reflection_test: CompileTimeError
+
+# Deferred loading - Issue 24676
+deferred_load_constants_test: Skip
+deferred_constraints_constants_test: Skip
+deferred_global_test: Skip
+deferred_inheritance_constraints_test: Skip
+
+deopt_inlined_function_lazy_test: Pass, Crash # Incompatible flag: --deoptimize-alot
+tearoff_basic_test: RuntimeError, Crash # Conflicting flag.
+vm/type_cast_vm_test: RuntimeError # Line number mismatch.
+regress_23408_test: RuntimeError
+issue21159_test: Pass, Crash, Timeout # Issue 24659 - missing stack overflow check
+
+stack_trace_test: Fail  # Issue 24783 - inlined frames missing
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index a0c0638..13c5598 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -68,11 +68,6 @@
 if_null_assignment_behavior_test/13: Crash # Issue 23491
 if_null_assignment_behavior_test/14: Crash # Issue 23491
 
-if_null_assignment_behavior_test/29: Crash # Issue 23611
-prefix_assignment_test/01: Crash # Issue 23611
-prefix_assignment_test/02: Crash # Issue 23611
-prefix_identifier_reference_test/05: Crash # Issue 23611
-
 const_error_multiply_initialized_test/02: CompileTimeError # Issue 23618
 const_error_multiply_initialized_test/04: CompileTimeError # Issue 23618
 
@@ -175,8 +170,6 @@
 const_dynamic_type_literal_test/02: CompileTimeError # Issue 23009
 const_dynamic_type_literal_test/03: CompileTimeError # Issue 23009
 
-generic_field_mixin4_test: Crash # Issue 18651
-
 # Compilation errors.
 method_override5_test: RuntimeError # Issue 12809
 external_test/10: CompileTimeError # Issue 12887
@@ -227,6 +220,7 @@
 regress_22443_test: Pass,RuntimeError # Issue 17458
 
 [ $compiler == dart2js && $cps_ir == false ]
+generic_field_mixin4_test: Crash # Issue 18651
 generic_field_mixin5_test: Crash # Issue 18651
 many_method_calls_test: Crash # Stack overflow in HGraphVisitor.visitPostDominatorTree.visitBasicBlockAndSuccessors
 
@@ -272,7 +266,6 @@
 async_star_stream_take_test: Crash # (Stream makeStream(i...  cannot handle sync*/async* functions
 async_star_take_reyield_test: Crash # (fivePartialSums(Str...  cannot handle sync*/async* functions
 async_star_test: Crash # (f()async*{}): cannot handle sync*/async* functions
-async_this_bound_test: RuntimeError # Cannot read property 'set$f' of undefined
 asyncstar_concat_test: Crash # (concat(a,b)async*{yield* a;yield* b;}): cannot handle sync*/async* functions
 asyncstar_throw_in_catch_test: Crash # (foo4(Tracer tracer)...  cannot handle sync*/async* functions
 asyncstar_yield_test: Crash # (Stream<int> foo4()a...  cannot handle sync*/async* functions
@@ -280,10 +273,6 @@
 await_for_cancel_test: Crash # (await for(var x in controller.stream){for(int j=0;j<10;j++ ){if(j==5)continue outer;}}): await for
 await_for_test: Crash # (await for(var x in infiniteStream()){i++ ;if(i>10)break;t4.record(x);}): await for
 await_for_use_local_test: Crash # (await for(var v in s){accum+= v;}): await for
-await_future_test: RuntimeError # Cannot read property '_await_future_test$_box_0' of undefined
-await_postfix_expr_test: RuntimeError # Please triage this failure.
-await_regression_test: RuntimeError # "Obelix".then$1 is not a function
-await_test: RuntimeError # Cannot read property '$add' of undefined
 cha_deopt1_test: Crash # (d.make_u()): deferred access is not implemented
 cha_deopt2_test: Crash # (d.make_u()): deferred access is not implemented
 cha_deopt3_test: Crash # (d.make_u()): deferred access is not implemented
@@ -291,7 +280,6 @@
 closures_initializer_test: RuntimeError # Please triage this failure.
 constructor12_test: RuntimeError # Please triage this failure.
 crash_6725_test/01: Crash # unsupported operation on erroneous element
-cyclic_default_values_test: RuntimeError # Z.cyclic_default_values_test__foo$closure is not a function
 deferred_call_empty_before_load_test: Crash # (lib1.thefun()): deferred access is not implemented
 deferred_closurize_load_library_test: RuntimeError # D.loadLibrary is not a function
 deferred_constant_list_test: RuntimeError # K.loadLibrary is not a function
@@ -338,12 +326,10 @@
 deferred_type_dependency_test/type_annotation: Crash # (lib1.fooAnnotation("string")): deferred access is not implemented
 field3a_negative_test: Fail # Bogus result from type inference in case of invalid program.
 first_class_types_test: RuntimeError # Please triage this failure.
-for2_test: Crash # The null object does not have a getter 'field'.
-for_variable_capture_test: Crash # (i=0): For-loop variable captured in loop header
 generic2_test: RuntimeError # Please triage this failure.
-generic_field_mixin3_test: RuntimeError # Please triage this failure.
 generic_instanceof_test: RuntimeError # Please triage this failure.
 generic_native_test: RuntimeError # Please triage this failure.
+gc_test: Crash # Internal Error: Pending statics (see above).
 infinite_switch_label_test: Crash # (switch (target){l0:...  continue to a labeled switch case
 instanceof2_test: RuntimeError # Please triage this failure.
 instanceof4_test/01: RuntimeError # Please triage this failure.
@@ -360,11 +346,8 @@
 regress_22443_test: RuntimeError # M.loadLibrary is not a function
 regress_23408_test: RuntimeError # G.loadLibrary is not a function
 regress_23500_test/01: Crash # (await for(var c in new Stream.fromIterable([] )){}): await for
-super_bound_closure_test/01: RuntimeError # Cannot read property 'call' of undefined
-super_bound_closure_test/none: RuntimeError # Cannot read property 'call' of undefined
 super_call4_test: RuntimeError # Please triage this failure.
 super_getter_setter_test: Crash # Class 'PartialMethodElement' has no instance getter 'initializer'.
-super_implicit_closure_test: RuntimeError # Cannot read property 'call' of undefined
 super_operator_index5_test: Crash # (super[0]=42): visitUnresolvedSuperIndexSet
 super_operator_index7_test: Crash # (super[0]=42): visitUnresolvedSuperIndexSet
 super_operator_index8_test: Crash # (super[f()]=g()): visitUnresolvedSuperIndexSet
@@ -373,13 +356,6 @@
 switch_label2_test: Crash # (switch (target){cas...  continue to a labeled switch case
 switch_label_test: Crash # (switch (animal){cas...  continue to a labeled switch case
 switch_try_catch_test: Crash # (switch (0){_0:case ...  continue to a labeled switch case
-sync_generator1_test/01: RuntimeError # Expect.equals(expected: <(1, 2, 3, 5, [6])>, actual: <(1)>) fails.
-sync_generator1_test/none: RuntimeError # Expect.equals(expected: <(1, 2, 3, 5, [6])>, actual: <(1)>) fails.
-sync_generator3_test/test1: RuntimeError # Please triage this failure.
-sync_generator3_test/test2: RuntimeError # Please triage this failure.
-syncstar_yield_test/copyParameters: RuntimeError # Please triage this failure.
-syncstar_yield_test/none: RuntimeError # Please triage this failure.
-syncstar_yieldstar_test: RuntimeError # Please triage this failure.
 type_variable_closure2_test: RuntimeError # Please triage this failure.
 type_variable_field_initializer_closure_test: RuntimeError # Please triage this failure.
 type_variable_field_initializer_test: RuntimeError # Please triage this failure.
diff --git a/tests/language/nan_identical_test.dart b/tests/language/nan_identical_test.dart
index b4bba9a..a567f80 100644
--- a/tests/language/nan_identical_test.dart
+++ b/tests/language/nan_identical_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 // Test a new statement by itself.
-// VMOptions=--optimization-counter-threshold=4 --no-use-osr
+// VMOptions=--optimization-counter-threshold=4
 
 import 'dart:typed_data';
 
@@ -48,4 +48,4 @@
   }
 }
 
-checkIdentical(a, b) => identical(a, b);
\ No newline at end of file
+checkIdentical(a, b) => identical(a, b);
diff --git a/tests/language/null2_test.dart b/tests/language/null2_test.dart
index 16d3a83..000eed6 100644
--- a/tests/language/null2_test.dart
+++ b/tests/language/null2_test.dart
@@ -5,16 +5,9 @@
 
 import "package:expect/expect.dart";
 
-// Magic incantation to avoid the compiler recognizing the constant values
-// at compile time. If the result is computed at compile time, the dynamic code
-// will not be tested.
-confuse(x) {
-  try {
-    if (new DateTime.now().millisecondsSinceEpoch == 42) x = 42;
-    throw [x];
-  } on dynamic catch (e) { return e[0]; }
-  return 42;
-}
+@AssumeDynamic()
+@NoInline()
+confuse(x) => x;
 
 main() {
   Expect.equals("Null", null.runtimeType.toString());
diff --git a/tests/language/operations_on_non_num_operand_test.dart b/tests/language/operations_on_non_num_operand_test.dart
new file mode 100644
index 0000000..9f990ad
--- /dev/null
+++ b/tests/language/operations_on_non_num_operand_test.dart
@@ -0,0 +1,129 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Regression test for dart2js that used to miscompile boolean and operations 
+/// if one of the operands was an int and the other was not (issue 22427).
+///
+/// Extended to all operations as there is a risk of similar bugs with other
+/// operators, e.g. `a % 2` _looks_ like it might be 0 or 1.
+
+import "package:expect/expect.dart";
+
+@AssumeDynamic() @NoInline()
+confuse(x) => x;
+
+class Thing1 {
+  operator&(b) => this;
+  operator|(b) => this;
+  operator^(b) => this;
+  operator<<(b) => this;
+  operator>>(b) => this;
+
+  operator+(b) => this;
+  operator-(b) => this;
+  operator*(b) => this;
+  operator/(b) => this;
+  operator~/(b) => this;
+  operator%(b) => this;
+  remainder(b) => this;
+
+  operator<(b) => this;
+  operator<=(b) => this;
+  operator>(b) => this;
+  operator>=(b) => this;
+}
+
+class Thing2 {
+  @NoInline() operator&(b) => this;
+  @NoInline() operator|(b) => this;
+  @NoInline() operator^(b) => this;
+  @NoInline() operator<<(b) => this;
+  @NoInline() operator>>(b) => this;
+
+  @NoInline() operator+(b) => this;
+  @NoInline() operator-(b) => this;
+  @NoInline() operator*(b) => this;
+  @NoInline() operator/(b) => this;
+  @NoInline() operator~/(b) => this;
+  @NoInline() operator%(b) => this;
+  @NoInline() remainder(b) => this;
+
+  @NoInline() operator<(b) => this;
+  @NoInline() operator<=(b) => this;
+  @NoInline() operator>(b) => this;
+  @NoInline() operator>=(b) => this;
+}
+
+
+confused() {
+  var a = new Thing1();
+  Expect.equals(a, confuse(a) & 5 & 2);
+  Expect.equals(a, confuse(a) | 5 | 2);
+  Expect.equals(a, confuse(a) ^ 5 ^ 2);
+  Expect.equals(a, confuse(a) << 5 << 2);
+  Expect.equals(a, confuse(a) >> 5 >> 2);
+
+  Expect.equals(a, confuse(a) + 5 + 2);
+  Expect.equals(a, confuse(a) - 5 - 2);
+  Expect.equals(a, confuse(a) * 5 * 2);
+  Expect.equals(a, confuse(a) / 5 / 2);
+  Expect.equals(a, confuse(a) % 5 % 2);
+  Expect.equals(a, confuse(a) ~/ 5 ~/ 2);
+  Expect.equals(a, confuse(a).remainder(5).remainder(2));
+
+  Expect.equals(a, (confuse(a) < 5) < 2);
+  Expect.equals(a, (confuse(a) <= 5) <= 2);
+  Expect.equals(a, (confuse(a) > 5) > 2);
+  Expect.equals(a, (confuse(a) >= 5) >= 2);
+}
+
+direct1() {
+  var a = new Thing1();
+  Expect.equals(a, a & 5 & 2);
+  Expect.equals(a, a | 5 | 2);
+  Expect.equals(a, a ^ 5 ^ 2);
+  Expect.equals(a, a << 5 << 2);
+  Expect.equals(a, a >> 5 >> 2);
+
+  Expect.equals(a, a + 5 + 2);
+  Expect.equals(a, a - 5 - 2);
+  Expect.equals(a, a * 5 * 2);
+  Expect.equals(a, a / 5 / 2);
+  Expect.equals(a, a % 5 % 2);
+  Expect.equals(a, a ~/ 5 ~/ 2);
+  Expect.equals(a, a.remainder(5).remainder(2));
+
+  Expect.equals(a, (a < 5) < 2);
+  Expect.equals(a, (a <= 5) <= 2);
+  Expect.equals(a, (a > 5) > 2);
+  Expect.equals(a, (a >= 5) >= 2);
+}
+
+direct2() {
+  var a = new Thing2();
+  Expect.equals(a, a & 5 & 2);
+  Expect.equals(a, a | 5 | 2);
+  Expect.equals(a, a ^ 5 ^ 2);
+  Expect.equals(a, a << 5 << 2);
+  Expect.equals(a, a >> 5 >> 2);
+
+  Expect.equals(a, a + 5 + 2);
+  Expect.equals(a, a - 5 - 2);
+  Expect.equals(a, a * 5 * 2);
+  Expect.equals(a, a / 5 / 2);
+  Expect.equals(a, a % 5 % 2);
+  Expect.equals(a, a ~/ 5 ~/ 2);
+  Expect.equals(a, a.remainder(5).remainder(2));
+
+  Expect.equals(a, (a < 5) < 2);
+  Expect.equals(a, (a <= 5) <= 2);
+  Expect.equals(a, (a > 5) > 2);
+  Expect.equals(a, (a >= 5) >= 2);
+}
+
+main () {
+  confused();
+  direct1();
+  direct2();
+}
diff --git a/tests/language/pure_function2_test.dart b/tests/language/pure_function2_test.dart
index 1fdf5f0..c63d053 100644
--- a/tests/language/pure_function2_test.dart
+++ b/tests/language/pure_function2_test.dart
@@ -6,10 +6,9 @@
 
 // Regression test for issue 17483.
 
-confuse(x) {
-  if (new DateTime.now().millisecondsSinceEpoch == 42) return confuse(x);
-  return x;
-}
+
+@AssumeDynamic() @NoInline()
+confuse(x) => x;
 
 foo(trace) {
   trace.add("foo");
diff --git a/tests/language/super_bound_closure_test.dart b/tests/language/super_bound_closure_test.dart
index 1663c93..992d492 100644
--- a/tests/language/super_bound_closure_test.dart
+++ b/tests/language/super_bound_closure_test.dart
@@ -4,6 +4,10 @@
 
 import "package:expect/expect.dart";
 
+@AssumeDynamic()
+@NoInline()
+confuse(x) => x;
+
 class A {
   bar([var optional = 1]) => 498 + optional;
   bar2({ namedOptional: 2 }) => 40 + namedOptional;
@@ -93,11 +97,6 @@
   lastWhere(x, { orElse: 555 }) => -1;
 }
 
-confuse(x) {
-  if (new DateTime.now().millisecondsSinceEpoch == 42) return confuse(x - 1);
-  return x;
-}
-
 main() {
   var list = [new A(), new B(), [], "foo" ];
   var a = list[confuse(0)];
diff --git a/tests/language/vm/load_elimination_any_use_creates_alias_test.dart b/tests/language/vm/load_elimination_any_use_creates_alias_test.dart
index 1ad73c1..dd7341d 100644
--- a/tests/language/vm/load_elimination_any_use_creates_alias_test.dart
+++ b/tests/language/vm/load_elimination_any_use_creates_alias_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 // Test correctness of side effects tracking used by load to load forwarding.
 
-// VMOptions=--no-use-osr --optimization-counter-threshold=10 --enable-inlining-annotations
+// VMOptions=--no-use-osr --optimization-counter-threshold=10 --enable-inlining-annotations --no-background-compilation
 
 import "package:expect/expect.dart";
 
diff --git a/tests/language/vm/load_elimination_has_loads_from_place_test.dart b/tests/language/vm/load_elimination_has_loads_from_place_test.dart
index 24414eb..cc01ad7 100644
--- a/tests/language/vm/load_elimination_has_loads_from_place_test.dart
+++ b/tests/language/vm/load_elimination_has_loads_from_place_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 // Test correctness of side effects tracking used by load to load forwarding.
 
-// VMOptions=--optimization-counter-threshold=10 --no-use-osr --enable-inlining-annotations
+// VMOptions=--optimization-counter-threshold=10 --no-use-osr --enable-inlining-annotations --no-background-compilation
 
 // Tests correct handling of redefinitions in aliasing computation.
 
diff --git a/tests/language/vm/load_elimination_mark_stored_values_escaping_test.dart b/tests/language/vm/load_elimination_mark_stored_values_escaping_test.dart
index 3ea4271..1c079af 100644
--- a/tests/language/vm/load_elimination_mark_stored_values_escaping_test.dart
+++ b/tests/language/vm/load_elimination_mark_stored_values_escaping_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 // Test correctness of side effects tracking used by load to load forwarding.
 
-// VMOptions=--no-use-osr --optimization-counter-threshold=10 --enable-inlining-annotations
+// VMOptions=--no-use-osr --optimization-counter-threshold=10 --enable-inlining-annotations --no-background-compilation
 
 // Tests correct handling of redefinitions in aliasing computation.
 
diff --git a/tests/language/vm/load_elimination_two_redefinitions_test.dart b/tests/language/vm/load_elimination_two_redefinitions_test.dart
index 58a8f17..9e15ebc 100644
--- a/tests/language/vm/load_elimination_two_redefinitions_test.dart
+++ b/tests/language/vm/load_elimination_two_redefinitions_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 // Test correctness of side effects tracking used by load to load forwarding.
 
-// VMOptions=--optimization-counter-threshold=10 --no-use-osr --enable-inlining-annotations
+// VMOptions=--optimization-counter-threshold=10 --no-use-osr --enable-inlining-annotations --no-background-compilation
 
 // Tests correct handling of redefinitions in aliasing computation.
 
diff --git a/tests/language/vm/optimized_stacktrace_test.dart b/tests/language/vm/optimized_stacktrace_test.dart
index c5f98c9..3ad73f1 100644
--- a/tests/language/vm/optimized_stacktrace_test.dart
+++ b/tests/language/vm/optimized_stacktrace_test.dart
@@ -1,7 +1,7 @@
 // Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--stacktrace-every=3 --optimization-counter-threshold=10 --enable-inlining-annotations
+// VMOptions=--stacktrace-every=3 --optimization-counter-threshold=10 --enable-inlining-annotations --no-background-compilation
 
 // Test generating stacktraces with inlining and deferred code.
 // Regression test for issue dartbug.com/22331
diff --git a/tests/lib/async/dart2js_uncaught_error_test.dart b/tests/lib/async/dart2js_uncaught_error_test.dart
new file mode 100644
index 0000000..6c7f12d
--- /dev/null
+++ b/tests/lib/async/dart2js_uncaught_error_test.dart
@@ -0,0 +1,46 @@
+// 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.
+
+import "dart:async";
+import "dart:js";
+import "dart:collection" show Queue;
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+var errors = new Queue();
+int ctr = 0;
+
+main() {
+  print("STARTED");
+  asyncStart();
+
+  void errorHandler(self, message, url, line, [column, error]) {
+    print(">> $message / $ctr");
+    var expect = errors.removeFirst();
+    if (ctr == 2) {
+      asyncEnd();
+      print("DONE");
+    }
+    Expect.equals(expect[0].toString(), message);
+    Expect.equals(expect[1].toString(), error["stack"].toString());
+  }
+  context["onerror"] = new JsFunction.withThis(errorHandler);
+
+  void throwit() {
+    var err = ++ctr;
+    try {
+      throw err;
+    } catch (e, s) {
+      errors.add([e, s]);
+      rethrow;
+    }
+  }
+
+  () async {
+    () async {
+      throwit();
+    }();
+    throwit();
+  }();
+}
diff --git a/tests/lib/async/stream_periodic3_test.dart b/tests/lib/async/stream_periodic3_test.dart
index 437a8a6..b25ae27 100644
--- a/tests/lib/async/stream_periodic3_test.dart
+++ b/tests/lib/async/stream_periodic3_test.dart
@@ -21,7 +21,7 @@
                                         (x) => x);
     stream.take(10).listen((_) { }, onDone: expectAsync(() {
       int millis = watch.elapsedMilliseconds + safetyMargin;
-      expect(millis, greaterThan(10));
+      expect(millis, greaterThanOrEqualTo(10));
     }));
   });
 }
diff --git a/tests/lib/async/stream_periodic6_test.dart b/tests/lib/async/stream_periodic6_test.dart
new file mode 100644
index 0000000..1d4ffa3
--- /dev/null
+++ b/tests/lib/async/stream_periodic6_test.dart
@@ -0,0 +1,29 @@
+// 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.
+
+// Test merging streams.
+library dart.test.stream_from_iterable;
+
+import "dart:async";
+import 'package:unittest/unittest.dart';
+
+main() {
+  test("stream-periodic1", () {
+    Stream stream = new Stream.periodic(const Duration(milliseconds: 1),
+                                        (i) {
+                                          if (i == 3) throw 42;
+                                          return i;
+                                        });
+    int expected = 0;
+    var subscription;
+    subscription = stream.listen(expectAsync((data) {
+      expect(data, expected++);
+      if (expected == 5) subscription.cancel();
+    }, count: 4),
+    onError: expectAsync((e, s) {
+      expect(e, 42);
+      expected++;
+    }));
+  });
+}
diff --git a/tests/lib/developer/timeline_test.dart b/tests/lib/developer/timeline_test.dart
new file mode 100644
index 0000000..fab8e93
--- /dev/null
+++ b/tests/lib/developer/timeline_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:developer';
+import 'package:expect/expect.dart';
+
+void testUnbalancedStartFinish() {
+  Timeline.startSync('A');
+  Timeline.finishSync();
+
+  bool exceptionCaught = false;
+  try {
+    Timeline.finishSync();
+  } catch (e) {
+    exceptionCaught = true;
+  }
+  Expect.isTrue(exceptionCaught);
+}
+
+void main() {
+  testUnbalancedStartFinish();
+}
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 00412af..2c983c3 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -147,6 +147,7 @@
 async/stream_periodic3_test: RuntimeError # Timer interface not supported; Issue 7728.
 async/stream_periodic4_test: RuntimeError # Timer interface not supported; Issue 7728.
 async/stream_periodic5_test: RuntimeError # Timer interface not supported; Issue 7728.
+async/stream_periodic6_test: RuntimeError # Timer interface not supported; Issue 7728.
 async/run_zoned7_test: RuntimeError # Timer interface not supported: Issue 7728.
 async/catch_errors22_test: RuntimeError # Timer interface not supported: Issue 7728.
 async/timer_isActive_test: RuntimeError # Timer interface not supported: Issue 7728.
@@ -319,6 +320,7 @@
 
 [ $compiler == dart2js ]
 developer/metrics_num_test: Skip # Because of a int / double type test.
+developer/timeline_test: Skip # Not supported
 
 [ $arch == simarm64 ]
 convert/utf85_test: Skip # Pass, Slow Issue 20111.
@@ -329,6 +331,9 @@
 [ $runtime == vm && $mode == debug && $arch == x64 && $system == windows ]
 convert/streamed_conversion_json_utf8_decode_test: Pass, Slow
 
+[ $runtime == vm && $mode == release && $arch == ia32 && $system == windows ]
+convert/json_test: RuntimeError # Issue 24908
+
 [ $mode == debug && $arch != ia32 && $arch != x64 && $arch != simarm && $arch != simarmv5te ]
 convert/streamed_conversion_json_utf8_decode_test: Skip  # Verification not yet implemented.
 
@@ -338,10 +343,7 @@
 
 [ $compiler == dart2js && $cps_ir ]
 async/async_await_zones_test: Crash # (await for(var x in bar().take(100)){sum+= x;}): await for
-async/stream_empty_test: RuntimeError # $async$temp1.runTest_unreachable is not a function
 async/stream_iterator_test: Crash # (Stream createCancel...  cannot handle sync*/async* functions
-convert/json_pretty_test: RuntimeError # Please triage this failure.
-convert/line_splitter_test: RuntimeError # Please triage this failure.
 mirrors/deferred_mirrors_metadata_test: RuntimeError # U.loadLibrary is not a function
 mirrors/deferred_mirrors_metatarget_test: RuntimeError # X.loadLibrary is not a function
 mirrors/deferred_mirrors_update_test: RuntimeError # U.loadLibrary is not a function
@@ -356,3 +358,11 @@
 mirrors/mirrors_used_typedef_declaration_test/01: Crash # Assertion failure: typedef(Foo) has not been checked for cycles.
 mirrors/mirrors_used_typedef_declaration_test/none: Crash # Assertion failure: typedef(Foo) has not been checked for cycles.
 mirrors/typedef_library_test: Crash # Assertion failure: typedef(G) has not been checked for cycles.
+
+[ $compiler != dart2js ]
+async/dart2js_uncaught_error_test: Skip  # JS-integration only test
+
+[ $noopt ]
+mirrors/*: SkipByDesign
+convert/chunked_conversion_utf88_test: Pass, Timeout
+convert/utf85_test: Pass, Timeout
diff --git a/tests/lib/math/random_secure_test.dart b/tests/lib/math/random_secure_test.dart
new file mode 100644
index 0000000..33a563e
--- /dev/null
+++ b/tests/lib/math/random_secure_test.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that the secure random generator does not systematically generates
+// duplicates. Note that this test is flaky by definition, since duplicates
+// can occur. They should be extremely rare, though.
+
+// Library tag to allow Dartium to run the test.
+library random_secure;
+
+import "package:expect/expect.dart";
+import 'dart:math';
+
+main() {
+  var results;
+  var rng0;
+  var rng1;
+  var checkInt = (max) {
+    var intVal0 = rng0.nextInt(max);
+    var intVal1 = rng1.nextInt(max);
+    if (max > (1 << 28)) {
+      Expect.isFalse(results.contains(intVal0));
+      results.add(intVal0);
+      Expect.isFalse(results.contains(intVal1));
+      results.add(intVal1);
+    }
+  };
+  results = [];
+  rng0 = new Random.secure();
+  for(var i = 0; i <= 32; i++) {
+    rng1 = new Random.secure();
+    checkInt(pow(2, 32));
+    checkInt(pow(2, 32 - i));
+    checkInt(1000000000);
+  }
+  var checkDouble = () {
+    var doubleVal0 = rng0.nextDouble();
+    var doubleVal1 = rng1.nextDouble();
+    Expect.isFalse(results.contains(doubleVal0));
+    results.add(doubleVal0);
+    Expect.isFalse(results.contains(doubleVal1));
+    results.add(doubleVal1);
+  };
+  results = [];
+  rng0 = new Random.secure();
+  for(var i = 0; i < 32; i++) {
+    rng1 = new Random.secure();
+    checkDouble();
+  }
+  var cnt0 = 0;
+  var cnt1 = 0;
+  rng0 = new Random.secure();
+  for(var i = 0; i < 32; i++) {
+    rng1 = new Random.secure();
+    cnt0 += rng0.nextBool() ? 1 : 0;
+    cnt1 += rng1.nextBool() ? 1 : 0;
+  }
+  Expect.isTrue((cnt0 > 0) && (cnt0 < 32));
+  Expect.isTrue((cnt1 > 0) && (cnt1 < 32));
+}
+
diff --git a/tests/standalone/io/web_socket_compression_test.dart b/tests/standalone/io/web_socket_compression_test.dart
new file mode 100644
index 0000000..b1fd13f
--- /dev/null
+++ b/tests/standalone/io/web_socket_compression_test.dart
@@ -0,0 +1,250 @@
+// 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.
+//
+// VMOptions=
+// VMOptions=--short_socket_read
+// VMOptions=--short_socket_write
+// VMOptions=--short_socket_read --short_socket_write
+
+import "dart:async";
+import "dart:convert";
+import "dart:io";
+import "dart:typed_data";
+import "dart:math";
+
+import "package:async_helper/async_helper.dart";
+import "package:crypto/crypto.dart";
+import "package:expect/expect.dart";
+import "package:path/path.dart";
+
+const WEB_SOCKET_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
+
+const String HOST_NAME = 'localhost';
+
+String localFile(path) => Platform.script.resolve(path).toFilePath();
+
+SecurityContext serverContext = new SecurityContext()
+  ..useCertificateChain(localFile('certificates/server_chain.pem'))
+  ..usePrivateKey(localFile('certificates/server_key.pem'),
+                  password: 'dartdart');
+
+class SecurityConfiguration {
+  final bool secure;
+
+  SecurityConfiguration({bool this.secure});
+
+  Future<HttpServer> createServer({int backlog: 0}) =>
+      secure ? HttpServer.bindSecure(HOST_NAME,
+          0,
+          serverContext,
+          backlog: backlog)
+          : HttpServer.bind(HOST_NAME,
+          0,
+          backlog: backlog);
+
+  Future<WebSocket> createClient(int port) =>
+      // TODO(whesse): Add client context argument to WebSocket.connect
+      WebSocket.connect('${secure ? "wss" : "ws"}://$HOST_NAME:$port/');
+
+  Future<HttpClientResponse> createWebsocket(String url, String headerValue) {
+    HttpClient _httpClient = new HttpClient();
+    Uri uri = Uri.parse(url);
+
+    Random random = new Random();
+    // Generate 16 random bytes.
+    Uint8List nonceData = new Uint8List(16);
+    for (int i = 0; i < 16; i++) {
+      nonceData[i] = random.nextInt(256);
+    }
+    String nonce = CryptoUtils.bytesToBase64(nonceData);
+
+    uri = new Uri(
+        scheme: uri.scheme == "wss" ? "https" : "http",
+        userInfo: uri.userInfo,
+        host: uri.host,
+        port: uri.port,
+        path: uri.path,
+        query: uri.query,
+        fragment: uri.fragment);
+    return _httpClient.openUrl("GET", uri).then((request) {
+      if (uri.userInfo != null && !uri.userInfo.isEmpty) {
+        // If the URL contains user information use that for basic
+        // authorization.
+        String auth = CryptoUtils.bytesToBase64(UTF8.encode(uri.userInfo));
+        request.headers.set(HttpHeaders.AUTHORIZATION, "Basic $auth");
+      }
+      // Setup the initial handshake.
+      request.headers
+        ..set(HttpHeaders.CONNECTION, "Upgrade")
+        ..set(HttpHeaders.UPGRADE, "websocket")
+        ..set("Sec-WebSocket-Key", nonce)
+        ..set("Cache-Control", "no-cache")
+        ..set("Sec-WebSocket-Version", "13")
+        ..set("Sec-WebSocket-Extensions", headerValue);
+
+      return request.close();
+    });
+  }
+
+  void testCompressionSupport({server: false,
+        client: false,
+        contextTakeover: false}) {
+    asyncStart();
+
+    var clientOptions = new CompressionOptions(
+        enabled: client,
+        serverNoContextTakeover: contextTakeover,
+        clientNoContextTakeover: contextTakeover);
+    var serverOptions = new CompressionOptions(
+        enabled: server,
+        serverNoContextTakeover: contextTakeover,
+        clientNoContextTakeover: contextTakeover);
+
+    createServer().then((server) {
+      server.listen((request) {
+        Expect.isTrue(WebSocketTransformer.isUpgradeRequest(request));
+        WebSocketTransformer.upgrade(request, compression: serverOptions)
+                            .then((webSocket) {
+            webSocket.listen((message) {
+              Expect.equals("Hello World", message);
+
+              webSocket.add(message);
+              webSocket.close();
+            });
+            webSocket.add("Hello World");
+        });
+      });
+
+      var url = '${secure ? "wss" : "ws"}://$HOST_NAME:${server.port}/';
+      WebSocket.connect(url, compression: clientOptions).then((websocket) {
+        var future = websocket.listen((message) {
+          Expect.equals("Hello World", message);
+        }).asFuture();
+        websocket.add("Hello World");
+        return future;
+      }).then((_) {
+        server.close();
+        asyncEnd();
+      });
+    });
+  }
+
+  void testCompressionHeaders() {
+    asyncStart();
+    createServer().then((server) {
+      server.listen((request) {
+        Expect.equals('Upgrade', request.headers.value(HttpHeaders.CONNECTION));
+        Expect.equals('websocket', request.headers.value(HttpHeaders.UPGRADE));
+
+        var key = request.headers.value('Sec-WebSocket-Key');
+        var sha1 = new SHA1()..add("$key$WEB_SOCKET_GUID".codeUnits);
+        var accept = CryptoUtils.bytesToBase64(sha1.close());
+        request.response
+            ..statusCode = HttpStatus.SWITCHING_PROTOCOLS
+            ..headers.add(HttpHeaders.CONNECTION, "Upgrade")
+            ..headers.add(HttpHeaders.UPGRADE, "websocket")
+            ..headers.add("Sec-WebSocket-Accept", accept)
+            ..headers.add("Sec-WebSocket-Extensions",
+              "permessage-deflate;"
+              // Test quoted values and space padded =
+              'server_max_window_bits="10"; client_max_window_bits = 12'
+              'client_no_context_takeover; server_no_context_takeover');
+        request.response.contentLength = 0;
+        request.response.detachSocket().then((socket) {
+          return new WebSocket.fromUpgradedSocket(socket, serverSide: true);
+        }).then((websocket) {
+          websocket.add("Hello");
+          websocket.close();
+          asyncEnd();
+        });
+      });
+
+      var url = '${secure ? "wss" : "ws"}://$HOST_NAME:${server.port}/';
+
+      WebSocket.connect(url).then((websocket) {
+        return websocket.listen((message) {
+          Expect.equals("Hello", message);
+          websocket.close();
+        }).asFuture();
+      }).then((_) => server.close());
+    });
+  }
+
+  void testReturnHeaders(String headerValue, String expected) {
+    asyncStart();
+    createServer().then((server) {
+      server.listen((request) {
+        // Stuff
+        Expect.isTrue(WebSocketTransformer.isUpgradeRequest(request));
+        WebSocketTransformer.upgrade(request).then((webSocket) {
+            webSocket.listen((message) {
+              Expect.equals("Hello World", message);
+
+              webSocket.add(message);
+              webSocket.close();
+            });
+        });
+      });
+
+      var url = '${secure ? "wss" : "ws"}://$HOST_NAME:${server.port}/';
+      createWebsocket(url, headerValue)
+        .then((HttpClientResponse response) {
+          Expect.equals(response.statusCode, HttpStatus.SWITCHING_PROTOCOLS);
+          print(response.headers.value('Sec-WebSocket-Extensions'));
+          Expect.equals(response.headers.value("Sec-WebSocket-Extensions"),
+            expected);
+
+          String accept = response.headers.value("Sec-WebSocket-Accept");
+          Expect.isNotNull(accept);
+
+          var protocol = response.headers.value('Sec-WebSocket-Protocol');
+          return response.detachSocket().then((socket) =>
+              new WebSocket.fromUpgradedSocket(
+                  socket, protocol: protocol, serverSide: false));
+        }).then((websocket) {
+          var future = websocket.listen((message) {
+            Expect.equals("Hello", message);
+            websocket.close();
+          }).asFuture();
+          websocket.add("Hello World");
+          return future;
+        }).then((_) {
+          server.close();
+          asyncEnd();
+        });
+    }); // End createServer
+  }
+
+  void runTests() {
+    // No compression or takeover
+    testCompressionSupport();
+    // compression no takeover
+    testCompressionSupport(server: true, client: true);
+    // compression and context takeover.
+    testCompressionSupport(server: true, client: true, contextTakeover: true);
+    // Compression on client but not server. No take over
+    testCompressionSupport(client: true);
+    // Compression on server but not client.
+    testCompressionSupport(server: true);
+
+    testCompressionHeaders();
+    // Chrome headers
+    testReturnHeaders('permessage-deflate; client_max_window_bits',
+                      "permessage-deflate; client_max_window_bits=15");
+    // Firefox headers
+    testReturnHeaders('permessage-deflate',
+                      "permessage-deflate; client_max_window_bits=15");
+    // Ensure max_window_bits resize appropriately.
+    testReturnHeaders('permessage-deflate; server_max_window_bits=10',
+                      "permessage-deflate;" 
+                      " server_max_window_bits=10;"
+                      " client_max_window_bits=10");
+  }
+}
+
+main() {
+  new SecurityConfiguration(secure: false).runTests();
+  // TODO(whesse): Make WebSocket.connect() take an optional context: parameter.
+  // new SecurityConfiguration(secure: true).runTests();
+}
diff --git a/tests/standalone/io/web_socket_typed_data_test.dart b/tests/standalone/io/web_socket_typed_data_test.dart
index d65bedc..571b57d 100644
--- a/tests/standalone/io/web_socket_typed_data_test.dart
+++ b/tests/standalone/io/web_socket_typed_data_test.dart
@@ -15,13 +15,17 @@
 
 Future<HttpServer> createServer() => HttpServer.bind("127.0.0.1", 0);
 
-Future<WebSocket> createClient(int port) =>
-  WebSocket.connect('ws://127.0.0.1:$port/');
+Future<WebSocket> createClient(int port, bool compression) =>
+  compression ? WebSocket.connect('ws://127.0.0.1:$port/')
+    : WebSocket.connect('ws://127.0.0.1:$port/',
+        compression: CompressionOptions.OFF);
 
-void test(expected, testData) {
+void test(expected, testData, compression) {
   createServer().then((server) {
     var messageCount = 0;
-    server.transform(new WebSocketTransformer()).listen((webSocket) {
+    var transformer = compression ? new WebSocketTransformer()
+        : new WebSocketTransformer(compression: CompressionOptions.OFF);
+    server.transform(transformer).listen((webSocket) {
       webSocket.listen(
           (message) {
             Expect.listEquals(expected, message);
@@ -31,7 +35,7 @@
           onDone: () => Expect.equals(testData.length, messageCount));
     });
 
-    createClient(server.port).then((webSocket) {
+    createClient(server.port, compression).then((webSocket) {
       var messageCount = 0;
       webSocket.listen(
           (message) {
@@ -45,7 +49,7 @@
   });
 }
 
-testUintLists() {
+testUintLists({bool compression: false}) {
   var fillData = new List.generate(256, (index) => index);
   var testData = [
     new Uint8List(256),
@@ -55,10 +59,10 @@
     new Uint64List(256),
   ];
   testData.forEach((list) => list.setAll(0, fillData));
-  test(fillData, testData);
+  test(fillData, testData, compression);
 }
 
-testIntLists() {
+testIntLists({bool compression: false}) {
   var fillData = new List.generate(128, (index) => index);
   var testData = [
     new Int8List(128),
@@ -67,18 +71,20 @@
     new Int64List(128),
   ];
   testData.forEach((list) => list.setAll(0, fillData));
-  test(fillData, testData);
+  test(fillData, testData, compression);
 }
 
-void testOutOfRangeClient() {
+void testOutOfRangeClient({bool compression: false}) {
   createServer().then((server) {
     var messageCount = 0;
-    server.transform(new WebSocketTransformer()).listen((webSocket) {
+    var transformer = compression ? new WebSocketTransformer()
+        : new WebSocketTransformer(compression: CompressionOptions.OFF);
+    server.transform(transformer).listen((webSocket) {
       webSocket.listen((message) => Expect.fail("No message expected"));
     });
 
     Future clientError(data) {
-      return createClient(server.port).then((webSocket) {
+      return createClient(server.port, compression).then((webSocket) {
         var messageCount = 0;
         webSocket.listen((message) => Expect.fail("No message expected"));
         webSocket.add(data);
@@ -129,7 +135,7 @@
   });
 }
 
-void testOutOfRangeServer() {
+void testOutOfRangeServer({bool compression: false}) {
   var futures = [];
   var testData = [];
   var data;
@@ -175,7 +181,9 @@
 
   createServer().then((server) {
     var messageCount = 0;
-    server.transform(new WebSocketTransformer()).listen((webSocket) {
+    var transformer = compression ? new WebSocketTransformer()
+        : new WebSocketTransformer(compression: CompressionOptions.OFF);
+    server.transform(transformer).listen((webSocket) {
       webSocket.listen((message) {
         messageCount++;
         webSocket.add(testData[message[0]]);
@@ -187,7 +195,7 @@
 
     Future x(int i) {
       var completer = new Completer();
-      createClient(server.port).then((webSocket) {
+      createClient(server.port, compression).then((webSocket) {
           webSocket.listen((message) => Expect.fail("No message expected"),
                            onDone: () => completer.complete(true),
                            onError: (e) => completer.completeError(e));
@@ -204,7 +212,11 @@
 
 main() {
   testUintLists();
+  testUintLists(compression: true);
   testIntLists();
+  testIntLists(compression: true);
   testOutOfRangeClient();
+  testOutOfRangeClient(compression: true);
   // testOutOfRangeServer();
+  // testOutOfRangeServer(compression: true);
 }
diff --git a/tests/standalone/precompilation_dart2js_test.dart b/tests/standalone/precompilation_dart2js_test.dart
new file mode 100644
index 0000000..c961a5e
--- /dev/null
+++ b/tests/standalone/precompilation_dart2js_test.dart
@@ -0,0 +1,108 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test generating and running a simple precompiled snapshot of this script.
+
+import 'dart:io';
+
+main(List args) {
+  if (args.length > 0 && args[0] == "--hello") {
+    print("Hello");
+    return;
+  }
+
+  var cc, cc_flags, shared, libname;
+  if (Platform.isLinux) {
+    cc = 'gcc';
+    shared = '-shared';
+    libname = 'libprecompiled.so';
+  } else if (Platform.isMacOS) {
+    cc = 'clang';
+    shared = '-dynamiclib';
+    libname = 'libprecompiled.dylib';
+  } else {
+    print("Test only supports Linux and Mac");
+    return;
+  }
+
+  if (Platform.version.contains("x64")) {
+    cc_flags = "-m64";
+  } else if (Platform.version.contains("simarm64")) {
+    cc_flags = "-m64";
+  } else if (Platform.version.contains("simarm")) {
+    cc_flags = "-m32";
+  } else if (Platform.version.contains("simmips")) {
+    cc_flags = "-m32";
+  } else if (Platform.version.contains("arm")) {
+    cc_flags = "";
+  } else if (Platform.version.contains("mips")) {
+    cc_flags = "-EL";
+  } else {
+    print("Architecture not supported: ${Platform.version}");
+    return;
+  }
+
+  var abs_package_root = new File(Platform.packageRoot).absolute.path;
+  var dart_executable =
+      Directory.current.path + Platform.pathSeparator + Platform.executable;
+  Directory tmp;
+  try {
+    tmp = Directory.current.createTempSync("temp_precompilation_test");
+    var exec = "${dart_executable}_no_snapshot";
+    var args = ["--package-root=$abs_package_root",
+                "--gen-precompiled-snapshot",
+                "${abs_package_root}compiler/src/dart2js.dart"];
+    print("$exec ${args.join(' ')}");
+    var result = Process.runSync(exec, args, workingDirectory: tmp.path);
+    if (result.exitCode != 0) {
+      print(result.stdout);
+      print(result.stderr);
+      throw "Snapshot generation failed.";
+    }
+
+    // Check if gcc is present, and skip test if it is not.
+    try {
+      result = Process.runSync(
+          cc,
+          ["--version"],
+          workingDirectory: tmp.path);
+      if (result.exitCode != 0) {
+        throw "$cc --version failed.";
+      }
+    } catch(e) {
+      print("Skipping test because $cc is not present: $e");
+      return;
+    }
+
+    result = Process.runSync(
+        cc,
+        [shared, cc_flags, "-o", libname, "precompiled.S"],
+        workingDirectory: tmp.path);
+    if (result.exitCode != 0) {
+      print(result.stdout);
+      print(result.stderr);
+      throw "Shared library creation failed!";
+    }
+
+    var ld_library_path = new String.fromEnvironment("LD_LIBRARY_PATH");
+    ld_library_path = "${ld_library_path}:${tmp.path}";
+    exec = "${dart_executable}";
+    args = ["--run-precompiled-snapshot", "ignored_script", "--version"];
+    print("LD_LIBRARY_PATH=$ld_library_path $exec ${args.join(' ')}");
+    result = Process.runSync(exec, args,
+       workingDirectory: tmp.path,
+       environment: {"LD_LIBRARY_PATH": ld_library_path});
+    if (result.exitCode != 0) {
+      print(result.stdout);
+      print(result.stderr);
+      throw "Precompiled binary failed.";
+    }
+    print(result.stdout);
+    if (!result.stdout.contains("Dart-to-JavaScript compiler")) {
+      throw "Precompiled binary output mismatch.";
+    }
+  } finally {
+    tmp?.deleteSync(recursive: true);
+  }
+}
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index 2831a9c..b136d43 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -62,6 +62,7 @@
 out_of_memory_test: Skip
 verbose_gc_to_bmu_test: Skip
 precompilation_test: Skip # Standalone only test.
+precompilation_dart2js_test: Skip # Standalone only test.
 noopt_test: Skip # Standalone only test.
 
 [ $compiler == dartanalyzer || $compiler == dart2analyzer ]
@@ -106,14 +107,20 @@
 unboxed_int_converter_test: Skip
 pair_location_remapping_test: Skip
 precompilation_test: Skip # Standalone only test.
+precompilation_dart2js_test: Skip # Standalone only test.
 noopt_test: Skip # Standalone only test.
 
 [ $runtime == vm && $arch == ia32]
 precompilation_test: Skip # Not expected to pass on ia32.
+precompilation_dart2js_test: Skip # Not expected to pass on ia32.
 noopt_test: Skip # Not expected to pass on ia32.
 
 [ $runtime == vm && $arch == arm]
 precompilation_test: Skip # Issue 24427
+precompilation_dart2js_test: Skip # Issue 24427
+
+[ $runtime == vm && $arch == mips]
+precompilation_dart2js_test: SkipSlow
 
 [ $compiler == dart2js && $jscl ]
 assert_test: RuntimeError, OK # Assumes unspecified fields on the AssertionError.
@@ -157,7 +164,7 @@
 javascript_int_overflow_literal_test/01: Fail # Issue 14651.
 javascript_int_overflow_test: Fail # Issue 14651.
 
-[ $compiler == none && $runtime == drt ]
+[ $compiler == none && $runtime == drt && $arch == x64 ]
 map_literal_oom_test: RuntimeError # Issue 24571
 
 [ $compiler == dartanalyzer || $compiler == dart2analyzer ]
@@ -209,5 +216,7 @@
 io/secure_socket_renegotiate_test: RuntimeError
 io/secure_socket_bad_data_test: RuntimeError  # An error in a secure connection just puts a READ_CLOSED on the stream, rather than signaling an error on the stream.
 
-[ $compiler == dart2js && $cps_ir ]
-priority_queue_stress_test: RuntimeError # Cannot read property 'length' of undefined
+[ $noopt ]
+map_literal_oom_test: Pass, Crash # Issue 24678
+javascript*: SkipByDesign # JS overflow flag unsupported
+io/web_socket_test: Pass, RuntimeError # Issue 24674
diff --git a/tests/try/poi/compiler_test_case.dart b/tests/try/poi/compiler_test_case.dart
index a1df70a..711e47e 100644
--- a/tests/try/poi/compiler_test_case.dart
+++ b/tests/try/poi/compiler_test_case.dart
@@ -78,7 +78,7 @@
   /// Returns a future for the mainApp after running the compiler.
   Future<LibraryElement> compile() {
     return loadMainApp().then((LibraryElement library) {
-      return compiler.runCompiler(scriptUri).then((_) => library);
+      return compiler.run(scriptUri).then((_) => library);
     });
   }
 
diff --git a/tests/try/poi/forget_element_test.dart b/tests/try/poi/forget_element_test.dart
index 22b61ce..095b52c 100644
--- a/tests/try/poi/forget_element_test.dart
+++ b/tests/try/poi/forget_element_test.dart
@@ -260,12 +260,12 @@
   }
 
   Iterable codegenSeenClassesIn(LibraryElement library) {
-    return compiler.codegenWorld.allInstantiatedClasses.where(
+    return compiler.enqueuer.codegen.processedClasses.where(
         (e) => e.library == library);
   }
 
   Iterable resolutionSeenClassesIn(LibraryElement library) {
-    return compiler.resolverWorld.allInstantiatedClasses.where(
+    return compiler.enqueuer.resolution.processedClasses.where(
         (e) => e.library == library);
   }
 }
diff --git a/tests/try/poi/serialize_test.dart b/tests/try/poi/serialize_test.dart
index 87f4d7b..b77327e 100644
--- a/tests/try/poi/serialize_test.dart
+++ b/tests/try/poi/serialize_test.dart
@@ -582,6 +582,10 @@
   {
     "name": "Uri",
     "kind": "class"
+  },
+  {
+    "name": "UriData",
+    "kind": "class"
   }
 ];
 
diff --git a/tests/utils/dummy_compiler_test.dart b/tests/utils/dummy_compiler_test.dart
index 43a79c5..608e099 100644
--- a/tests/utils/dummy_compiler_test.dart
+++ b/tests/utils/dummy_compiler_test.dart
@@ -15,7 +15,9 @@
 import '../compiler/dart2js/mock_libraries.dart';
 
 String libProvider(Uri uri) {
-  if (uri.path.endsWith("/core.dart")) {
+  if (uri.path.endsWith(".platform")) {
+    return DEFAULT_PLATFORM_CONFIG;
+  } if (uri.path.endsWith("/core.dart")) {
     return buildLibrarySource(DEFAULT_CORE_LIBRARY);
   } else if (uri.path.endsWith('core_patch.dart')) {
     return DEFAULT_PATCH_CORE_SOURCE;
diff --git a/tests/utils/utils.status b/tests/utils/utils.status
index 43fb007..5b2f041 100644
--- a/tests/utils/utils.status
+++ b/tests/utils/utils.status
@@ -32,3 +32,6 @@
 dummy_compiler_test: Crash # (switch (function.na...  continue to a labeled switch case
 recursive_import_test: Crash # (switch (function.na...  continue to a labeled switch case
 source_mirrors_test: Crash, Slow # (switch (function.na...  continue to a labeled switch case
+
+[ $noopt ]
+source_mirrors_test: SkipByDesign # Imports dart:mirrors
diff --git a/tools/VERSION b/tools/VERSION
index 8f8b388..86d48bc 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -25,7 +25,7 @@
 #
 CHANNEL dev
 MAJOR 1
-MINOR 13
+MINOR 14
 PATCH 0
-PRERELEASE 7
-PRERELEASE_PATCH 12
+PRERELEASE 0
+PRERELEASE_PATCH 0
diff --git a/tools/bots/android.py b/tools/bots/android.py
index 39cbb25..21b6978 100644
--- a/tools/bots/android.py
+++ b/tools/bots/android.py
@@ -52,7 +52,9 @@
     if os.path.exists('./out/lastHooksTargetOS.txt'):
       os.remove('./out/lastHooksTargetOS.txt')
     targets = ['runtime']
-    args = [sys.executable, './tools/build.py', '--mode=' + build_info.mode,
+    args = [sys.executable, './tools/build.py',
+            '--arch=' + build_info.arch,
+            '--mode=' + build_info.mode,
             '--os=android'] + targets
     print 'Building Android: %s' % (' '.join(args))
     bot.RunProcess(args)
diff --git a/tools/bots/bot.py b/tools/bots/bot.py
index ed20c5d..cfd9076 100644
--- a/tools/bots/bot.py
+++ b/tools/bots/bot.py
@@ -241,6 +241,7 @@
     cmd.extend(targets)
 
     print 'Running: %s' % (' '.join(map(lambda arg: '"%s"' % arg, cmd)))
+    sys.stdout.flush()
     RunProcess(cmd)
 
 
diff --git a/tools/bots/dart2js_dump_info.py b/tools/bots/dart2js_dump_info.py
index e213954..eb86385 100644
--- a/tools/bots/dart2js_dump_info.py
+++ b/tools/bots/dart2js_dump_info.py
@@ -43,6 +43,7 @@
     dump_compilations = os.path.join(temp_dir, 'dump')
     normal_compilation_command = [sys.executable,
                                   './tools/test.py',
+                                  '--arch=ia32',
                                   '--mode=%s' % build_info.mode,
                                   '-cdart2js',
                                   '-rnone',
diff --git a/tools/bots/pkg.py b/tools/bots/pkg.py
index b3e22a7..7dad673 100644
--- a/tools/bots/pkg.py
+++ b/tools/bots/pkg.py
@@ -44,7 +44,8 @@
     common_args.append('--builder-tag=%s' % build_info.builder_tag)
 
   # There are a number of big/integration tests in pkg, run with bigger timeout
-  common_args.append('--timeout=120')
+  timeout = 300 if build_info.mode == 'debug' else 120
+  common_args.append('--timeout=%s' % timeout)
   # We have some unreproducible vm crashes on these bots
   common_args.append('--copy-coredumps')
 
@@ -53,7 +54,7 @@
   if build_info.system == 'windows':
     common_args.append('-j1')
 
-  bot.RunTest('pkg ', build_info,
+  bot.RunTest('pkg', build_info,
               common_args + ['pkg', 'docs'],
               swallow_error=True)
 
diff --git a/tools/create_sdk.py b/tools/create_sdk.py
index f377798..5cf2b1a 100755
--- a/tools/create_sdk.py
+++ b/tools/create_sdk.py
@@ -39,6 +39,10 @@
 # ......dart_native_api.h
 # ......dart_tools_api.h
 # ....lib/
+# ......dart_client.platform
+# ......dart_server.platform
+# ......dart_shared.platform
+# ......dart2dart.platform
 # ......_internal/
 # ......async/
 # ......collection/
@@ -241,6 +245,13 @@
              ignore=ignore_patterns('*.svn', 'doc', '*.py', '*.gypi', '*.sh',
                                     '.gitignore'))
 
+  # Copy the platform descriptors.
+  for file_name in ["dart_client.platform",
+                    "dart_server.platform",
+                    "dart_shared.platform",
+                    "dart2dart.platform"]:
+    copyfile(join(HOME, 'sdk', 'lib', file_name), join(LIB, file_name));
+
   # Copy libraries.dart to lib/_internal/libraries.dart for backwards
   # compatibility.
   #
diff --git a/tools/dart2js/angular2_testing_deps/CURRENT_ANGULAR_DEPS b/tools/dart2js/angular2_testing_deps/CURRENT_ANGULAR_DEPS
index 2e2224a..586e643 100644
--- a/tools/dart2js/angular2_testing_deps/CURRENT_ANGULAR_DEPS
+++ b/tools/dart2js/angular2_testing_deps/CURRENT_ANGULAR_DEPS
@@ -1 +1 @@
-da6def3772e22665c381306fd5f8be30a60c2058
+64bd9639a14afd83bf3f03ffe82825be2c8e940c
diff --git a/tools/ddbg.dart b/tools/ddbg.dart
index 1d1199b..f14a017 100644
--- a/tools/ddbg.dart
+++ b/tools/ddbg.dart
@@ -774,7 +774,7 @@
         });
     } else {
       var matchNames = matches.map((handler) => handler.name);
-      print("Ambigous command '$command' : ${matchNames.toList()}");
+      print("Ambiguous command '$command' : ${matchNames.toList()}");
       cmdo.show();
     }
   }
diff --git a/tools/ddbg_service/lib/debugger.dart b/tools/ddbg_service/lib/debugger.dart
index d3b0f9c..0a04161 100644
--- a/tools/ddbg_service/lib/debugger.dart
+++ b/tools/ddbg_service/lib/debugger.dart
@@ -160,7 +160,7 @@
         });
     } else {
       var matchNames = matches.map((handler) => handler.name);
-      cmdo.print("Ambigous command '$command' : ${matchNames.toList()}");
+      cmdo.print("Ambiguous command '$command' : ${matchNames.toList()}");
       cmdo.show();
     }
   }
diff --git a/tools/deps/dartium.deps/DEPS b/tools/deps/dartium.deps/DEPS
index 3ec5f48..25978fa 100644
--- a/tools/deps/dartium.deps/DEPS
+++ b/tools/deps/dartium.deps/DEPS
@@ -13,8 +13,8 @@
   "dartium_chromium_branch": "master",
   "dartium_chromium_commit": "62a7524d4f71c9e0858d24b0aa1bbff3a2d09bff",
   "chromium_base_revision": "297060",
-  "dartium_webkit_branch": "/blink/branches/dart/2171_4",
-  "dartium_webkit_revision": "202698",
+  "dartium_webkit_branch": "/blink/branches/dart/dartium",
+  "dartium_webkit_revision": "202699",
 
   # We use mirrors of all github repos to guarantee reproducibility and
   # consistency between what users see and what the bots see.
@@ -36,7 +36,7 @@
   "collection_rev": "@1da9a07f32efa2ba0c391b289e2037391e31da0e",
   "crypto_rev" : "@2df57a1e26dd88e8d0614207d4b062c73209917d",
   "csslib_tag" : "@0.12.0",
-  "dart2js_info_rev" : "@c4ad464717e3a304fb0d44a6937c25ff2049b863",
+  "dart2js_info_rev" : "@0a221eaf16aec3879c45719de656680ccb80d8a1",
   "glob_rev": "@704cf75e4f26b417505c5c611bdaacd8808467dd",
   "html_tag" : "@0.12.1+1",
   "http_rev" : "@9b93e1542c753090c50b46ef1592d44bc858bfe7",
@@ -56,6 +56,7 @@
   "pool_rev": "@22e12aeb16ad0b626900dbe79e4a25391ddfb28c",
   "pub_rev": "@9d707158fedc86fc2b02f62cdfe804902b098d9d",
   "pub_semver_tag": "@1.2.0",
+  "quiver_tag": "@0.21.4",
   "shelf_rev": "@1e87b79b21ac5e6fa2f93576d6c06eaa65285ef4",
   "shelf_web_socket_rev": "@ff170cec2c0e4e5722cdf47c557be63b5035a602",
   "source_span_rev": "@42501132e43599a151ba6727d340e44442f86c05",
@@ -69,7 +70,7 @@
   "zlib_rev": "@c3d0a6190f2f8c924a05ab6cc97b8f975bddd33f",
   "web_components_rev": "@0e636b534d9b12c9e96f841e6679398e91a986ec",
 
-  "co19_rev": "@ead3698f33d2cd41e75b6ce5d4a1203767cedd50",
+  "co19_rev": "@3ed795ea02e022ef19c77cf1b6095b7c8f5584d0",
   "fake_async_rev": "@38614",
 })
 
@@ -156,6 +157,10 @@
       (Var("github_mirror") % "pub") + Var("pub_rev"),
   "src/dart/third_party/pkg/pub_semver":
       (Var("github_mirror") % "pub_semver") + Var("pub_semver_tag"),
+  "src/dart/third_party/pkg/quiver":
+      Var("chromium_git")
+      + "/external/github.com/google/quiver-dart.git"
+      + Var("quiver_tag"),
   "src/dart/third_party/pkg/shelf":
       (Var("github_mirror") % "shelf") + Var("shelf_rev"),
   "src/dart/third_party/pkg/shelf_web_socket":
diff --git a/tools/dom/docs/docs.json b/tools/dom/docs/docs.json
index cbe7eb3..5b936a6 100644
--- a/tools/dom/docs/docs.json
+++ b/tools/dom/docs/docs.json
@@ -140,7 +140,8 @@
         " * See also:",
         " *",
         " * * [CanvasGradient](https://developer.mozilla.org/en-US/docs/DOM/CanvasGradient) from MDN.",
-        " * * [CanvasGradient](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvasgradient) from whatwg.",
+        " * * [CanvasGradient](https://html.spec.whatwg.org/multipage/scripting.html#canvasgradient)",
+        " *   from WHATWG.",
         " * * [CanvasGradient](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvasgradient) from W3C.",
         " */"
       ],
@@ -184,7 +185,8 @@
         " *",
         " * See also:",
         " * * [CanvasPattern](https://developer.mozilla.org/en-US/docs/DOM/CanvasPattern) from MDN.",
-        " * * [CanvasPattern](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvaspattern) from whatwg.",
+        " * * [CanvasPattern](https://html.spec.whatwg.org/multipage/scripting.html#canvaspattern)",
+        " *   from WHATWG.",
         " * * [CanvasPattern](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvaspattern) from W3C.",
         " */"
       ]
@@ -212,9 +214,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Current default path]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#current-default-path)",
-          "   * from WHATWG.",
+          "   * * [Current default",
+          "   *   path](https://html.spec.whatwg.org/multipage/scripting.html#current-default-path)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "imageSmoothingEnabled": [
@@ -224,9 +226,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Image smoothing]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#image-smoothing)",
-          "   * from WHATWG.",
+          "   * * [Image",
+          "   *   smoothing](https://html.spec.whatwg.org/multipage/scripting.html#image-smoothing)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "webkitBackingStorePixelRatio": [
@@ -236,8 +238,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [High DPI Canvas tutorial]",
-          "   * (http://www.html5rocks.com/en/tutorials/canvas/hidpi/) from HTML5Rocks.",
+          "   * * [High DPI Canvas",
+          "   *   tutorial](http://www.html5rocks.com/en/tutorials/canvas/hidpi/)",
+          "   *   from HTML5Rocks.",
           "   */"
         ]
       }
@@ -629,13 +632,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "dragenterEvent": [
@@ -645,13 +648,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "dragEvent": [
@@ -664,13 +667,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "draggable": [
@@ -679,13 +682,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "dragleaveEvent": [
@@ -695,13 +698,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "dragoverEvent": [
@@ -711,13 +714,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "dragstartEvent": [
@@ -726,13 +729,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "dropEvent": [
@@ -742,13 +745,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "errorEvent": [
@@ -774,12 +777,11 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Element.getBoundingClientRect]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect)",
-          "   * from MDN.",
-          "   * * [The getBoundingClientRect() method]",
-          "   * (http://www.w3.org/TR/cssom-view/#the-getclientrects-and-getboundingclientrect-methods)",
-          "   * from W3C.",
+          "   * * [Element.getBoundingClientRect](https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect)",
+          "   *   from MDN.",
+          "   * * [The getBoundingClientRect()",
+          "   *   method](http://www.w3.org/TR/cssom-view/#the-getclientrects()-and-getboundingclientrect()-methods)",
+          "   *   from W3C.",
           "   */"
         ],
         "getClientRects": [
@@ -789,12 +791,11 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Element.getClientRects]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Element.getClientRects)",
-          "   * from MDN.",
-          "   * * [The getClientRects() method]",
-          "   * (http://www.w3.org/TR/cssom-view/#the-getclientrects-and-getboundingclientrect-methods)",
-          "   * from W3C.",
+          "   * * [Element.getClientRects](https://developer.mozilla.org/en-US/docs/Web/API/Element.getClientRects)",
+          "   *   from MDN.",
+          "   * * [The getClientRects()",
+          "   *   method](http://www.w3.org/TR/cssom-view/#the-getclientrects()-and-getboundingclientrect()-methods)",
+          "   *   from W3C.",
           "   */"
         ],
         "getDestinationInsertionPoints": [
@@ -804,9 +805,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Shadow DOM specification]",
-          "   * (https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html)",
-          "   * from W3C.",
+          "   * * [Shadow DOM",
+          "   *   specification](https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html)",
+          "   *   from W3C.",
           "   */"
         ],
         "getElementsByClassName": [
@@ -815,11 +816,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [getElementsByClassName]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/document.getElementsByClassName)",
-          "   * from MDN.",
-          "   * * [DOM specification]",
-          "   * (http://www.w3.org/TR/domcore/) from W3C.",
+          "   * * [getElementsByClassName](https://developer.mozilla.org/en-US/docs/Web/API/document.getElementsByClassName)",
+          "   *   from MDN.",
+          "   * * [DOM specification](http://www.w3.org/TR/domcore/) from W3C.",
           "   */"
         ],
         "hidden": [
@@ -828,9 +827,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Hidden attribute specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/editing.html#the-hidden-attribute)",
-          "   * from WHATWG.",
+          "   * * [Hidden attribute",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#the-hidden-attribute)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "inputEvent": [
@@ -847,8 +846,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Input method editor specification]",
-          "   * (http://www.w3.org/TR/ime-api/) from W3C.",
+          "   * * [Input method editor",
+          "   *   specification](http://www.w3.org/TR/ime-api/) from W3C.",
           "   */"
         ],
         "invalidEvent": [
@@ -990,13 +989,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "ondragend": [
@@ -1006,13 +1005,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "ondragenter": [
@@ -1022,13 +1021,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "ondragleave": [
@@ -1038,13 +1037,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "ondragover": [
@@ -1054,13 +1053,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "ondragstart": [
@@ -1070,13 +1069,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "ondrop": [
@@ -1086,13 +1085,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "onerror": [
@@ -1207,11 +1206,11 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Using custom pseudo elements]",
-          "   * (http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom-201/#toc-custom-pseduo)",
-          "   * from HTML5Rocks.",
-          "   * * [Custom pseudo-elements]",
-          "   * (http://www.w3.org/TR/shadow-dom/#custom-pseudo-elements) from W3C.",
+          "   * * [Using custom pseudo",
+          "   *   elements](http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom-201/#toc-custom-pseduo)",
+          "   *   from HTML5Rocks.",
+          "   * * [Custom pseudo-elements](http://www.w3.org/TR/shadow-dom/#custom-pseudo-elements)",
+          "   *   from W3C.",
           "   */"
         ],
         "querySelector": [
@@ -1246,8 +1245,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [scrollByLines]",
-          "   * (http://docs.webplatform.org/wiki/dom/methods/scrollByLines) from WebPlatform.org.",
+          "   * * [scrollByLines](http://docs.webplatform.org/wiki/dom/methods/scrollByLines)",
+          "   *   from WebPlatform.org.",
           "   */"
         ],
         "scrollByPages": [
@@ -1256,8 +1255,7 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [scrollByPages]",
-          "   * (http://docs.webplatform.org/wiki/dom/methods/scrollByPages) from WebPlatform.org.",
+          "   * * [scrollByPages](http://docs.webplatform.org/wiki/dom/methods/scrollByPages) from WebPlatform.org.",
           "   */"
         ],
         "scrollEvent": [
@@ -1355,9 +1353,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [The translate attribute]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#the-translate-attribute)",
-          "   * from WHATWG.",
+          "   * * [The translate",
+          "   *   attribute](https://html.spec.whatwg.org/multipage/dom.html#the-translate-attribute)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "webkitdropzone": [
@@ -1367,13 +1365,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "webkitfullscreenchangeEvent": [
@@ -1398,11 +1396,10 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [CSS regions and exclusions tutorial]",
-          "   * (http://www.html5rocks.com/en/tutorials/regions/adobe/) from HTML5Rocks.",
-          "   * * [Regions](http://html.adobe.com/webplatform/layout/regions/) from Adobe.",
-          "   * * [CSS regions specification]",
-          "   * (http://www.w3.org/TR/css3-regions/) from W3C.",
+          "   * * [CSS regions and exclusions",
+          "   *   tutorial](http://www.html5rocks.com/en/tutorials/regions/adobe/) from HTML5Rocks.",
+          "   * * [Regions](http://webplatform.adobe.com/regions/) from Adobe.",
+          "   * * [CSS regions specification](http://www.w3.org/TR/css3-regions/) from W3C.",
           "   */"
         ],
         "webkitRegionOverset": [
@@ -1416,11 +1413,10 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [CSS regions and exclusions tutorial]",
-          "   * (http://www.html5rocks.com/en/tutorials/regions/adobe/) from HTML5Rocks.",
-          "   * * [Regions](http://html.adobe.com/webplatform/layout/regions/) from Adobe.",
-          "   * * [CSS regions specification]",
-          "   * (http://www.w3.org/TR/css3-regions/) from W3C.",
+          "   * * [CSS regions and exclusions",
+          "   *   tutorial](http://www.html5rocks.com/en/tutorials/regions/adobe/) from HTML5Rocks.",
+          "   * * [Regions](http://webplatform.adobe.com/regions/) from Adobe.",
+          "   * * [CSS regions specification](http://www.w3.org/TR/css3-regions/) from W3C.",
           "   */"
         ],
         "webkitRequestFullscreen": [
@@ -1429,11 +1425,10 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Using the fullscreen API]",
-          "   * (http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api)",
-          "   * tutorial from WebPlatform.org.",
-          "   * * [Fullscreen specification]",
-          "   * (http://www.w3.org/TR/fullscreen/) from W3C.",
+          "   * * [Using the fullscreen",
+          "   *   API](http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api)",
+          "   *   tutorial from WebPlatform.org.",
+          "   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.",
           "   */"
         ],
         "webkitRequestPointerLock": [
@@ -1442,12 +1437,11 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Pointer lock and first person shooter controls]",
-          "   * (http://www.html5rocks.com/en/tutorials/pointerlock/intro/) tutorial from",
-          "   * HTML5Rocks.",
-          "   *",
-          "   * * [Pointer lock specification]",
-          "   * (http://www.w3.org/TR/pointerlock/) from W3C.",
+          "   * * [Pointer lock and first person shooter",
+          "   *   controls](http://www.html5rocks.com/en/tutorials/pointerlock/intro/)",
+          "   *   tutorial from HTML5Rocks.",
+          "   * * [Pointer lock specification](http://www.w3.org/TR/pointerlock/)",
+          "   *   from W3C.",
           "   */"
         ]
       }
@@ -1460,8 +1454,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Target phase] (http://www.w3.org/TR/DOM-Level-3-Events/#target-phase)",
-          "   * from W3C.",
+          "   * * [Target phase](http://www.w3.org/TR/DOM-Level-3-Events/#target-phase)",
+          "   *   from W3C.",
           "   */"
         ],
         "BUBBLING_PHASE": [
@@ -1470,8 +1464,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Bubble phase] (http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)",
-          "   * from W3C.",
+          "   * * [Bubble phase](http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)",
+          "   *   from W3C.",
           "   */"
         ],
         "CAPTURING_PHASE": [
@@ -1481,8 +1475,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Bubble phase] (http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)",
-          "   * from W3C.",
+          "   * * [Bubble phase](http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)",
+          "   *   from W3C.",
           "   */"
         ],
         "clipboardData": [
@@ -1491,8 +1485,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [clipboardData specification]",
-          "   * (http://www.w3.org/TR/clipboard-apis/#attributes) from W3C.",
+          "   * * [clipboardData specification](http://www.w3.org/TR/clipboard-apis/#attributes)",
+          "   *   from W3C.",
           "   */"
         ],
         "path": [
@@ -1501,9 +1495,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Shadow DOM extensions to Event]",
-          "   * (http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event) from",
-          "   * W3C.",
+          "   * * [Shadow DOM extensions to",
+          "   *   Event](http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event)",
+          "   *   from W3C.",
           "   */"
         ]
       }
@@ -1694,7 +1688,7 @@
         " *",
         " * See also:",
         " *",
-        " * * [<area>](https://developer.mozilla.org/en-US/docs/HTML/Element/area)",
+        " * * [`<area>`](https://developer.mozilla.org/en-US/docs/HTML/Element/area)",
         " * on MDN.",
         " */"
       ]
@@ -1887,7 +1881,7 @@
         " *",
         " * See also:",
         " *",
-        " * * [HTML <div> element](http://www.w3.org/TR/html-markup/div.html) from W3C.",
+        " * * [HTML `<div>` element](http://www.w3.org/TR/html-markup/div.html) from W3C.",
         " * * [Block-level element](http://www.w3.org/TR/CSS2/visuren.html#block-boxes) from W3C.",
         " * * [Inline-level element](http://www.w3.org/TR/CSS2/visuren.html#inline-boxes) from W3C.",
         " */"
@@ -2457,9 +2451,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.childNodes]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.childNodes)",
-          "   * from MDN.",
+          "   * * [Node.childNodes](https://developer.mozilla.org/en-US/docs/Web/API/Node.childNodes)",
+          "   *   from MDN.",
           "   */"
         ],
         "cloneNode": [
@@ -2471,9 +2464,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.cloneNode]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.cloneNode) from",
-          "   * MDN.",
+          "   * * [Node.cloneNode](https://developer.mozilla.org/en-US/docs/Web/API/Node.cloneNode)",
+          "   *   from MDN.",
           "   */"
         ],
         "contains": [
@@ -2482,8 +2474,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.contains]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.contains) from MDN.",
+          "   * * [Node.contains](https://developer.mozilla.org/en-US/docs/Web/API/Node.contains)",
+          "   *   from MDN.",
           "   */"
         ],
         "firstChild": [
@@ -2492,9 +2484,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.firstChild]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.firstChild)",
-          "   * from MDN.",
+          "   * * [Node.firstChild](https://developer.mozilla.org/en-US/docs/Web/API/Node.firstChild)",
+          "   *   from MDN.",
           "   */"
         ],
         "hasChildNodes": [
@@ -2503,9 +2494,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.hasChildNodes]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.hasChildNodes) from",
-          "   * MDN.",
+          "   * * [Node.hasChildNodes](https://developer.mozilla.org/en-US/docs/Web/API/Node.hasChildNodes)",
+          "   *   from MDN.",
           "   */"
         ],
         "insertBefore": [
@@ -2514,9 +2504,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.insertBefore]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.insertBefore) from",
-          "   * MDN.",
+          "   * * [Node.insertBefore](https://developer.mozilla.org/en-US/docs/Web/API/Node.insertBefore)",
+          "   *   from MDN.",
           "   */"
         ],
         "lastChild": [
@@ -2525,9 +2514,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.lastChild]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.lastChild)",
-          "   * from MDN.",
+          "   * * [Node.lastChild](https://developer.mozilla.org/en-US/docs/Web/API/Node.lastChild)",
+          "   *   from MDN.",
           "   */"
         ],
         "nextSibling": [
@@ -2536,9 +2524,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.nextSibling]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nextSibling)",
-          "   * from MDN.",
+          "   * * [Node.nextSibling](https://developer.mozilla.org/en-US/docs/Web/API/Node.nextSibling)",
+          "   *   from MDN.",
           "   */"
         ],
         "nodeName": [
@@ -2549,10 +2536,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.nodeName]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeName)",
-          "   * from MDN. This page contains a table of [nodeName] values for each",
-          "   * [nodeType].",
+          "   * * [Node.nodeName](https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeName)",
+          "   *   from MDN. This page contains a table of [nodeName] values for each",
+          "   *   [nodeType].",
           "   */"
         ],
         "nodeType": [
@@ -2576,8 +2562,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.nodeType]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeType) from MDN.",
+          "   * * [Node.nodeType](https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeType)",
+          "   *   from MDN.",
           "   */"
         ],
         "nodeValue": [
@@ -2588,10 +2574,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.nodeValue]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeValue)",
-          "   * from MDN. This page contains a table of [nodeValue] values for each",
-          "   * [nodeType].",
+          "   * * [Node.nodeValue](https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeValue)",
+          "   *   from MDN. This page contains a table of [nodeValue] values for each",
+          "   *   [nodeType].",
           "   */"
         ],
         "ownerDocument": [
@@ -2602,9 +2587,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.ownerDocument]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.ownerDocument) from",
-          "   * MDN.",
+          "   * * [Node.ownerDocument](https://developer.mozilla.org/en-US/docs/Web/API/Node.ownerDocument)",
+          "   *   from MDN.",
           "   */"
         ],
         "parentElement": [
@@ -2616,9 +2600,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.parentElement]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.parentElement) from",
-          "   * W3C.",
+          "   * * [Node.parentElement](https://developer.mozilla.org/en-US/docs/Web/API/Node.parentElement)",
+          "   *   from W3C.",
           "   */"
         ],
         "parentNode": [
@@ -2627,9 +2610,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.parentNode]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.parentNode) from",
-          "   * MDN.",
+          "   * * [Node.parentNode](https://developer.mozilla.org/en-US/docs/Web/API/Node.parentNode)",
+          "   *   from MDN.",
           "   */"
         ],
         "previousSibling": [
@@ -2638,9 +2620,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.previousSibling]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.previousSibling)",
-          "   * from MDN.",
+          "   * * [Node.previousSibling](https://developer.mozilla.org/en-US/docs/Web/API/Node.previousSibling)",
+          "   *   from MDN.",
           "   */"
         ],
         "textContent": [
@@ -2649,9 +2630,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.textContent]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.textContent) from",
-          "   * MDN.",
+          "   * * [Node.textContent](https://developer.mozilla.org/en-US/docs/Web/API/Node.textContent)",
+          "   *   from MDN.",
           "   */"
         ]
       }
@@ -3287,9 +3267,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [User prompts]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#user-prompts)",
-          "   * from WHATWG.",
+          "   * * [User prompts](https://html.spec.whatwg.org/multipage/webappapis.html#user-prompts)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "applicationCache": [
@@ -3298,11 +3277,12 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [A beginner's guide to using the application cache]",
-          "   * (http://www.html5rocks.com/en/tutorials/appcache/beginner) from HTML5Rocks.",
-          "   * * [Application cache API]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/offline.html#application-cache-api)",
-          "   * from WHATWG.",
+          "   * * [A beginner's guide to using the application",
+          "   *   cache](http://www.html5rocks.com/en/tutorials/appcache/beginner)",
+          "   *   from HTML5Rocks.",
+          "   * * [Application cache",
+          "   *   API](https://html.spec.whatwg.org/multipage/browsers.html#application-cache-api)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "confirm": [
@@ -3311,9 +3291,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [User prompts]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#user-prompts)",
-          "   * from WHATWG.",
+          "   * * [User prompts](https://html.spec.whatwg.org/multipage/webappapis.html#user-prompts)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "crypto": [
@@ -3362,12 +3341,10 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [devicePixelRatio]",
-          "   * (http://www.quirksmode.org/blog/archives/2012/06/devicepixelrati.html) from",
-          "   * quirksmode.",
-          "   * * [More about devicePixelRatio]",
-          "   * (http://www.quirksmode.org/blog/archives/2012/07/more_about_devi.html) from",
-          "   * quirksmode.",
+          "   * * [devicePixelRatio](http://www.quirksmode.org/blog/archives/2012/06/devicepixelrati.html)",
+          "   *   from quirksmode.",
+          "   * * [More about devicePixelRatio](http://www.quirksmode.org/blog/archives/2012/07/more_about_devi.html)",
+          "   *   from quirksmode.",
           "   */"
         ],
         "DOMContentLoadedEvent": [
@@ -3384,8 +3361,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Window.find]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.find) from MDN.",
+          "   * * [Window.find](https://developer.mozilla.org/en-US/docs/Web/API/Window.find)",
+          "   *   from MDN.",
           "   */"
         ],
         "getMatchedCSSRules": [
@@ -3399,9 +3376,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Window.getSelection]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.getSelection)",
-          "   * from MDN.",
+          "   * * [Window.getSelection](https://developer.mozilla.org/en-US/docs/Web/API/Window.getSelection)",
+          "   *   from MDN.",
           "   */"
         ],
         "hashchangeEvent": [
@@ -3418,9 +3394,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Loading web pages]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html)",
-          "   * from WHATWG.",
+          "   * * [Loading web pages](https://html.spec.whatwg.org/multipage/browsers.html)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "innerHeight": [
@@ -3429,9 +3404,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [innerHeight]",
-          "   * (http://docs.webplatform.org/wiki/css/cssom/properties/innerHeight) from",
-          "   * WebPlatform.org.",
+          "   * * [innerHeight](http://docs.webplatform.org/wiki/css/cssom/properties/innerHeight)",
+          "   *   from WebPlatform.org.",
           "   */"
         ],
         "innerWidth": [
@@ -3440,9 +3414,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [innerWidth]",
-          "   * (http://docs.webplatform.org/wiki/css/cssom/properties/innerWidth) from",
-          "   * WebPlatform.org.",
+          "   * * [innerWidth](http://docs.webplatform.org/wiki/css/cssom/properties/innerWidth)",
+          "   *   from WebPlatform.org.",
           "   */"
         ],
         "localStorage": [
@@ -3451,13 +3424,12 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [DOM storage guide]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage) from",
-          "   * MDN.",
-          "   * * [The past, present & future of local storage for web applications]",
-          "   * (http://diveintohtml5.info/storage.html) from Dive Into HTML5.",
-          "   * * [Local storage specification]",
-          "   * (http://www.w3.org/TR/webstorage/#the-localstorage-attribute) from W3C.",
+          "   * * [DOM storage guide](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage)",
+          "   *   from MDN.",
+          "   * * [The past, present & future of local storage for web",
+          "   *   applications](http://diveintohtml5.info/storage.html) from Dive Into HTML5.",
+          "   * * [Local storage specification](http://www.w3.org/TR/webstorage/#the-localstorage-attribute)",
+          "   *   from W3C.",
           "   */"
         ],
         "locationbar": [
@@ -3466,9 +3438,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Browser interface elements]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)",
-          "   * from WHATWG.",
+          "   * * [Browser interface",
+          "   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "matchMedia": [
@@ -3477,11 +3449,11 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Testing media queries]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Testing_media_queries)",
-          "   * from MDN.",
-          "   * * [The MediaQueryList specification]",
-          "   * (http://www.w3.org/TR/cssom-view/#the-mediaquerylist-interface) from W3C.",
+          "   * * [Testing media",
+          "   *   queries](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Testing_media_queries)",
+          "   *   from MDN.",
+          "   * * [The MediaQueryList",
+          "   *   specification](http://www.w3.org/TR/cssom-view/#the-mediaquerylist-interface) from W3C.",
           "   */"
         ],
         "menubar": [
@@ -3490,9 +3462,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Browser interface elements]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)",
-          "   * from WHATWG.",
+          "   * * [Browser interface",
+          "   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "messageEvent": [
@@ -3511,10 +3483,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Window.moveBy]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.moveBy) from MDN.",
-          "   * * [Window.moveBy]",
-          "   * (http://dev.w3.org/csswg/cssom-view/#dom-window-moveby) from W3C.",
+          "   * * [Window.moveBy](https://developer.mozilla.org/en-US/docs/Web/API/Window.moveBy)",
+          "   *   from MDN.",
+          "   * * [Window.moveBy](http://dev.w3.org/csswg/cssom-view/#dom-window-moveby) from W3C.",
           "   */"
         ],
         "name": [
@@ -3523,9 +3494,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Window name]",
-          "   * (http://docs.webplatform.org/wiki/html/attributes/name_(window)) from",
-          "   * WebPlatform.org.",
+          "   * * [Window name](http://docs.webplatform.org/wiki/html/attributes/name_(window))",
+          "   *   from WebPlatform.org.",
           "   */"
         ],
         "navigator": [
@@ -3534,9 +3504,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [The navigator object]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#the-navigator-object)",
-          "   * from WHATWG.",
+          "   * * [The navigator",
+          "   *   object](https://html.spec.whatwg.org/multipage/webappapis.html#the-navigator-object)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "offlineEvent": [
@@ -3553,9 +3523,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [offscreenBuffering]",
-          "   * (http://docs.webplatform.org/wiki/dom/properties/offscreenBuffering) from",
-          "   * WebPlatform.org.",
+          "   * * [offscreenBuffering](http://docs.webplatform.org/wiki/dom/properties/offscreenBuffering)",
+          "   *   from WebPlatform.org.",
           "   */"
         ],
         "onabort": [
@@ -3740,9 +3709,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [outerHeight]",
-          "   * (http://docs.webplatform.org/wiki/css/cssom/properties/outerHeight) from",
-          "   * WebPlatform.org.",
+          "   * * [outerHeight](http://docs.webplatform.org/wiki/css/cssom/properties/outerHeight)",
+          "   *   from WebPlatform.org.",
           "   */"
         ],
         "outerWidth": [
@@ -3751,9 +3719,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [outerWidth]",
-          "   * (http://docs.webplatform.org/wiki/css/cssom/properties/outerWidth) from",
-          "   * WebPlatform.org.",
+          "   * * [outerWidth](http://docs.webplatform.org/wiki/css/cssom/properties/outerWidth)",
+          "   *   from WebPlatform.org.",
           "   */"
         ],
         "pagehideEvent": [
@@ -3780,10 +3747,11 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [The Screen interface specification]",
-          "   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.",
-          "   * * [scrollX and pageXOffset]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX) from MDN.",
+          "   * * [The Screen interface",
+          "   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.",
+          "   * * [scrollX and",
+          "   *   pageXOffset](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX)",
+          "   *   from MDN.",
           "   */"
         ],
         "pageYOffset": [
@@ -3794,10 +3762,11 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [The Screen interface specification]",
-          "   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.",
-          "   * * [scrollY and pageYOffset]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY) from MDN.",
+          "   * * [The Screen interface",
+          "   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.",
+          "   * * [scrollY and",
+          "   *   pageYOffset](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY)",
+          "   *   from MDN.",
           "   */"
         ],
         "performance": [
@@ -3806,11 +3775,11 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Measuring page load speed with navigation timeing]",
-          "   * (http://www.html5rocks.com/en/tutorials/webperformance/basics/) from",
-          "   * HTML5Rocks.",
-          "   * * [Navigation timing specification]",
-          "   * (http://www.w3.org/TR/navigation-timing/) from W3C.",
+          "   * * [Measuring page load speed with navigation",
+          "   *   timeing](http://www.html5rocks.com/en/tutorials/webperformance/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Navigation timing",
+          "   *   specification](http://www.w3.org/TR/navigation-timing/) from W3C.",
           "   */"
         ],
         "PERSISTENT": [
@@ -3820,10 +3789,11 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Exploring the FileSystem APIs]",
-          "   * (http://www.html5rocks.com/en/tutorials/file/filesystem/) from HTML5Rocks.",
-          "   * * [File API]",
-          "   * (http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem) from W3C.",
+          "   * * [Exploring the FileSystem",
+          "   *   APIs](http://www.html5rocks.com/en/tutorials/file/filesystem/)",
+          "   *   from HTML5Rocks.",
+          "   * * [File API](http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem)",
+          "   *   from W3C.",
           "   */"
         ],
         "popstateEvent": [
@@ -3840,8 +3810,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Window.print]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.print) from MDN.",
+          "   * * [Window.print](https://developer.mozilla.org/en-US/docs/Web/API/Window.print)",
+          "   *   from MDN.",
           "   */"
         ],
         "resizeBy": [
@@ -3850,8 +3820,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Window resizeBy] (http://docs.webplatform.org/wiki/dom/methods/resizeBy)",
-          "   * from WebPlatform.org.",
+          "   * * [Window resizeBy](http://docs.webplatform.org/wiki/dom/methods/resizeBy)",
+          "   *   from WebPlatform.org.",
           "   */"
         ],
         "resizeEvent": [
@@ -3868,8 +3838,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Window resizeTo] (http://docs.webplatform.org/wiki/dom/methods/resizeTo)",
-          "   * from WebPlatform.org.",
+          "   * * [Window resizeTo](http://docs.webplatform.org/wiki/dom/methods/resizeTo)",
+          "   *   from WebPlatform.org.",
           "   */"
         ],
         "screen": [
@@ -3878,8 +3848,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [The Screen interface specification]",
-          "   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.",
+          "   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)",
+          "   *   from W3C.",
           "   */"
         ],
         "screenLeft": [
@@ -3889,8 +3859,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [The Screen interface specification]",
-          "   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.",
+          "   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)",
+          "   *   from W3C.",
           "   */"
         ],
         "screenTop": [
@@ -3899,8 +3869,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [The Screen interface specification]",
-          "   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.",
+          "   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)",
+          "   *   from W3C.",
           "   */"
         ],
         "screenX": [
@@ -3909,8 +3879,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [The Screen interface specification]",
-          "   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.",
+          "   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)",
+          "   *   from W3C.",
           "   */"
         ],
         "screenY": [
@@ -3919,8 +3889,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [The Screen interface specification]",
-          "   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.",
+          "   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)",
+          "   *   from W3C.",
           "   */"
         ],
         "scroll": [
@@ -3931,8 +3901,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Window scroll] (http://docs.webplatform.org/wiki/dom/methods/scroll)",
-          "   * from WebPlatform.org.",
+          "   * * [Window scroll](http://docs.webplatform.org/wiki/dom/methods/scroll)",
+          "   *   from WebPlatform.org.",
           "   */"
         ],
         "scrollbars": [
@@ -3941,9 +3911,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Browser interface elements]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)",
-          "   * from WHATWG.",
+          "   * * [Browser interface",
+          "   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "scrollBy": [
@@ -3952,8 +3922,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Window scrollBy] (http://docs.webplatform.org/wiki/dom/methods/scrollBy)",
-          "   * from WebPlatform.org.",
+          "   * * [Window scrollBy](http://docs.webplatform.org/wiki/dom/methods/scrollBy)",
+          "   *   from WebPlatform.org.",
           "   */"
         ],
         "scrollTo": [
@@ -3964,8 +3934,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Window scrollTo] (http://docs.webplatform.org/wiki/dom/methods/scrollTo)",
-          "   * from WebPlatform.org.",
+          "   * * [Window scrollTo](http://docs.webplatform.org/wiki/dom/methods/scrollTo)",
+          "   *   from WebPlatform.org.",
           "   */"
         ],
         "self": [
@@ -3974,8 +3944,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Window.self]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.self) from MDN.",
+          "   * * [Window.self](https://developer.mozilla.org/en-US/docs/Web/API/Window.self)",
+          "   *   from MDN.",
           "   */"
         ],
         "sessionStorage": [
@@ -3984,13 +3954,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [DOM storage guide]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage) from",
-          "   * MDN.",
-          "   * * [The past, present & future of local storage for web applications]",
-          "   * (http://diveintohtml5.info/storage.html) from Dive Into HTML5.",
-          "   * * [Local storage specification]",
-          "   * (http://www.w3.org/TR/webstorage/#dom-sessionstorage) from W3C.",
+          "   * * [DOM storage",
+          "   *   guide](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage)",
+          "   *   from MDN.",
+          "   * * [The past, present & future of local storage for web",
+          "   *   applications](http://diveintohtml5.info/storage.html) from Dive Into HTML5.",
+          "   * * [Local storage",
+          "   *   specification](http://www.w3.org/TR/webstorage/#dom-sessionstorage) from W3C.",
           "   */"
         ],
         "showModalDialog": [
@@ -3999,9 +3969,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Dialogs implemented using separate documents]",
-          "   * (http://www.w3.org/html/wg/drafts/html/master/webappapis.html#dialogs-implemented-using-separate-documents)",
-          "   * from W3C.",
+          "   * * [Dialogs implemented using separate",
+          "   *   documents](http://www.w3.org/html/wg/drafts/html/master/webappapis.html#dialogs-implemented-using-separate-documents)",
+          "   *   from W3C.",
           "   */"
         ],
         "speechSynthesis": [
@@ -4010,9 +3980,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Web speech specification]",
-          "   * (https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section)",
-          "   * from W3C.",
+          "   * * [Web speech",
+          "   *   specification](https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section)",
+          "   *   from W3C.",
           "   */"
         ],
         "status": [
@@ -4024,9 +3994,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Browser interface elements]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)",
-          "   * from WHATWG.",
+          "   * * [Browser interface",
+          "   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "stop": [
@@ -4035,9 +4005,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [The Window object]",
-          "   * (http://www.w3.org/html/wg/drafts/html/master/browsers.html#the-window-object)",
-          "   * from W3C.",
+          "   * * [The Window",
+          "   *   object](http://www.w3.org/html/wg/drafts/html/master/browsers.html#the-window-object)",
+          "   *   from W3C.",
           "   */"
         ],
         "storageEvent": [
@@ -4054,9 +4024,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [StyleMedia class reference]",
-          "   * (https://developer.apple.com/library/safari/documentation/SafariDOMAdditions/Reference/StyleMedia/StyleMedia/StyleMedia.html)",
-          "   * from Safari Developer Library.",
+          "   * * [StyleMedia class",
+          "   *   reference](https://developer.apple.com/library/safari/documentation/SafariDOMAdditions/Reference/StyleMedia/)",
+          "   *   from Safari Developer Library.",
           "   */"
         ],
         "TEMPORARY": [
@@ -4065,10 +4035,10 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Exploring the FileSystem APIs]",
-          "   * (http://www.html5rocks.com/en/tutorials/file/filesystem/) from HTML5Rocks.",
-          "   * * [File API]",
-          "   * (http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem) from W3C.",
+          "   * * [Exploring the FileSystem",
+          "   *   APIs](http://www.html5rocks.com/en/tutorials/file/filesystem/) from HTML5Rocks.",
+          "   * * [File API](http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem)",
+          "   *   from W3C.",
           "   */"
         ],
         "toolbar": [
@@ -4077,9 +4047,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Browser interface elements]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)",
-          "   * from WHATWG.",
+          "   * * [Browser interface",
+          "   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "unloadEvent": [
@@ -4120,8 +4090,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Obtaining access to file system entry points]",
-          "   * (http://www.w3.org/TR/file-system-api/#obtaining-access-to-file-system-entry-points)",
+          "   * * [Obtaining access to file system entry",
+          "   *   points](http://www.w3.org/TR/file-system-api/#obtaining-access-to-file-system-entry-points)",
           "   * from W3C.",
           "   */"
         ],
@@ -4131,8 +4101,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Window.window]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.window) from MDN.",
+          "   * * [Window.window](https://developer.mozilla.org/en-US/docs/Web/API/Window.window)",
+          "   *   from MDN.",
           "   */"
         ]
       }
@@ -4197,7 +4167,8 @@
           "   * `getAllResponseHeaders` will return the response headers for the current",
           "   * part of the request.",
           "   *",
-          "   * See also [HTTP response headers](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)",
+          "   * See also [HTTP response",
+          "   * headers](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Response_fields)",
           "   * for a list of common response headers.",
           "   */"
         ],
@@ -4205,7 +4176,8 @@
           "/**",
           "   * Return the response header named `header`, or null if not found.",
           "   *",
-          "   * See also [HTTP response headers](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)",
+          "   * See also [HTTP response",
+          "   * headers](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Response_fields)",
           "   * for a list of common response headers.",
           "   */"
         ],
@@ -4239,7 +4211,7 @@
           "   * response.",
           "   *",
           "   * This value must be set before the request has been sent. See also the list",
-          "   * of [common MIME types](http://en.wikipedia.org/wiki/Internet_media_type#List_of_common_media_types)",
+          "   * of [IANA Official MIME types](https://www.iana.org/assignments/media-types/media-types.xhtml)",
           "   */"
         ],
         "readyState": [
@@ -4307,7 +4279,8 @@
           "   * 'text'. Some newer browsers will throw NS_ERROR_DOM_INVALID_ACCESS_ERR if",
           "   * `responseType` is set while performing a synchronous request.",
           "   *",
-          "   * See also: [MDN responseType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType)",
+          "   * See also: [MDN",
+          "   * responseType](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-responsetype)",
           "   */"
         ],
         "responseXML": [
@@ -4330,9 +4303,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [XMLHttpRequest.send]",
-          "   * (https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)",
-          "   * from MDN.",
+          "   * * [XMLHttpRequest.send](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)",
+          "   *   from MDN.",
           "   */"
         ],
         "setRequestHeader": [
@@ -4347,24 +4319,23 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [XMLHttpRequest.setRequestHeader]",
-          "   * (https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)",
-          "   * from MDN.",
-          "   * * [The setRequestHeader() method]",
-          "   * (http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader()-method) from",
-          "   * W3C.",
+          "   * * [XMLHttpRequest.setRequestHeader](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#setRequestHeader())",
+          "   *   from MDN.",
+          "   * * [The setRequestHeader()",
+          "   *   method](http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader()-method)",
+          "   *   from W3C.",
           "   */"
         ],
         "status": [
           "/**",
-          "   * The http result code from the request (200, 404, etc).",
-          "   * See also: [Http Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)",
+          "   * The HTTP result code from the request (200, 404, etc).",
+          "   * See also: [HTTP Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)",
           "   */"
         ],
         "statusText": [
           "/**",
           "   * The request response string (such as \\\"200 OK\\\").",
-          "   * See also: [Http Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)",
+          "   * See also: [HTTP Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)",
           "   */"
         ],
         "timeout": [
@@ -4377,12 +4348,10 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [XMLHttpRequest.timeout]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#timeout)",
-          "   * from MDN.",
-          "   * * [The timeout attribute]",
-          "   * (http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute)",
-          "   * from W3C.",
+          "   * * [XMLHttpRequest.timeout](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-timeout)",
+          "   *   from MDN.",
+          "   * * [The timeout attribute](http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute)",
+          "   *   from W3C.",
           "   */"
         ],
         "upload": [
@@ -5267,6 +5236,8 @@
           "   *",
           "   * [oldVersion] should match the database's current [version] exactly.",
           "   *",
+          "   * See also:",
+          "   *",
           "   * * [Database.changeVersion](http://www.w3.org/TR/webdatabase/#dom-database-changeversion) from W3C.",
           "   */"
         ]
diff --git a/tools/dom/scripts/generator.py b/tools/dom/scripts/generator.py
index 2cdc750..0f8867d 100644
--- a/tools/dom/scripts/generator.py
+++ b/tools/dom/scripts/generator.py
@@ -732,6 +732,12 @@
       Conversion('convertNativeToDart_SerializedScriptValue',
                  'dynamic', 'dynamic'),
 
+    # TODO(alanknight): This generates two variations for dart2js, because of
+    # the optional argument, but not in Dartium. Should do the same for both.
+    'any set History.pushState': _serialize_SSV,
+
+    'any set History.replaceState': _serialize_SSV,
+
     '* get History.state':
       Conversion('convertNativeToDart_SerializedScriptValue',
                  'dynamic', 'dynamic'),
@@ -1443,6 +1449,7 @@
         return_type = return_type.replace('Html', 'HTML', 1)
     return (type_registry.HasInterface(return_type) or not(return_type) or
             return_type == 'Object' or
+            return_type == 'dynamic' or
             return_type == 'Future' or
             return_type == 'SqlDatabase' or # renamed to Database
             return_type == 'HTMLElement' or
diff --git a/tools/dom/src/CanvasImageSource.dart b/tools/dom/src/CanvasImageSource.dart
index e030533..ffcd34a 100644
--- a/tools/dom/src/CanvasImageSource.dart
+++ b/tools/dom/src/CanvasImageSource.dart
@@ -33,11 +33,10 @@
  *
  * ## Other resources
  *
- * * [Image sources for 2D rendering contexts]
- * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#image-sources-for-2d-rendering-contexts)
- * from WHATWG.
- * * [Drawing images]
- * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
- * from WHATWG.
+ * * [Image sources for 2D rendering
+ *   contexts](https://html.spec.whatwg.org/multipage/scripting.html#image-sources-for-2d-rendering-contexts)
+ *   from WHATWG.
+ * * [Drawing images](https://html.spec.whatwg.org/multipage/scripting.html#dom-context-2d-drawimage)
+ *   from WHATWG.
  */
 abstract class CanvasImageSource {}
diff --git a/tools/dom/src/CrossFrameTypes.dart b/tools/dom/src/CrossFrameTypes.dart
index cda5957..a923377 100644
--- a/tools/dom/src/CrossFrameTypes.dart
+++ b/tools/dom/src/CrossFrameTypes.dart
@@ -39,9 +39,9 @@
    *
    * ## Other resources
    *
-   * * [Session history and navigation specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html)
-   * from WHATWG.
+   * * [Session history and navigation
+   *   specification](https://html.spec.whatwg.org/multipage/browsers.html#history)
+   *   from WHATWG.
    */
   HistoryBase get history;
 
@@ -134,12 +134,10 @@
    *
    * ## Other resources
    *
-   * * [window.postMessage]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage) from
-   * MDN.
-   * * [Cross-document messaging]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/web-messaging.html)
-   * from WHATWG.
+   * * [window.postMessage](https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage)
+   *   from MDN.
+   * * [Cross-document messaging](https://html.spec.whatwg.org/multipage/comms.html#web-messaging)
+   *   from WHATWG.
    */
   void postMessage(var message, String targetOrigin, [List messagePorts]);
 }
diff --git a/tools/dom/src/EventStreamProvider.dart b/tools/dom/src/EventStreamProvider.dart
index ea66285..3b41f51 100644
--- a/tools/dom/src/EventStreamProvider.dart
+++ b/tools/dom/src/EventStreamProvider.dart
@@ -112,9 +112,8 @@
    *
    * ## Other resources
    *
-   * * [Event Capture]
-   * (http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture)
-   * from the W3C DOM Events specification.
+   * * [Event Capture](http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture)
+   *   from the W3C DOM Events specification.
    */
   StreamSubscription<T> capture(void onData(T event));
 }
diff --git a/tools/dom/src/dart2js_WrappedEvent.dart b/tools/dom/src/dart2js_WrappedEvent.dart
index 4f30af9..e7e21a0 100644
--- a/tools/dom/src/dart2js_WrappedEvent.dart
+++ b/tools/dom/src/dart2js_WrappedEvent.dart
@@ -76,9 +76,9 @@
    *
    * ## Other resources
    *
-   * * [Shadow DOM extensions to Event]
-   * (http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event) from
-   * W3C.
+   * * [Shadow DOM extensions to
+   *   Event](http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event)
+   *   from W3C.
    */
   // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#extensions-to-event
   @Experimental()
diff --git a/tools/dom/src/dartium_WrappedEvent.dart b/tools/dom/src/dartium_WrappedEvent.dart
index 9fa56fd..18c43f0 100644
--- a/tools/dom/src/dartium_WrappedEvent.dart
+++ b/tools/dom/src/dartium_WrappedEvent.dart
@@ -83,9 +83,9 @@
    *
    * ## Other resources
    *
-   * * [Shadow DOM extensions to Event]
-   * (http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event) from
-   * W3C.
+   * * [Shadow DOM extensions to
+   *   Event](http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event)
+   *   from W3C.
    */
   // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#extensions-to-event
   @Experimental()
diff --git a/tools/dom/src/native_DOMImplementation.dart b/tools/dom/src/native_DOMImplementation.dart
index b18a026..e9e3720 100644
--- a/tools/dom/src/native_DOMImplementation.dart
+++ b/tools/dom/src/native_DOMImplementation.dart
@@ -266,6 +266,9 @@
       // 'this' needs to be handled by calling Dart_EvaluateExpr with
       // 'this' as the target rather than by passing it as an argument.
       if (arg == 'this') return;
+      // Avoid being broken by bogus ':async_op' local passed in when within
+      // an async method.
+      if (arg.startsWith(':')) return;
       if (args.isNotEmpty) {
         sb.write(", ");
       }
diff --git a/tools/dom/templates/html/dartium/html_dartium.darttemplate b/tools/dom/templates/html/dartium/html_dartium.darttemplate
index 0e029f2..c82e9b5 100644
--- a/tools/dom/templates/html/dartium/html_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/html_dartium.darttemplate
@@ -405,32 +405,6 @@
 
 }
 
-/// Upgrade a Dart HtmlElement to the user's Dart custom element class.
-_upgradeHtmlElement(dartInstance) {
-  // Only try upgrading HtmlElement (Dart class) if there is a failure then
-  // don't try it again - one failure is enough.
-  if (dartInstance.runtimeType == HtmlElement && !dartInstance.isBadUpgrade) {
-    // Must be exactly HtmlElement not something derived from it.
-
-    var customElementClass = getCustomElementType(dartInstance);
-
-    // Custom Element to upgrade.
-    if (customElementClass != null) {
-      var jsObject = dartInstance.blink_jsObject;
-      try {
-        dartInstance = _blink.Blink_Utils.constructElement(customElementClass, jsObject);
-      } catch (e) {
-        dartInstance._badUpgrade();
-      } finally {
-        dartInstance.blink_jsObject = jsObject;
-        js.setDartHtmlWrapperFor(jsObject, dartInstance);
-     }
-   }
-  }
-
-  return dartInstance;
-}
-
 @Deprecated("Internal Use Only")
 class DebugAssertException implements Exception {
   String message;
@@ -480,7 +454,12 @@
   try {
     dartClass = _blink.Blink_Utils.constructElement(customElementClass, $this);
   } catch (e) {
-    dartClass._badUpgrade();
+    // Did the dartClass get allocated but the created failed?  Otherwise, other
+    // components inside of this failed somewhere (could be JS custom element).
+    if (dartClass != null) {
+      // Yes, mark as didn't upgrade.
+      dartClass._badUpgrade();
+    }
     throw e;
   } finally {
     // Need to remember the Dart class that was created for this custom so
diff --git a/tools/dom/templates/html/impl/impl_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate
index 25608df..03539f5 100644
--- a/tools/dom/templates/html/impl/impl_Element.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Element.darttemplate
@@ -666,7 +666,8 @@
    *
    * See also:
    *
-   * * [Custom data attributes](http://www.w3.org/TR/html5/global-attributes.html#custom-data-attribute)
+   * * [Custom data
+   *   attributes](http://dev.w3.org/html5/spec-preview/global-attributes.html#custom-data-attribute)
    */
   Map<String, String> get dataset =>
     new _DataAttributeMap(attributes);
@@ -892,8 +893,8 @@
    *
    * ## Other resources
    *
-   * * [Node.namespaceURI]
-   * (http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-NodeNSname) from W3C.
+   * * [Node.namespaceURI](http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-NodeNSname)
+   *   from W3C.
    */
   @DomName('Element.namespaceUri')
   String get namespaceUri => _namespaceUri;
@@ -1122,11 +1123,9 @@
    *
    * ## Other resources
    *
-   * * [Shadow DOM 101]
-   * (http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
-   * from HTML5Rocks.
-   * * [Shadow DOM specification]
-   * (http://www.w3.org/TR/shadow-dom/) from W3C.
+   * * [Shadow DOM 101](http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
+   *   from HTML5Rocks.
+   * * [Shadow DOM specification](http://www.w3.org/TR/shadow-dom/) from W3C.
    */
   @DomName('Element.createShadowRoot')
   @SupportedBrowser(SupportedBrowser.CHROME, '25')
@@ -1142,11 +1141,10 @@
    *
    * ## Other resources
    *
-   * * [Shadow DOM 101]
-   * (http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
-   * from HTML5Rocks.
-   * * [Shadow DOM specification]
-   * (http://www.w3.org/TR/shadow-dom/) from W3C.
+   * * [Shadow DOM 101](http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
+   *   from HTML5Rocks.
+   * * [Shadow DOM specification](http://www.w3.org/TR/shadow-dom/)
+   *   from W3C.
    */
   @DomName('Element.shadowRoot')
   @SupportedBrowser(SupportedBrowser.CHROME, '25')
diff --git a/tools/dom/templates/html/impl/impl_GlobalEventHandlers.darttemplate b/tools/dom/templates/html/impl/impl_GlobalEventHandlers.darttemplate
index d1b4f83..af140f7 100644
--- a/tools/dom/templates/html/impl/impl_GlobalEventHandlers.darttemplate
+++ b/tools/dom/templates/html/impl/impl_GlobalEventHandlers.darttemplate
@@ -4,6 +4,15 @@
 
 part of $LIBRARYNAME;
 
+// We implement EventTarget and have stubs for its methods because it's tricky to
+// convince the scripts to make our instance methods abstract, and the bodies that
+// get generated require `this` to be an EventTarget.
 @DocsEditable()
-$(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME extends EventTarget {
+$(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME implements EventTarget {
+
+  void addEventListener(String type, dynamic listener(Event event), [bool useCapture]);
+  bool dispatchEvent(Event event);
+  void removeEventListener(String type, dynamic listener(Event event), [bool useCapture]);
+  Events get on;
+
 $!MEMBERS}
diff --git a/tools/dom/templates/html/impl/impl_HTMLCanvasElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLCanvasElement.darttemplate
index 3d49d69..41ecdb9 100644
--- a/tools/dom/templates/html/impl/impl_HTMLCanvasElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLCanvasElement.darttemplate
@@ -19,10 +19,9 @@
    *
    * ## Other resources
    *
-   * * [WebGL fundamentals]
-   * (http://www.html5rocks.com/en/tutorials/webgl/webgl_fundamentals/) from
-   * HTML5Rocks.
-   * * [WebGL homepage] (http://get.webgl.org/).
+   * * [WebGL fundamentals](http://www.html5rocks.com/en/tutorials/webgl/webgl_fundamentals/)
+   *   from HTML5Rocks.
+   * * [WebGL homepage](http://get.webgl.org/).
    */
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.FIREFOX)
diff --git a/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate b/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
index 6cbf883..1b4b7e6 100644
--- a/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
@@ -112,11 +112,10 @@
    *
    * ## Other resources
    *
-   * * [Using the fullscreen API]
-   * (http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api) from
-   * WebPlatform.org.
-   * * [Fullscreen specification]
-   * (http://www.w3.org/TR/fullscreen/) from W3C.
+   * * [Using the fullscreen
+   *   API](http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api)
+   *   from WebPlatform.org.
+   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.
    */
   @DomName('Document.webkitExitFullscreen')
   @SupportedBrowser(SupportedBrowser.CHROME)
@@ -140,11 +139,10 @@
    *
    * ## Other resources
    *
-   * * [Using the fullscreen API]
-   * (http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api) from
-   * WebPlatform.org.
-   * * [Fullscreen specification]
-   * (http://www.w3.org/TR/fullscreen/) from W3C.
+   * * [Using the fullscreen
+   *   API](http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api)
+   *   from WebPlatform.org.
+   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.
    */
   @DomName('Document.webkitFullscreenElement')
   @SupportedBrowser(SupportedBrowser.CHROME)
@@ -157,11 +155,10 @@
    *
    * ## Other resources
    *
-   * * [Using the fullscreen API]
-   * (http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api) from
-   * WebPlatform.org.
-   * * [Fullscreen specification]
-   * (http://www.w3.org/TR/fullscreen/) from W3C.
+   * * [Using the fullscreen
+   *   API](http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api)
+   *   from WebPlatform.org.
+   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.
    */
   @DomName('Document.webkitFullscreenEnabled')
   @SupportedBrowser(SupportedBrowser.CHROME)
diff --git a/tools/dom/templates/html/impl/impl_Node.darttemplate b/tools/dom/templates/html/impl/impl_Node.darttemplate
index 23b4afe..17bc601 100644
--- a/tools/dom/templates/html/impl/impl_Node.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Node.darttemplate
@@ -299,9 +299,8 @@
    *
    * ## Other resources
    *
-   * * [Node.childNodes]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.childNodes)
-   * from MDN.
+   * * [Node.childNodes](https://developer.mozilla.org/en-US/docs/Web/API/Node.childNodes)
+   *   from MDN.
    */
   @DomName('Node.childNodes')
   @DocsEditable()
@@ -312,9 +311,8 @@
    *
    * ## Other resources
    *
-   * * [Node.childNodes]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.childNodes)
-   * from MDN.
+   * * [Node.childNodes](https://developer.mozilla.org/en-US/docs/Web/API/Node.childNodes)
+   *   from MDN.
    */
   @DomName('Node.childNodes')
   @DocsEditable()
diff --git a/tools/dom/templates/html/impl/impl_Window.darttemplate b/tools/dom/templates/html/impl/impl_Window.darttemplate
index 36dfc9a..896e204 100644
--- a/tools/dom/templates/html/impl/impl_Window.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Window.darttemplate
@@ -41,9 +41,9 @@
    *
    * ## Other resources
    *
-   * * [Loading web pages]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html)
-   * from WHATWG.
+   * * [Loading web
+   *   pages](https://html.spec.whatwg.org/multipage/browsers.html)
+   *   from WHATWG.
    */
   Document get document => JS('Document', '#.document', this);
 
@@ -57,10 +57,10 @@
    *
    * ## Other resources
    *
-   * * [Window.open]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.open) from MDN.
-   * * [Window open]
-   * (http://docs.webplatform.org/wiki/dom/methods/open) from WebPlatform.org.
+   * * [Window.open](https://developer.mozilla.org/en-US/docs/Web/API/Window.open)
+   *   from MDN.
+   * * [Window open](http://docs.webplatform.org/wiki/dom/methods/open)
+   *   from WebPlatform.org.
    */
   WindowBase open(String url, String name, [String options]) {
     if (options == null) {
@@ -122,8 +122,8 @@
    *
    * ## Other resources
    *
-   * * [Window.cancelAnimationFrame]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.cancelAnimationFrame) from MDN.
+   * * [Window.cancelAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/Window.cancelAnimationFrame)
+   *   from MDN.
    */
   void cancelAnimationFrame(int id) {
     _ensureRequestAnimationFrame();
@@ -244,10 +244,10 @@
    *
    * ## Other resources
    *
-   * * [Window.moveTo]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.moveTo) from MDN.
-   * * [Window.moveTo]
-   * (http://dev.w3.org/csswg/cssom-view/#dom-window-moveto) from W3C.
+   * * [Window.moveTo](https://developer.mozilla.org/en-US/docs/Web/API/Window.moveTo)
+   *   from MDN.
+   * * [Window.moveTo](http://dev.w3.org/csswg/cssom-view/#dom-window-moveto)
+   *   from W3C.
    */
   void moveTo(Point p) {
     _moveTo(p.x, p.y);
@@ -267,10 +267,10 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
-   * * [scrollX]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX) from MDN.
+   * * [The Screen interface
+   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [scrollX](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX)
+   *   from MDN.
    */
   @DomName('Window.scrollX')
   @DocsEditable()
@@ -283,10 +283,10 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
-   * * [scrollY]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY) from MDN.
+   * * [The Screen interface
+   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [scrollY](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY)
+   *   from MDN.
    */
   @DomName('Window.scrollY')
   @DocsEditable()
diff --git a/tools/precompilation/test_linux.sh b/tools/precompilation/test_linux.sh
index e8839e1..d6263b1 100755
--- a/tools/precompilation/test_linux.sh
+++ b/tools/precompilation/test_linux.sh
@@ -2,12 +2,12 @@
 
 # Usage:
 #   cd sdk
-#   ./tools/precompilation/test_linux.sh
+#   ./tools/precompilation/test_linux.sh <dart-script-file>
 
 ./tools/build.py -mdebug -ax64 runtime
 
-./out/DebugX64/dart_no_snapshot --gen-precompiled-snapshot ~/hello.dart
+./out/DebugX64/dart_no_snapshot --gen-precompiled-snapshot "$1"
 
 gcc -m64 -shared -Wl,-soname,libprecompiled.so -o libprecompiled.so precompiled.S
 
-LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$PWD" gdb -ex run --args ./out/DebugX64/dart --run-precompiled-snapshot not_used.dart
+LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$PWD" gdb -ex run --args ./out/DebugX64/dart --run-precompiled-snapshot --observe --profile-vm not_used.dart
diff --git a/tools/precompilation/test_linux_simarm.sh b/tools/precompilation/test_linux_simarm.sh
index b55a5e9..5f477f6 100755
--- a/tools/precompilation/test_linux_simarm.sh
+++ b/tools/precompilation/test_linux_simarm.sh
@@ -2,12 +2,12 @@
 
 # Usage:
 #   cd sdk
-#   ./tools/precompilation/test_linux.sh
+#   ./tools/precompilation/test_linux.sh <dart-script-file>
 
 ./tools/build.py -mdebug -asimarm runtime
 
-./out/DebugSIMARM/dart_no_snapshot --gen-precompiled-snapshot ~/hello.dart
+./out/DebugSIMARM/dart_no_snapshot --gen-precompiled-snapshot "$1"
 
 gcc -m32 -shared -Wl,-soname,libprecompiled.so -o libprecompiled.so precompiled.S
 
-LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$PWD" gdb -ex run --args ./out/DebugSIMARM/dart --run-precompiled-snapshot not_used.dart
+LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$PWD" gdb -ex run --args ./out/DebugSIMARM/dart --run-precompiled-snapshot --observe not_used.dart
diff --git a/tools/precompilation/test_macos.sh b/tools/precompilation/test_macos.sh
index 48e318d..4dbf51c 100755
--- a/tools/precompilation/test_macos.sh
+++ b/tools/precompilation/test_macos.sh
@@ -2,12 +2,12 @@
 
 # Usage:
 #   cd sdk
-#   ./tools/precompilation/test_macos.sh
+#   ./tools/precompilation/test_macos.sh <dart-script-file>
 
 ./tools/build.py -mdebug -ax64 runtime
 
-./xcodebuild/DebugX64/dart_no_snapshot --gen-precompiled-snapshot ~/hello.dart
+./xcodebuild/DebugX64/dart_no_snapshot --gen-precompiled-snapshot "$1"
 
 clang -m64 -dynamiclib -o libprecompiled.dylib precompiled.S
 
-LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$PWD" lldb -- ./xcodebuild/DebugX64/dart --run-precompiled-snapshot not_used.dart
+LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$PWD" lldb -- ./xcodebuild/DebugX64/dart --run-precompiled-snapshot --observe not_used.dart
diff --git a/tools/testing/dart/compiler_configuration.dart b/tools/testing/dart/compiler_configuration.dart
index 9ec90f0..83fcfbe 100644
--- a/tools/testing/dart/compiler_configuration.dart
+++ b/tools/testing/dart/compiler_configuration.dart
@@ -61,6 +61,7 @@
     bool useSdk = configuration['use_sdk'];
     bool isCsp = configuration['csp'];
     bool useCps = configuration['cps_ir'];
+    bool useNoopt = configuration['noopt'];
 
     switch (compiler) {
       case 'dartanalyzer':
@@ -80,7 +81,7 @@
       case 'none':
         return new NoneCompilerConfiguration(
             isDebug: isDebug, isChecked: isChecked,
-            isHostChecked: isHostChecked, useSdk: useSdk);
+            isHostChecked: isHostChecked, useSdk: useSdk, useNoopt: useNoopt);
       default:
         throw "Unknown compiler '$compiler'";
     }
@@ -136,14 +137,17 @@
 
 /// The "none" compiler.
 class NoneCompilerConfiguration extends CompilerConfiguration {
+  final bool useNoopt;
+
   NoneCompilerConfiguration({
       bool isDebug,
       bool isChecked,
       bool isHostChecked,
-      bool useSdk})
+      bool useSdk,
+      bool useNoopt})
       : super._subclass(
           isDebug: isDebug, isChecked: isChecked,
-          isHostChecked: isHostChecked, useSdk: useSdk);
+          isHostChecked: isHostChecked, useSdk: useSdk), useNoopt = useNoopt;
 
   bool get hasCompiler => false;
 
@@ -160,6 +164,9 @@
       args.add('--enable_asserts');
       args.add('--enable_type_checks');
     }
+    if (useNoopt) {
+      args.add('--noopt');
+    }
     return args
         ..addAll(vmOptions)
         ..addAll(sharedOptions)
diff --git a/tools/testing/dart/test_configurations.dart b/tools/testing/dart/test_configurations.dart
index c552282..f4ea6d6 100644
--- a/tools/testing/dart/test_configurations.dart
+++ b/tools/testing/dart/test_configurations.dart
@@ -99,6 +99,7 @@
       List settings = ['compiler', 'runtime', 'mode', 'arch']
           .map((name) => conf[name]).toList();
       if (conf['checked']) settings.add('checked');
+      if (conf['noopt']) settings.add('noopt');
       output_words.add(settings.join('_'));
     }
     print(output_words.join(' '));
diff --git a/tools/testing/dart/test_options.dart b/tools/testing/dart/test_options.dart
index ca0adad..1113174 100644
--- a/tools/testing/dart/test_options.dart
+++ b/tools/testing/dart/test_options.dart
@@ -107,7 +107,7 @@
               ['-a', '--arch'],
               ['all', 'ia32', 'x64', 'arm', 'armv5te', 'arm64', 'mips',
                'simarm', 'simarmv5te', 'simarm64', 'simmips'],
-              'ia32'),
+              'x64'),
           new _TestOptionSpecification(
               'system',
               'The operating system to run tests on',
@@ -150,6 +150,13 @@
               false,
               type: 'bool'),
           new _TestOptionSpecification(
+              'noopt',
+              'Run an in-place precompilation',
+              ['--noopt'],
+              [],
+              false,
+              type: 'bool'),
+          new _TestOptionSpecification(
               'timeout',
               'Timeout in seconds',
               ['-t', '--timeout'],
@@ -875,7 +882,7 @@
    */
   _TestOptionSpecification _getSpecification(String name) {
     for (var option in _options) {
-      if (option.keys.any((key) => key == name)) {
+      if (option.keys.contains(name)) {
         return option;
       }
     }
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index b4e7b53..b36668c 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -224,7 +224,7 @@
   String get jsShellFileName {
     var executableSuffix = getExecutableSuffix('jsshell');
     var executable = 'jsshell$executableSuffix';
-    var jsshellDir = '${TestUtils.dartDir}/tools/testing/bin';
+    var jsshellDir = '${TestUtils.dartDir.toNativePath()}/tools/testing/bin';
     return '$jsshellDir/$executable';
   }
 
diff --git a/tools/utils.py b/tools/utils.py
index 7b203aa..a6e7f51 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -58,12 +58,12 @@
     return 'arm64'
   elif os_id.startswith('mips'):
     return 'mips'
+  elif '64' in os_id:
+    return 'x64'
   elif (not os_id) or (not re.match('(x|i[3-6])86', os_id) is None):
     return 'ia32'
   elif os_id == 'i86pc':
     return 'ia32'
-  elif '64' in os_id:
-    return 'x64'
   else:
     guess_os = GuessOS()
     print "Warning: Guessing architecture %s based on os %s\n"\